virtual-context 0.2.8__tar.gz → 0.2.9__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 (225) hide show
  1. {virtual_context-0.2.8 → virtual_context-0.2.9}/PKG-INFO +13 -3
  2. {virtual_context-0.2.8 → virtual_context-0.2.9}/README.md +12 -2
  3. {virtual_context-0.2.8 → virtual_context-0.2.9}/pyproject.toml +1 -1
  4. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_cli_init.py +40 -0
  5. virtual_context-0.2.9/tests/test_fact_redesign.py +95 -0
  6. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_format_agnostic.py +3 -3
  7. virtual_context-0.2.9/tests/test_store_recovery.py +192 -0
  8. virtual_context-0.2.9/virtual-context.yaml +109 -0
  9. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/__init__.py +1 -1
  10. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/cli/main.py +95 -4
  11. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/config.py +1 -0
  12. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/compaction_pipeline.py +8 -2
  13. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/compactor.py +12 -0
  14. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/composite_store.py +9 -0
  15. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/conversation_store.py +1 -0
  16. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/protocols.py +3 -0
  17. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/store.py +16 -0
  18. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/tag_generator.py +8 -0
  19. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/engine.py +1 -0
  20. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/dashboard.py +1 -1
  21. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/formats.py +170 -22
  22. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/handlers.py +22 -7
  23. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/message_filter.py +185 -22
  24. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/metrics.py +1 -1
  25. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/server.py +59 -27
  26. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/state.py +2 -2
  27. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/storage/falkordb.py +9 -0
  28. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/storage/filesystem.py +9 -0
  29. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/storage/neo4j.py +11 -0
  30. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/storage/postgres.py +32 -0
  31. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/storage/sqlite.py +83 -0
  32. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/types.py +2 -0
  33. {virtual_context-0.2.8 → virtual_context-0.2.9}/.gitignore +0 -0
  34. {virtual_context-0.2.8 → virtual_context-0.2.9}/LICENSE +0 -0
  35. {virtual_context-0.2.8 → virtual_context-0.2.9}/assets/dashboard.png +0 -0
  36. {virtual_context-0.2.8 → virtual_context-0.2.9}/assets/hero.png +0 -0
  37. {virtual_context-0.2.8 → virtual_context-0.2.9}/models.yaml +0 -0
  38. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/REGRESSION_MAP.md +0 -0
  39. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/conftest.py +0 -0
  40. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/docker-compose.test.yml +0 -0
  41. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/haiku/__init__.py +0 -0
  42. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/haiku/conftest.py +0 -0
  43. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/haiku/test_compaction.py +0 -0
  44. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/haiku/test_retrieval.py +0 -0
  45. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/haiku/test_tagging.py +0 -0
  46. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/ollama/__init__.py +0 -0
  47. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/ollama/conftest.py +0 -0
  48. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/ollama/test_compactor.py +0 -0
  49. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/ollama/test_pipeline.py +0 -0
  50. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/ollama/test_provider.py +0 -0
  51. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/ollama/test_tag_generator.py +0 -0
  52. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/proxy/__init__.py +0 -0
  53. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/proxy/test_dashboard_cors.py +0 -0
  54. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/proxy/test_metrics.py +0 -0
  55. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_assembler.py +0 -0
  56. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_backend_integration.py +0 -0
  57. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_budget_enforcement.py +0 -0
  58. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_compaction_commit_prune.py +0 -0
  59. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_compactor.py +0 -0
  60. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_compactor_concurrent.py +0 -0
  61. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_composite_store.py +0 -0
  62. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_config.py +0 -0
  63. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_context_bleed.py +0 -0
  64. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_conversation_identity.py +0 -0
  65. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_conversation_lifecycle.py +0 -0
  66. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_conversation_scoping.py +0 -0
  67. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_embedding_tag_generator.py +0 -0
  68. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_empty_turn_skip.py +0 -0
  69. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_engine_integration.py +0 -0
  70. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_engine_lookback.py +0 -0
  71. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_engine_state.py +0 -0
  72. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_fact_enrichment.py +0 -0
  73. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_fact_graph_integration.py +0 -0
  74. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_fact_link_checker.py +0 -0
  75. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_fact_link_query.py +0 -0
  76. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_fact_link_types.py +0 -0
  77. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_fact_links_sqlite.py +0 -0
  78. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_fill_pass.py +0 -0
  79. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_find_quote.py +0 -0
  80. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_headless.py +0 -0
  81. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_history_filter.py +0 -0
  82. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_idf_retrieval.py +0 -0
  83. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_ingest_index_integrity.py +0 -0
  84. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_longmemeval_auth.py +0 -0
  85. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_mcp_server.py +0 -0
  86. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_media.py +0 -0
  87. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_message_filter.py +0 -0
  88. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_metrics_persistence.py +0 -0
  89. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_model_catalog.py +0 -0
  90. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_model_limits.py +0 -0
  91. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_monitor.py +0 -0
  92. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_multi_instance.py +0 -0
  93. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_noop_fact_link_store.py +0 -0
  94. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_openrouter_provider.py +0 -0
  95. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_paging.py +0 -0
  96. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_passthrough_filter.py +0 -0
  97. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_presets.py +0 -0
  98. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_prev_context_leak.py +0 -0
  99. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_provider_adapters.py +0 -0
  100. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_proxy.py +0 -0
  101. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_proxy_dashboard.py +0 -0
  102. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_proxy_formats.py +0 -0
  103. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_proxy_message_filter.py +0 -0
  104. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_proxy_session.py +0 -0
  105. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_proxy_streaming.py +0 -0
  106. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_raw_content.py +0 -0
  107. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_recall_all.py +0 -0
  108. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_registry_lifecycle.py +0 -0
  109. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_request_captures_persistence.py +0 -0
  110. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_retriever.py +0 -0
  111. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_rrf_scoring.py +0 -0
  112. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_segmenter.py +0 -0
  113. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_semantic_search.py +0 -0
  114. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_sender_identity.py +0 -0
  115. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_session_cache.py +0 -0
  116. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_session_date.py +0 -0
  117. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_storage_protocols.py +0 -0
  118. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_store_sqlite.py +0 -0
  119. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_stub_turn_handling.py +0 -0
  120. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_supersession.py +0 -0
  121. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_supersession_migration.py +0 -0
  122. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_tag_canonicalizer.py +0 -0
  123. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_tag_consolidator.py +0 -0
  124. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_tag_generator.py +0 -0
  125. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_tag_splitter.py +0 -0
  126. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_telemetry.py +0 -0
  127. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_telemetry_integration.py +0 -0
  128. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_tool_loop.py +0 -0
  129. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_tool_output_interceptor.py +0 -0
  130. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_tool_result_filter.py +0 -0
  131. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_tool_tags.py +0 -0
  132. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_tui.py +0 -0
  133. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_turn_grouping.py +0 -0
  134. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_turn_tag_index.py +0 -0
  135. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_unified_budget.py +0 -0
  136. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_upstream_trim.py +0 -0
  137. {virtual_context-0.2.8 → virtual_context-0.2.9}/tests/test_verb_expansion.py +0 -0
  138. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual-context.yaml.example +0 -0
  139. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/cli/__init__.py +0 -0
  140. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/conversation_identity.py +0 -0
  141. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/__init__.py +0 -0
  142. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/assembler.py +0 -0
  143. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/embedding_provider.py +0 -0
  144. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/embedding_tag_generator.py +0 -0
  145. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/engine_utils.py +0 -0
  146. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/fact_query.py +0 -0
  147. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/fts_preprocessor.py +0 -0
  148. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/hint_builder.py +0 -0
  149. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/llm_utils.py +0 -0
  150. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/math_utils.py +0 -0
  151. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/model_catalog.py +0 -0
  152. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/monitor.py +0 -0
  153. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/paging_manager.py +0 -0
  154. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/provider_adapters.py +0 -0
  155. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/quote_search.py +0 -0
  156. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/retrieval_assembler.py +0 -0
  157. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/retrieval_scoring.py +0 -0
  158. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/retriever.py +0 -0
  159. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/search_engine.py +0 -0
  160. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/segmenter.py +0 -0
  161. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/semantic_search.py +0 -0
  162. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/tag_canonicalizer.py +0 -0
  163. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/tag_consolidator.py +0 -0
  164. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/tag_scoring.py +0 -0
  165. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/tag_splitter.py +0 -0
  166. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/tagging_pipeline.py +0 -0
  167. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/telemetry.py +0 -0
  168. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/temporal_resolver.py +0 -0
  169. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/tool_loop.py +0 -0
  170. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/tool_query.py +0 -0
  171. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/core/turn_tag_index.py +0 -0
  172. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/data/anthropic-tokenizer/tokenizer.json +0 -0
  173. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/ingest/__init__.py +0 -0
  174. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/ingest/curator.py +0 -0
  175. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/ingest/date_resolver.py +0 -0
  176. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/ingest/parsers.py +0 -0
  177. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/ingest/supersession.py +0 -0
  178. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/mcp/__init__.py +0 -0
  179. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/mcp/server.py +0 -0
  180. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/model_limits.py +0 -0
  181. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/openclaw/virtual-context.mjs +0 -0
  182. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/patterns.py +0 -0
  183. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/presets/__init__.py +0 -0
  184. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/presets/agentic.py +0 -0
  185. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/presets/base.py +0 -0
  186. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/presets/coding.py +0 -0
  187. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/providers/__init__.py +0 -0
  188. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/providers/anthropic.py +0 -0
  189. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/providers/base.py +0 -0
  190. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/providers/generic_openai.py +0 -0
  191. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/providers/ollama_native.py +0 -0
  192. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/__init__.py +0 -0
  193. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/_envelope.py +0 -0
  194. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/dashboard.html +0 -0
  195. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/helpers.py +0 -0
  196. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/media.py +0 -0
  197. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/multi.py +0 -0
  198. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/registry.py +0 -0
  199. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/session_cache.py +0 -0
  200. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/static/android-chrome-192x192.png +0 -0
  201. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/static/android-chrome-512x512.png +0 -0
  202. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/static/apple-touch-icon.png +0 -0
  203. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/static/favicon-16x16.png +0 -0
  204. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/static/favicon-32x32.png +0 -0
  205. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/static/favicon.ico +0 -0
  206. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/static/site.webmanifest +0 -0
  207. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/proxy/tool_output_interceptor.py +0 -0
  208. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/storage/__init__.py +0 -0
  209. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/storage/helpers.py +0 -0
  210. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/storage/noop_fact_link_store.py +0 -0
  211. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/token_counter.py +0 -0
  212. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/__init__.py +0 -0
  213. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/app.py +0 -0
  214. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/chat.tcss +0 -0
  215. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/chat_provider.py +0 -0
  216. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/headless.py +0 -0
  217. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/modals/__init__.py +0 -0
  218. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/modals/turn_inspector.py +0 -0
  219. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/state.py +0 -0
  220. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/widgets/__init__.py +0 -0
  221. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/widgets/budget_bar.py +0 -0
  222. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/widgets/chat_view.py +0 -0
  223. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/widgets/input_box.py +0 -0
  224. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/widgets/tag_panel.py +0 -0
  225. {virtual_context-0.2.8 → virtual_context-0.2.9}/virtual_context/tui/widgets/turn_list.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: virtual-context
3
- Version: 0.2.8
3
+ Version: 0.2.9
4
4
  Summary: OS-style virtual memory for LLM session context management
5
5
  Project-URL: Homepage, https://virtual-context.com
6
6
  Project-URL: Repository, https://github.com/virtual-context/virtual-context
@@ -180,10 +180,16 @@ proxy:
180
180
  **Daemon mode:** run as a background service:
181
181
 
182
182
  ```bash
183
- virtual-context onboard --install-daemon --upstream https://api.anthropic.com
183
+ # Creates config if needed, installs + starts daemon
184
+ virtual-context daemon install --upstream https://api.anthropic.com
185
+
186
+ # Or: guided interactive setup with daemon
187
+ virtual-context onboard --wizard --install-daemon
184
188
  ```
185
189
 
186
- Daemon setup docs (macOS `launchd`, Linux `systemd --user`, Windows Task Scheduler): [`docs/install.md`](docs/install.md)
190
+ Daemon lifecycle: `daemon status | start | stop | restart | uninstall`
191
+
192
+ Full setup docs (macOS `launchd`, Linux `systemd --user`, Windows Task Scheduler): [`docs/install.md`](docs/install.md)
187
193
 
188
194
  ### Python SDK
189
195
 
@@ -639,10 +645,14 @@ virtual-context transform -m "What about auth?"# tag + retrieve + assemble
639
645
  virtual-context aliases list # show all tag aliases
640
646
  virtual-context aliases suggest # auto-detect potential aliases
641
647
  virtual-context aliases add db database # register alias manually
648
+ virtual-context init coding # create config from preset
649
+ virtual-context onboard # guided setup (create/validate config)
650
+ virtual-context onboard --wizard # interactive multi-instance setup
642
651
  virtual-context proxy -u https://api.anthropic.com # single-instance proxy
643
652
  virtual-context proxy # multi-instance (from config)
644
653
  virtual-context presets list # list available config presets
645
654
  virtual-context presets show coding # dump preset config as YAML
655
+ virtual-context daemon install # install daemon/service
646
656
  virtual-context daemon status # service status (platform-specific)
647
657
  virtual-context daemon start # start/enable daemon
648
658
  virtual-context daemon stop # stop daemon
@@ -133,10 +133,16 @@ proxy:
133
133
  **Daemon mode:** run as a background service:
134
134
 
135
135
  ```bash
136
- virtual-context onboard --install-daemon --upstream https://api.anthropic.com
136
+ # Creates config if needed, installs + starts daemon
137
+ virtual-context daemon install --upstream https://api.anthropic.com
138
+
139
+ # Or: guided interactive setup with daemon
140
+ virtual-context onboard --wizard --install-daemon
137
141
  ```
138
142
 
139
- Daemon setup docs (macOS `launchd`, Linux `systemd --user`, Windows Task Scheduler): [`docs/install.md`](docs/install.md)
143
+ Daemon lifecycle: `daemon status | start | stop | restart | uninstall`
144
+
145
+ Full setup docs (macOS `launchd`, Linux `systemd --user`, Windows Task Scheduler): [`docs/install.md`](docs/install.md)
140
146
 
141
147
  ### Python SDK
142
148
 
@@ -592,10 +598,14 @@ virtual-context transform -m "What about auth?"# tag + retrieve + assemble
592
598
  virtual-context aliases list # show all tag aliases
593
599
  virtual-context aliases suggest # auto-detect potential aliases
594
600
  virtual-context aliases add db database # register alias manually
601
+ virtual-context init coding # create config from preset
602
+ virtual-context onboard # guided setup (create/validate config)
603
+ virtual-context onboard --wizard # interactive multi-instance setup
595
604
  virtual-context proxy -u https://api.anthropic.com # single-instance proxy
596
605
  virtual-context proxy # multi-instance (from config)
597
606
  virtual-context presets list # list available config presets
598
607
  virtual-context presets show coding # dump preset config as YAML
608
+ virtual-context daemon install # install daemon/service
599
609
  virtual-context daemon status # service status (platform-specific)
600
610
  virtual-context daemon start # start/enable daemon
601
611
  virtual-context daemon stop # stop daemon
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "virtual-context"
7
- version = "0.2.8"
7
+ version = "0.2.9"
8
8
  description = "OS-style virtual memory for LLM session context management"
9
9
  readme = "README.md"
10
10
  license = "AGPL-3.0-or-later"
@@ -97,6 +97,46 @@ def test_daemon_restart_in_help(tmp_cwd):
97
97
  assert "restart" in result.stdout
98
98
 
99
99
 
100
+ def test_daemon_not_installed_guard(tmp_cwd):
101
+ """daemon commands should fail with a helpful message when no daemon is installed."""
102
+ env = {**__import__("os").environ, "HOME": str(tmp_cwd)}
103
+ for action in ("status", "start", "stop", "restart"):
104
+ result = subprocess.run(
105
+ [sys.executable, "-m", "virtual_context.cli.main", "daemon", action],
106
+ capture_output=True,
107
+ text=True,
108
+ env=env,
109
+ )
110
+ assert result.returncode != 0, f"daemon {action} should fail when not installed"
111
+ assert "not installed" in result.stdout.lower(), (
112
+ f"daemon {action} should mention 'not installed'"
113
+ )
114
+ assert "daemon install" in result.stdout, (
115
+ f"daemon {action} should suggest 'daemon install'"
116
+ )
117
+
118
+
119
+ def test_daemon_install_creates_config(tmp_cwd):
120
+ """daemon install should auto-create config from agentic preset if none exists."""
121
+ config_path = tmp_cwd / "virtual-context.yaml"
122
+ assert not config_path.exists()
123
+ # daemon install will fail on launchctl/systemctl, but should create config first
124
+ result = _run_cli("daemon", "install")
125
+ assert config_path.exists(), "daemon install should create config"
126
+ assert "Created config" in result.stdout
127
+ content = config_path.read_text()
128
+ assert "tag_generator" in content
129
+
130
+
131
+ def test_daemon_install_preserves_existing_config(tmp_cwd):
132
+ """daemon install should not overwrite an existing config."""
133
+ config_path = tmp_cwd / "virtual-context.yaml"
134
+ config_path.write_text("custom: true\n")
135
+ result = _run_cli("daemon", "install")
136
+ assert config_path.read_text() == "custom: true\n"
137
+ assert "Created config" not in result.stdout
138
+
139
+
100
140
  def test_presets_list(tmp_cwd):
101
141
  result = _run_cli("presets", "list")
102
142
  assert result.returncode == 0
@@ -0,0 +1,95 @@
1
+ """Tests for fact extraction redesign."""
2
+ from virtual_context.types import CompactorConfig
3
+
4
+
5
+ def test_compactor_config_has_code_mode():
6
+ cc = CompactorConfig()
7
+ assert hasattr(cc, "code_mode")
8
+ assert cc.code_mode is True
9
+
10
+
11
+ def test_config_loader_reads_code_mode():
12
+ from virtual_context.config import load_config
13
+ import tempfile, os, yaml
14
+ cfg = {"compaction": {"code_mode": False}, "context_window": 100000}
15
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
16
+ yaml.dump(cfg, f)
17
+ tmp_path = f.name
18
+ try:
19
+ config = load_config(tmp_path)
20
+ assert config.compactor.code_mode is False
21
+ finally:
22
+ os.unlink(tmp_path)
23
+
24
+
25
+ def test_replace_facts_for_segment_default():
26
+ from virtual_context.core.store import ContextStore
27
+
28
+ class MinimalStore(ContextStore):
29
+ """Minimal concrete subclass that only implements abstract methods as no-ops."""
30
+ def store_segment(self, segment): return ""
31
+ def get_segment(self, ref, *, conversation_id=None): return None
32
+ def get_summary(self, ref, *, conversation_id=None): return None
33
+ def get_summaries_by_tags(self, tags, min_overlap=1, limit=10, before=None, after=None, conversation_id=None): return []
34
+ def search(self, query, tags=None, limit=5, conversation_id=None): return []
35
+ def get_all_tags(self, conversation_id=None): return []
36
+ def get_conversation_stats(self): return []
37
+ def get_tag_aliases(self, conversation_id=None): return {}
38
+ def set_tag_alias(self, alias, canonical, conversation_id=""): pass
39
+ def delete_segment(self, ref): return False
40
+ def cleanup(self, max_age=None, max_total_tokens=None): return 0
41
+ def save_tag_summary(self, tag_summary, conversation_id=""): pass
42
+ def get_tag_summary(self, tag, conversation_id=""): return None
43
+ def get_all_tag_summaries(self, *, conversation_id=None): return []
44
+ def search_full_text(self, query, limit=5, conversation_id=None): return []
45
+ def get_segments_by_tags(self, tags, min_overlap=1, limit=20, conversation_id=None): return []
46
+
47
+ store = MinimalStore()
48
+ deleted, inserted = store.replace_facts_for_segment("conv1", "seg1", [])
49
+ assert deleted == 0
50
+ assert inserted == 0
51
+
52
+
53
+ def test_compaction_uses_replace_facts_for_segment():
54
+ """Verify the compaction pipeline calls replace_facts_for_segment."""
55
+ import inspect
56
+ from virtual_context.core import compaction_pipeline
57
+ source = inspect.getsource(compaction_pipeline)
58
+ assert "replace_facts_for_segment" in source, \
59
+ "compaction_pipeline must call replace_facts_for_segment"
60
+
61
+
62
+ def test_code_mode_prompt_appended():
63
+ """When code_mode is True, the compactor prompt should include the code mode block."""
64
+ from virtual_context.core.compactor import CODE_MODE_FACT_PROMPT
65
+ assert "Do NOT extract intermediary" in CODE_MODE_FACT_PROMPT
66
+ assert "conclusions, findings, discoveries" in CODE_MODE_FACT_PROMPT
67
+
68
+
69
+ def test_tag_generator_accepts_code_mode():
70
+ from virtual_context.core.tag_generator import LLMTagGenerator
71
+ from virtual_context.types import TagGeneratorConfig
72
+ from unittest.mock import MagicMock
73
+ gen = LLMTagGenerator(llm_provider=MagicMock(), config=TagGeneratorConfig(), code_mode=True)
74
+ assert gen._code_mode is True
75
+
76
+
77
+ def test_build_tag_generator_passes_code_mode():
78
+ from virtual_context.core.tag_generator import build_tag_generator, LLMTagGenerator
79
+ from virtual_context.types import TagGeneratorConfig
80
+ from unittest.mock import MagicMock
81
+ config = TagGeneratorConfig(type="llm", provider="openrouter", model="test")
82
+ gen = build_tag_generator(config, MagicMock(), code_mode=True)
83
+ assert isinstance(gen, LLMTagGenerator)
84
+ assert gen._code_mode is True
85
+ gen2 = build_tag_generator(config, MagicMock())
86
+ assert gen2._code_mode is False
87
+
88
+
89
+ def test_engine_passes_code_mode_to_tag_generator():
90
+ import inspect
91
+ from virtual_context import engine
92
+ source = inspect.getsource(engine)
93
+ assert "code_mode" in source, "engine.py must reference code_mode"
94
+ assert "compactor.code_mode" in source or "config.compactor.code_mode" in source, \
95
+ "engine.py must read code_mode from compactor config"
@@ -450,7 +450,7 @@ class TestCollapseChainsCrossFormat:
450
450
  fmt = detect_format(body)
451
451
  tti = TurnTagIndex()
452
452
  original_count = len(body["messages"])
453
- result, collapsed, refs = collapse_turn_chains(
453
+ result, collapsed, refs, _ = collapse_turn_chains(
454
454
  body, fmt, protected_recent_turns=3, turn_tag_index=tti,
455
455
  store=None, conversation_id="test",
456
456
  )
@@ -480,7 +480,7 @@ class TestCollapseChainsCrossFormat:
480
480
  fmt = detect_format(body)
481
481
  tti = TurnTagIndex()
482
482
  original_count = len(body["input"])
483
- result, collapsed, refs = collapse_turn_chains(
483
+ result, collapsed, refs, _ = collapse_turn_chains(
484
484
  body, fmt, protected_recent_turns=3, turn_tag_index=tti,
485
485
  store=None, conversation_id="test",
486
486
  )
@@ -507,7 +507,7 @@ class TestCollapseChainsCrossFormat:
507
507
  fmt = detect_format(body)
508
508
  tti = TurnTagIndex()
509
509
  original_count = len(body["messages"])
510
- result, collapsed, refs = collapse_turn_chains(
510
+ result, collapsed, refs, _ = collapse_turn_chains(
511
511
  body, fmt, protected_recent_turns=3, turn_tag_index=tti,
512
512
  store=None, conversation_id="test",
513
513
  )
@@ -0,0 +1,192 @@
1
+ """Tests for store-backed pipeline recovery."""
2
+
3
+ from virtual_context.types import MonitorConfig
4
+
5
+
6
+ def test_monitor_config_has_store_recovery_threshold():
7
+ mc = MonitorConfig()
8
+ assert hasattr(mc, "store_recovery_threshold")
9
+ assert mc.store_recovery_threshold == 0.70
10
+
11
+
12
+ def _make_dummy_store():
13
+ """Create a minimal concrete ContextStore for testing default method implementations."""
14
+ from virtual_context.core.store import ContextStore
15
+
16
+ class DummyStore(ContextStore):
17
+ def store_segment(self, segment): return ""
18
+ def get_segment(self, ref, *, conversation_id=None): return None
19
+ def get_summary(self, ref, *, conversation_id=None): return None
20
+ def get_summaries_by_tags(self, tags, min_overlap=1, limit=10, before=None, after=None, conversation_id=None): return []
21
+ def search(self, query, tags=None, limit=5, conversation_id=None): return []
22
+ def get_all_tags(self, conversation_id=None): return []
23
+ def get_conversation_stats(self): return []
24
+ def get_tag_aliases(self, conversation_id=None): return {}
25
+ def set_tag_alias(self, alias, canonical, conversation_id=""): pass
26
+ def delete_segment(self, ref): return False
27
+ def cleanup(self, max_age=None, max_total_tokens=None): return 0
28
+ def save_tag_summary(self, tag_summary, conversation_id=""): pass
29
+ def get_tag_summary(self, tag, conversation_id=""): return None
30
+ def get_all_tag_summaries(self, *, conversation_id=None): return []
31
+ def search_full_text(self, query, limit=5, conversation_id=None): return []
32
+ def get_segments_by_tags(self, tags, min_overlap=1, limit=20, conversation_id=None): return []
33
+
34
+ return DummyStore()
35
+
36
+
37
+ def test_get_chain_snapshots_for_conversation_abstract():
38
+ s = _make_dummy_store()
39
+ assert s.get_chain_snapshots_for_conversation("conv1") == []
40
+ assert s.get_chain_snapshots_for_conversation("conv1", min_turn=100) == []
41
+
42
+
43
+ def test_get_tool_names_for_refs_abstract():
44
+ s = _make_dummy_store()
45
+ assert s.get_tool_names_for_refs(["ref1", "ref2"]) == []
46
+
47
+
48
+ def test_collapse_turn_chains_recovers_from_store():
49
+ from unittest.mock import MagicMock
50
+ from virtual_context.proxy.message_filter import collapse_turn_chains
51
+ from virtual_context.proxy.formats import detect_format
52
+ from virtual_context.core.turn_tag_index import TurnTagIndex, TurnTagEntry
53
+
54
+ body = {
55
+ "system": "test",
56
+ "messages": [
57
+ {"role": "user", "content": "hello"},
58
+ {"role": "assistant", "content": [{"type": "text", "text": "hi"}]},
59
+ {"role": "user", "content": "current question"},
60
+ ],
61
+ "model": "claude-opus-4-6",
62
+ }
63
+ fmt = detect_format(body)
64
+ tti = TurnTagIndex()
65
+ for i in range(100):
66
+ tti.entries.append(TurnTagEntry(turn_number=i, message_hash=f"hash_{i}", tags=[f"tag_{i}"]))
67
+
68
+ mock_store = MagicMock()
69
+ mock_store.get_chain_snapshots_for_conversation.return_value = [
70
+ {"ref": "chain_50_abc123", "turn_number": 50, "tool_output_refs": "tool_ref1,tool_ref2", "message_count": 4},
71
+ {"ref": "chain_80_def456", "turn_number": 80, "tool_output_refs": "tool_ref3", "message_count": 3},
72
+ ]
73
+ mock_store.get_tool_names_for_refs.return_value = ["web_search", "Read"]
74
+
75
+ result, count, refs, recovered = collapse_turn_chains(
76
+ body, fmt,
77
+ protected_recent_turns=6,
78
+ turn_tag_index=tti,
79
+ store=mock_store,
80
+ conversation_id="test-conv",
81
+ client_truncated=True,
82
+ )
83
+
84
+ mock_store.get_chain_snapshots_for_conversation.assert_called_once()
85
+ assert recovered == 2
86
+ assert "chain_50_abc123" in refs
87
+ assert "chain_80_def456" in refs
88
+
89
+ import json
90
+ result_json = json.dumps(result)
91
+ assert "Compacted turn 50" in result_json
92
+ assert "Compacted turn 80" in result_json
93
+ assert "vc_restore_tool" in result_json
94
+
95
+
96
+ def test_fill_pass_restores_from_store_on_truncation():
97
+ from unittest.mock import MagicMock
98
+ from virtual_context.proxy.message_filter import fill_pass
99
+ from virtual_context.proxy.formats import detect_format
100
+ from virtual_context.types import AssembledContext, RetrievalResult
101
+ from virtual_context.core.turn_tag_index import TurnTagIndex, TurnTagEntry
102
+ import copy
103
+
104
+ body = {
105
+ "system": "test",
106
+ "messages": [
107
+ {"role": "user", "content": "recent question"},
108
+ {"role": "assistant", "content": [{"type": "text", "text": "recent reply"}]},
109
+ {"role": "user", "content": "current question"},
110
+ ],
111
+ "model": "claude-opus-4-6",
112
+ }
113
+ fmt = detect_format(body)
114
+
115
+ mock_store = MagicMock()
116
+ mock_store.get_all_tag_summaries.return_value = []
117
+ mock_store.load_recent_turn_messages.return_value = [
118
+ (10, "older question about cooking", "I explained Italian techniques"),
119
+ (11, "what about baking?", "Bread baking involves..."),
120
+ ]
121
+ mock_store.get_tool_outputs_for_turn.return_value = []
122
+
123
+ assembled = AssembledContext(
124
+ presented_segment_refs=set(),
125
+ presented_tags=set(),
126
+ tag_sections={},
127
+ retrieval_result=RetrievalResult(),
128
+ )
129
+
130
+ tti = TurnTagIndex()
131
+ for i in range(50):
132
+ tti.entries.append(TurnTagEntry(turn_number=i, message_hash=f"hash_{i}", tags=[f"tag_{i}"]))
133
+
134
+ result_body, summaries, turns = fill_pass(
135
+ body=body, fmt=fmt,
136
+ outbound_tokens=70000, target_tokens=90000,
137
+ assembled=assembled, pre_filter_body=copy.deepcopy(body),
138
+ store=mock_store, conversation_id="test-conv",
139
+ summary_ratio=0.0,
140
+ client_truncated=True,
141
+ turn_tag_index=tti,
142
+ )
143
+
144
+ mock_store.load_recent_turn_messages.assert_called_once()
145
+ assert turns >= 1
146
+
147
+
148
+ def test_fill_pass_skips_tool_turns_from_store():
149
+ from unittest.mock import MagicMock
150
+ from virtual_context.proxy.message_filter import fill_pass
151
+ from virtual_context.proxy.formats import detect_format
152
+ from virtual_context.types import AssembledContext, RetrievalResult
153
+ from virtual_context.core.turn_tag_index import TurnTagIndex, TurnTagEntry
154
+ import copy, json
155
+
156
+ body = {
157
+ "system": "test",
158
+ "messages": [{"role": "user", "content": "current question"}],
159
+ "model": "claude-opus-4-6",
160
+ }
161
+ fmt = detect_format(body)
162
+
163
+ mock_store = MagicMock()
164
+ mock_store.get_all_tag_summaries.return_value = []
165
+ mock_store.load_recent_turn_messages.return_value = [
166
+ (10, "run the tests", "Here are the results"),
167
+ (11, "what about baking?", "Bread baking involves..."),
168
+ ]
169
+ mock_store.get_tool_outputs_for_turn.side_effect = lambda cid, tn: ["ref1"] if tn == 10 else []
170
+
171
+ assembled = AssembledContext(
172
+ presented_segment_refs=set(), presented_tags=set(),
173
+ tag_sections={}, retrieval_result=RetrievalResult(),
174
+ )
175
+
176
+ tti = TurnTagIndex()
177
+ for i in range(50):
178
+ tti.entries.append(TurnTagEntry(turn_number=i, message_hash=f"hash_{i}", tags=[f"tag_{i}"]))
179
+
180
+ result_body, summaries, turns = fill_pass(
181
+ body=body, fmt=fmt,
182
+ outbound_tokens=70000, target_tokens=90000,
183
+ assembled=assembled, pre_filter_body=copy.deepcopy(body),
184
+ store=mock_store, conversation_id="test-conv",
185
+ summary_ratio=0.0,
186
+ client_truncated=True,
187
+ turn_tag_index=tti,
188
+ )
189
+
190
+ result_json = json.dumps(result_body)
191
+ assert "Bread baking" in result_json
192
+ assert "run the tests" not in result_json
@@ -0,0 +1,109 @@
1
+ # virtual-context configuration — agentic preset
2
+ # Generated by: virtual-context init agentic
3
+ # Docs: https://github.com/virtual-context/virtual-context
4
+ #
5
+ # Balanced defaults for autonomous agent conversations across any domain.
6
+ # Tags emerge from conversation — no predefined domains to configure.
7
+
8
+ version: "0.2"
9
+ storage_root: ".virtualcontext"
10
+ context_window: 120000
11
+ token_counter: "estimate"
12
+
13
+ paging:
14
+ enabled: true
15
+ auto_promote: true
16
+ auto_evict: true
17
+ max_tool_loops: 10
18
+
19
+ tag_generator:
20
+ type: "llm"
21
+ provider: "ollama"
22
+ model: "qwen3:4b-instruct-2507-fp16"
23
+ max_tags: 10
24
+ min_tags: 5
25
+ max_tokens: 8192
26
+ prompt_mode: "compact"
27
+ context_lookback_pairs: 5
28
+ context_bleed_threshold: 0.1
29
+ keyword_fallback:
30
+ tag_keywords:
31
+ legal: [court, filing, motion, attorney, judge, case]
32
+ medical: [medication, doctor, lab, symptom, dose, blood]
33
+ code: [function, bug, deploy, git, API, database, error]
34
+ tag_patterns:
35
+ legal:
36
+ - "\\b\\d{2}-cv-\\d+\\b"
37
+ - "\\bN\\.?J\\.?S\\.?A\\.?\\b"
38
+ code:
39
+ - "\\bdef \\w+\\("
40
+ - "\\bclass \\w+[:(]"
41
+
42
+ tag_rules:
43
+ - match: "legal*"
44
+ priority: 9
45
+ ttl_days: null
46
+ - match: "medical*"
47
+ priority: 8
48
+ ttl_days: 90
49
+ - match: "debug*"
50
+ priority: 7
51
+ ttl_days: 7
52
+ - match: "*"
53
+ priority: 5
54
+ ttl_days: 30
55
+
56
+ compaction:
57
+ soft_threshold: 0.70
58
+ hard_threshold: 0.85
59
+ protected_recent_turns: 6
60
+ overflow_buffer: 1.2
61
+ summary_ratio: 0.15
62
+ min_summary_tokens: 200
63
+ max_summary_tokens: 2000
64
+ max_concurrent_summaries: 4
65
+ llm_token_overhead: 2000
66
+
67
+ summarization:
68
+ provider: "ollama"
69
+ model: "qwen3:4b-instruct-2507-fp16"
70
+ max_tokens: 1000
71
+ temperature: 0.3
72
+
73
+ providers:
74
+ ollama:
75
+ type: "generic_openai"
76
+ base_url: "http://127.0.0.1:11434/v1"
77
+
78
+ storage:
79
+ backend: "sqlite"
80
+ sqlite:
81
+ path: ".virtualcontext/store.db"
82
+
83
+ facts:
84
+ graph_links: true
85
+
86
+ assembly:
87
+ core_context_max_tokens: 18000
88
+ tag_context_max_tokens: 30000
89
+ facts_max_tokens: 20000
90
+ context_hint_enabled: true
91
+ context_hint_max_tokens: 2000
92
+ core_files: []
93
+
94
+ retrieval:
95
+ skip_active_tags: true
96
+ active_tag_lookback: 4
97
+ inbound_tagger_type: "embedding"
98
+ embedding_model: "all-MiniLM-L6-v2"
99
+ embedding_threshold: 0.3
100
+ strategy_config:
101
+ default:
102
+ min_overlap: 1
103
+ max_results: 10
104
+ max_budget_fraction: 0.25
105
+ include_related: true
106
+
107
+ telemetry:
108
+ enabled: true
109
+ models_file: "models.yaml"
@@ -14,7 +14,7 @@ from .types import (
14
14
  VirtualContextConfig,
15
15
  )
16
16
 
17
- __version__ = "0.2.8"
17
+ __version__ = "0.2.9"
18
18
 
19
19
  __all__ = [
20
20
  "VirtualContextEngine",