henchman-ai 0.1.9__tar.gz → 0.1.10__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 (285) hide show
  1. henchman_ai-0.1.10/.henchman/rag_index/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
  2. henchman_ai-0.1.10/.henchman/rag_index/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
  3. henchman_ai-0.1.10/.henchman/rag_index/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
  4. henchman_ai-0.1.10/.henchman/rag_index/chroma.sqlite3 +0 -0
  5. henchman_ai-0.1.10/.henchman/rag_manifest.json +1 -0
  6. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/CHANGELOG.md +25 -0
  7. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/PKG-INFO +3 -1
  8. henchman_ai-0.1.10/RAG_HOME_DIRECTORY_MIGRATION.md +138 -0
  9. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/pyproject.toml +3 -1
  10. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/app.py +17 -2
  11. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/builtins.py +3 -0
  12. henchman_ai-0.1.10/src/henchman/cli/commands/rag.py +209 -0
  13. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/repl.py +25 -2
  14. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/config/__init__.py +4 -0
  15. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/config/schema.py +60 -21
  16. henchman_ai-0.1.10/src/henchman/rag/__init__.py +38 -0
  17. henchman_ai-0.1.10/src/henchman/rag/chunker.py +206 -0
  18. henchman_ai-0.1.10/src/henchman/rag/embedder.py +148 -0
  19. henchman_ai-0.1.10/src/henchman/rag/indexer.py +373 -0
  20. henchman_ai-0.1.10/src/henchman/rag/repo_id.py +199 -0
  21. henchman_ai-0.1.10/src/henchman/rag/store.py +224 -0
  22. henchman_ai-0.1.10/src/henchman/rag/system.py +225 -0
  23. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/__init__.py +2 -0
  24. henchman_ai-0.1.10/src/henchman/tools/builtins/rag_search.py +146 -0
  25. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/version.py +1 -1
  26. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
  27. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
  28. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
  29. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
  30. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/manifest.json +1 -0
  31. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
  32. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
  33. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
  34. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
  35. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/manifest.json +1 -0
  36. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
  37. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
  38. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
  39. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
  40. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/manifest.json +1 -0
  41. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
  42. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
  43. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
  44. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
  45. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/manifest.json +1 -0
  46. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
  47. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
  48. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
  49. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
  50. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/manifest.json +1 -0
  51. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
  52. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
  53. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
  54. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
  55. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/manifest.json +1 -0
  56. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
  57. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
  58. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
  59. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
  60. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
  61. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/manifest.json +1 -0
  62. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
  63. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
  64. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
  65. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
  66. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
  67. henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/manifest.json +1 -0
  68. henchman_ai-0.1.10/tests/__init__.py +0 -0
  69. henchman_ai-0.1.10/tests/cli/__init__.py +0 -0
  70. henchman_ai-0.1.10/tests/config/__init__.py +0 -0
  71. henchman_ai-0.1.10/tests/core/__init__.py +0 -0
  72. henchman_ai-0.1.10/tests/mcp/__init__.py +0 -0
  73. henchman_ai-0.1.10/tests/providers/__init__.py +0 -0
  74. henchman_ai-0.1.10/tests/rag/__init__.py +1 -0
  75. henchman_ai-0.1.10/tests/rag/test_chunker.py +166 -0
  76. henchman_ai-0.1.10/tests/rag/test_embedder.py +81 -0
  77. henchman_ai-0.1.10/tests/rag/test_indexer.py +240 -0
  78. henchman_ai-0.1.10/tests/rag/test_rag_command.py +137 -0
  79. henchman_ai-0.1.10/tests/rag/test_rag_search_tool.py +136 -0
  80. henchman_ai-0.1.10/tests/rag/test_store.py +234 -0
  81. henchman_ai-0.1.10/tests/rag/test_system.py +286 -0
  82. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/test_version.py +1 -1
  83. henchman_ai-0.1.10/tests/tools/__init__.py +0 -0
  84. henchman_ai-0.1.9/TOOL_CHAINING_DESIGN.md +0 -425
  85. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/.github/copilot-instructions.md +0 -0
  86. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/.github/workflows/ci.yml +0 -0
  87. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/.github/workflows/publish.yml +0 -0
  88. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/.gitignore +0 -0
  89. /henchman_ai-0.1.9/tests/__init__.py → /henchman_ai-0.1.10/.henchman/rag_index/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
  90. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/LICENSE +0 -0
  91. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/PROJECT_PLAN.md +0 -0
  92. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/README.md +0 -0
  93. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/TASK_COMPLETION_SUMMARY.md +0 -0
  94. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/debug_compaction.py +0 -0
  95. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/api.md +0 -0
  96. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/configuration.md +0 -0
  97. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/extensions.md +0 -0
  98. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/getting-started.md +0 -0
  99. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/index.md +0 -0
  100. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/mcp.md +0 -0
  101. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/providers.md +0 -0
  102. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/tools.md +0 -0
  103. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/fix_repl.py +0 -0
  104. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/fix_repl_simple.py +0 -0
  105. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/mkdocs.yml +0 -0
  106. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/replace_method.py +0 -0
  107. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/reproduce_400_error.py +0 -0
  108. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/run_interactive_tests.py +0 -0
  109. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/scripts/ci.sh +0 -0
  110. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/__init__.py +0 -0
  111. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/__main__.py +0 -0
  112. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/__init__.py +0 -0
  113. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/__init__.py +0 -0
  114. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/chat.py +0 -0
  115. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/extensions.py +0 -0
  116. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/mcp.py +0 -0
  117. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/plan.py +0 -0
  118. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/skill.py +0 -0
  119. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/unlimited.py +0 -0
  120. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/console.py +0 -0
  121. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/input.py +0 -0
  122. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/json_output.py +0 -0
  123. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/prompts.py +0 -0
  124. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/repl.py.backup +0 -0
  125. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/repl.py.backup2 +0 -0
  126. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/config/context.py +0 -0
  127. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/config/settings.py +0 -0
  128. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/__init__.py +0 -0
  129. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/agent.py +0 -0
  130. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/agent.py.backup +0 -0
  131. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/events.py +0 -0
  132. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/session.py +0 -0
  133. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/turn.py +0 -0
  134. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/extensions/__init__.py +0 -0
  135. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/extensions/base.py +0 -0
  136. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/extensions/manager.py +0 -0
  137. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/__init__.py +0 -0
  138. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/client.py +0 -0
  139. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/config.py +0 -0
  140. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/manager.py +0 -0
  141. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/tool.py +0 -0
  142. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/__init__.py +0 -0
  143. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/anthropic.py +0 -0
  144. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/base.py +0 -0
  145. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/deepseek.py +0 -0
  146. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/ollama.py +0 -0
  147. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/openai_compat.py +0 -0
  148. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/openai_compat.py.backup +0 -0
  149. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/registry.py +0 -0
  150. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/__init__.py +0 -0
  151. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/executor.py +0 -0
  152. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/learner.py +0 -0
  153. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/models.py +0 -0
  154. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/store.py +0 -0
  155. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/__init__.py +0 -0
  156. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/base.py +0 -0
  157. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/ask_user.py +0 -0
  158. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/file_edit.py +0 -0
  159. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/file_read.py +0 -0
  160. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/file_write.py +0 -0
  161. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/glob_tool.py +0 -0
  162. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/grep.py +0 -0
  163. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/ls.py +0 -0
  164. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/shell.py +0 -0
  165. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/web_fetch.py +0 -0
  166. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/registry.py +0 -0
  167. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/__init__.py +0 -0
  168. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/compaction.py +0 -0
  169. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/retry.py +0 -0
  170. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/tokens.py +0 -0
  171. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/validation.py +0 -0
  172. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_compaction.py +0 -0
  173. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_compaction_fix.py +0 -0
  174. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_fixes.py +0 -0
  175. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_output.txt +0 -0
  176. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_run.py +0 -0
  177. /henchman_ai-0.1.9/tests/cli/__init__.py → /henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
  178. /henchman_ai-0.1.9/tests/config/__init__.py → /henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
  179. /henchman_ai-0.1.9/tests/core/__init__.py → /henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
  180. /henchman_ai-0.1.9/tests/mcp/__init__.py → /henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
  181. /henchman_ai-0.1.9/tests/providers/__init__.py → /henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
  182. /henchman_ai-0.1.9/tests/tools/__init__.py → /henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
  183. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/commands/test_plan.py +0 -0
  184. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/commands/test_skill.py +0 -0
  185. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/commands/test_skill_extended.py +0 -0
  186. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/commands/test_unlimited.py +0 -0
  187. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_app.py +0 -0
  188. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_app_extended.py +0 -0
  189. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_builtins.py +0 -0
  190. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_chat_command.py +0 -0
  191. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_cli_smoke.py +0 -0
  192. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_commands.py +0 -0
  193. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_commands_repro.py +0 -0
  194. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_console.py +0 -0
  195. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_enhanced_tool_display.py +0 -0
  196. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_input.py +0 -0
  197. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_input_bindings.py +0 -0
  198. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_json_output.py +0 -0
  199. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_keyboard_fixes.py +0 -0
  200. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_keyboard_integration.py +0 -0
  201. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_keyboard_interrupt.py +0 -0
  202. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_keyboard_verification.py +0 -0
  203. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_loop_protection.py +0 -0
  204. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_mcp_command.py +0 -0
  205. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_repl.py +0 -0
  206. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_repl_attribute_fix.py +0 -0
  207. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_repl_startup_message.py +0 -0
  208. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_repl_toolbar.py +0 -0
  209. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/config/test_context.py +0 -0
  210. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/config/test_schema.py +0 -0
  211. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/config/test_settings.py +0 -0
  212. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/conftest.py +0 -0
  213. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_automatic_compaction.py +0 -0
  214. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_events.py +0 -0
  215. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_session.py +0 -0
  216. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_session_manager.py +0 -0
  217. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_streaming_tool_calls.py +0 -0
  218. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_turn_state.py +0 -0
  219. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/e2e/test_context_safety.py +0 -0
  220. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/e2e/test_tool_fix.py +0 -0
  221. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/empty_message_validation/test_empty_messages.py +0 -0
  222. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/extensions/__init__.py +0 -0
  223. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/extensions/test_base.py +0 -0
  224. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/extensions/test_command.py +0 -0
  225. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/extensions/test_manager.py +0 -0
  226. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/integration/test_context_limits.py +0 -0
  227. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/integration/test_tool_integration.py +0 -0
  228. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/mcp/test_client.py +0 -0
  229. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/mcp/test_config.py +0 -0
  230. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/mcp/test_manager.py +0 -0
  231. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/mcp/test_tool.py +0 -0
  232. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_413_error_handling.py +0 -0
  233. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_anthropic.py +0 -0
  234. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_base.py +0 -0
  235. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_deepseek.py +0 -0
  236. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_ollama.py +0 -0
  237. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_openai_compat.py +0 -0
  238. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_registry.py +0 -0
  239. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_executor.py +0 -0
  240. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_learner.py +0 -0
  241. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_markdown_skills.py +0 -0
  242. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_models.py +0 -0
  243. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_store.py +0 -0
  244. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_store_extended.py +0 -0
  245. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/smoke/test_escape_key_behavior.py +0 -0
  246. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/smoke/test_large_file_handling.py +0 -0
  247. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/test_coverage_suite.py +0 -0
  248. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/test_main.py +0 -0
  249. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_ask_user_tool.py +0 -0
  250. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_base.py +0 -0
  251. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_directory_tools.py +0 -0
  252. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_file_tools.py +0 -0
  253. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_grep_tool.py +0 -0
  254. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_plan_mode_enforcement.py +0 -0
  255. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_registry.py +0 -0
  256. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_shell_tool.py +0 -0
  257. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_web_fetch_tool.py +0 -0
  258. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/INTERACTIVE_SESSION_TESTS.md +0 -0
  259. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/__init__.py +0 -0
  260. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/conftest.py +0 -0
  261. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_agent.py +0 -0
  262. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_compaction_llm.py +0 -0
  263. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_events.py +0 -0
  264. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_llm.py +0 -0
  265. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_mcp.py +0 -0
  266. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_plan_mode.py +0 -0
  267. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_repl_e2e.py +0 -0
  268. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_repl_integration.py +0 -0
  269. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_session.py +0 -0
  270. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_skills.py +0 -0
  271. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_slash_commands.py +0 -0
  272. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_tokens_llm.py +0 -0
  273. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_tool_calls.py +0 -0
  274. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_tool_integration.py +0 -0
  275. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_compaction.py +0 -0
  276. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_compaction_edge_cases.py +0 -0
  277. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_compaction_validation.py +0 -0
  278. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_multi_turn_tool_calls.py +0 -0
  279. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_protected_zone.py +0 -0
  280. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_retry.py +0 -0
  281. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_summarization.py +0 -0
  282. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_tiktoken_integration.py +0 -0
  283. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_token_counter_extended.py +0 -0
  284. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_tool_sequence_compaction.py +0 -0
  285. {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_validation.py +0 -0
@@ -0,0 +1 @@
1
+ {"files": {".github/copilot-instructions.md": "3f9a03cbb9d661c7bb3ad570579e4dc4c168cd524217f5d3fb5054498d6bec98", ".github/workflows/ci.yml": "21c5ab07549fc77783ecbf799c412dcd264d042a8e4f3060f49361f67eba127a", ".github/workflows/publish.yml": "c94cd6f85515df518e2aba031fc9861480ff8162a9ca48d62f20e095ed727dca", "CHANGELOG.md": "cfadd7fdb55b60b5e3953f2dc57b25dda2bbea10b2329567d15770259b6a7223", "README.md": "64049152c12bb45c0bfc00ea9d0d37593798d0bbcb1e6ab539ddc4444b4ee7cc", "TASK_COMPLETION_SUMMARY.md": "626218de9af1955090a12ccdbc4c36601070ce5c07f8c4cf061dfebd09deb4a4", "debug_compaction.py": "d1176bb9bb7ae4c487fddee30267c34dc0f5a83b0e74f6d6ff223718533ab1ae", "docs/api.md": "918525702474bcaea606a22fbf6de6cc09d5313c05eb35e8e33c7015b98edf1c", "docs/configuration.md": "b658b1ada34181207dc9c179c98d4382c7ca91645285d9adcd1ffda29dc533c8", "docs/extensions.md": "119b282b5334fa716d5d8b64e3586a972e52ef23e9c288434d4f5ef48ad8dd0b", "docs/getting-started.md": "7475ac86d283364d43a20ffbf93b80aa32e827468375c400287657b8607b474e", "docs/index.md": "56629b90eafe0b1b02e6a87c5db466f68997ea0c0c425f92976daee4de812bf3", "docs/mcp.md": "3cde577421456022a219a963897d3fc1c660cb1a6e919043974236eaf5042d99", "docs/providers.md": "03e4295b417c5c382b1210fa6390a6df5fba670d3201a271e40ecb2343eb5fd2", "docs/tools.md": "0003577d1fee2fe9a5b566d32a6d1319fd4677308b7f562c85a94acb9e12ce12", "mkdocs.yml": "7602989a71c67a03a2361e689ca1b4d9a4f9698ba818575c484271f321984373", "pyproject.toml": "ddd1adc1a5e41cd60a516fe0ce24280b62c9b0fa7e950fefaa4d1706260c2bcd", "reproduce_400_error.py": "618fecce2ef4b67c63975d9bd3f7ca077ba4ee5919e81c2c39ed7aa9e70c8b27", "run_interactive_tests.py": "8ee40beaaa27f2a3c0a065786942f9d99012bfae9aa1a6c66f3f30bfc0727d36", "scripts/ci.sh": "8a4bef555fe4a74327bf23beb4a39213ca0d9a893123d5465f804854c5f721be", "src/henchman/__init__.py": "3ff8c26ed80055b936867eae32e9b6518904ee9b53dfad66591914673d312af9", "src/henchman/__main__.py": "de845666fa1638de44ae524560e392539a753c4451c8ae8c913d8b1849db6f6a", "src/henchman/cli/__init__.py": "1aff3a6bf85eb812ea51dfb2e3a259532cd46839791fef51b5c586af7accc01c", "src/henchman/cli/app.py": "edf648ead6b887a153f848b122d0eb8dee1f2941d87368694202fc519b3d1e99", "src/henchman/cli/commands/__init__.py": "bf1c7497370b51b36f92f0c6a4e35209ebca6d447ec0a404b71b1a22331b24c5", "src/henchman/cli/commands/builtins.py": "778c206f755e5b069698ab64d0c2abe4d02fa3e3965607f10102a95a42460455", "src/henchman/cli/commands/chat.py": "aebc3564654375f2623623d24a8c36436bfa235b94e309eb7c51e3f6664e0027", "src/henchman/cli/commands/extensions.py": "afb3dfbdb063c01af95a117c1b8f69dbdcfb14ac7a81e449891f91ebba63ea2d", "src/henchman/cli/commands/mcp.py": "6db5b527df9f229bc30486dadcbd4c02436a0a31414d99d92cd2207fa2e32440", "src/henchman/cli/commands/plan.py": "e595de3e831520a071ba04a70c1e8dd93103a65db166ccd00f3f704d07dfce96", "src/henchman/cli/commands/skill.py": "6b35dbebe2978ed64ac0788157e3e993a09d25029985eb6be3a84d819febe394", "src/henchman/cli/console.py": "4ceb860523546b1c50ca99a6cc2d0fd4863bb4136569380065eb0acbcbae64de", "src/henchman/cli/input.py": "d2a5b7e9fedfd3a72de175dc6bba28c644d28480fe41790bb6644e87fc6ca34e", "src/henchman/cli/json_output.py": "f643fd4b9ab4c4180fe074064d3e0fe830d3efa17d5554dd118fca884a686672", "src/henchman/cli/prompts.py": "03150df897d649eb4e808c21571828b907ad36a63c85373b1672cee636f4d0b2", "src/henchman/cli/repl.py": "d1db21a38acc65bcb19d830ecd4468338e9dc817d80cbaae0ff74ef7f1d9eb23", "src/henchman/config/__init__.py": "dbc52dae13f27b430499b76f8b58c2a8edee2177e6a92019556be7a49bfea93a", "src/henchman/config/context.py": "6c9495e7a6d014080408d3030603366702249f4879d2e89b52d5166909ccabfd", "src/henchman/config/schema.py": "8b7f8b78dad9ab90015b202eddcadce377e2dd00251ce10a86936dd9e4e61625", "src/henchman/config/settings.py": "2b0956957dce82a6ff07221c857f62fe9f15335eae98334e6b49fe4384abc53b", "src/henchman/core/__init__.py": "06d3877ec241e9e5be421b4ae2c6ea3b3ccee862ea59e54b91ec0e03ec2ea8bd", "src/henchman/core/agent.py": "97d0493bc670e1b31d5324c38dc64a1bce16759d4a9dd9b7634f68500645629d", "src/henchman/core/events.py": "5228efdcd18d57cc899d07d8e3cbb4a4106f11ab8011ccc06e4180449cbc99f2", "src/henchman/core/session.py": "364c041b6652dae87665e5fcfcb91237b330425071c214d78f1d01a0d5192c3c", "src/henchman/extensions/__init__.py": "0bb2eb2b9d2e887c262e5386910ca781b16fb9461d09c6446fab9c3a4958ff0b", "src/henchman/extensions/base.py": "7075335aee0e1858eef56af5c408861d938e5bb7906dc0b5f9da8477639edd03", "src/henchman/extensions/manager.py": "c47c4ca34f81c73c857c3ddf660bec8a8bce458a4c33ab0f9c33ce4df50b6525", "src/henchman/mcp/__init__.py": "54c3bc6c8d79635fe8c5cc1d5a9df7e5808732b1e24c39d4d9b78b351e089813", "src/henchman/mcp/client.py": "d6910b53d43cd94cd40aead2ccb66d83196de80171a17c4da7fb7f911fcdcda1", "src/henchman/mcp/config.py": "ab30092133294257d57d95e250dd122c3284adab5747ef412a287b24903ff910", "src/henchman/mcp/manager.py": "0c187ce5299d45b53de832c82304664fa41804a44c34caf9bedd7f5211f1aeb0", "src/henchman/mcp/tool.py": "8de2fe16d802d8949b85f851f11178bcef4fc4b41eb7e28566e0c237aedc606f", "src/henchman/providers/__init__.py": "561f323e12520ad0e0bc4bd8036607450bee19e6ba7829bf0821b5af1a4b6191", "src/henchman/providers/anthropic.py": "430461db70e79a13bc4946c379b274482f0ad491fd3e0c664819e3e69ddb8dfd", "src/henchman/providers/base.py": "db760cdb5b876d25cdeef4fdd8252537a160228ced48e18c83bc8553087673a0", "src/henchman/providers/deepseek.py": "3bffc6c72d311c20e192c1c98136b97febbee5185b4fcb9f87b740ea5cb6c99e", "src/henchman/providers/ollama.py": "838bc64d296ff14116f36cab5512c2aa326a7435bfb06fa4cafc91884e996d88", "src/henchman/providers/openai_compat.py": "847b4516a192b3245c6f3bec63bdcf111ba6dd015cd761bc364de94d71832c1a", "src/henchman/providers/registry.py": "c6c39a62e69e9a00ce3a2f892e2e9445bb68d1d40fefbcbe2e8fffcf352e1065", "src/henchman/skills/__init__.py": "72f0a5e87471b1475a83e453a4c3fffd6c3f85e7b7ee0829017438d705de9845", "src/henchman/skills/executor.py": "b18b2cffcdf376e14b07f0000934973191cb03f96ff93d622874b17a5a6fd775", "src/henchman/skills/learner.py": "97322b2d4e7fa0b6ea0d817aef717eaf06f521a59e78eaa3cdcb01182f882a53", "src/henchman/skills/models.py": "56fafa39bc507b91bc130b8b5b639dce97a3dc27f2a869205e0090718f75c29b", "src/henchman/skills/store.py": "cffa879d57721c09be8ed18dcb96f7dddf6343ede937e9a48eb040cdcec20395", "src/henchman/tools/__init__.py": "34b42e611b4f1028eef1364783e660554aed7651dd313bbb3fc0b70f836176a8", "src/henchman/tools/base.py": "3cf78a4ba8ce0afde31528237798f79338234f3c3b5690406378a499e0e521c2", "src/henchman/tools/builtins/__init__.py": "55c785378558e03304c9723343ceb267effe9bbe701c2c8a610f3d7b1d950784", "src/henchman/tools/builtins/ask_user.py": "c4fbbbe1c074ad86a16476a355d8ca81d98a535db5496c808194a453fc016234", "src/henchman/tools/builtins/file_edit.py": "5637e961566e969201b9f45222c4f1f5e0f98181a74b26e4b32a39bc608be30a", "src/henchman/tools/builtins/file_read.py": "4490ac2bd63e3366dde0807c86719a32377397ad964aaef0392f5aa5c037b610", "src/henchman/tools/builtins/file_write.py": "d2f0c07ba2406470dd188852a5fdaae00a7143f0ca2f42f8f7f8dfaa882c897a", "src/henchman/tools/builtins/glob_tool.py": "ecd0256a7e40eaff915802148fc203efc698452bd77bd26db7623a202cc472eb", "src/henchman/tools/builtins/grep.py": "3d5f17db276702eb6b5824b9551f650011697d2bf43a5ceca9ad4ab5be57e33d", "src/henchman/tools/builtins/ls.py": "e624aa1e296b12267cce2386e272b00bdd1fb8b131d3557fd01cdf4b63cd02ba", "src/henchman/tools/builtins/shell.py": "1b1f31d6306ad4dbc44459dcfa450d328bc5a1683f8b822b57f6ac9121027c43", "src/henchman/tools/builtins/web_fetch.py": "bb08199b4c9edf20ee4b65360cf5780fef1b8ef8980d328df9c362ee608c469c", "src/henchman/tools/registry.py": "62b0f3dbd9b03063c6749079443d1095a907889fb6e29dddfe39c868c634e612", "src/henchman/utils/__init__.py": "6b2bb65d1371dc5c34cfcbdb2277badc0de0063c6eefbf5013cb1442c8cd9e6e", "src/henchman/utils/compaction.py": "8cfa49e6d426f88067e180a1886acacbcbbf2b8389db7964dc9beaf2c35b4187", "src/henchman/utils/tokens.py": "0fd1f872214d1fb9756f4e4819bc34534b66cb6c85e5a22d159c83b9f185e779", "src/henchman/utils/validation.py": "9a88f82d05d55edd89fb7fe95951ffd3e11a6f2458029394d8e8792524c8b9af", "src/henchman/version.py": "143feeca497cd1e7cd22fce720bbfa3cb3fd53adbf37d6ba3c9b69346fa78650", "test_compaction.py": "2741d592b110eb7d4c97b978e123325041bade06d9eb71eed5c15d7b924dce2c", "test_compaction_fix.py": "f887aac4296123c0c8838c99b93f6c9c43a2ed5f543bd88e608ac47511a5ec34", "test_output.txt": "8b2ddcf428eb722e747849d9b0de75694ebbc2829908c374cd64153f6e2944a6", "test_run.py": "fc78e5e1f233ede8637faa5267d3c57be8515a22fbf952e2b6dbb085a9366dc2", "tests/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tests/cli/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tests/cli/commands/test_plan.py": "031cfb7336dcdccf0f8a69dbc57bde1c098ecd73a9267c898ad9aea582db43e4", "tests/cli/commands/test_skill.py": "78153940821fb05c983fd4bcda5af1fde0c0995e0139f589efa7dcb3820955ba", "tests/cli/commands/test_skill_extended.py": "b780c2e0e6b592e98b825b161e52577f5ccdc935693f052d4e2a74e19249259b", "tests/cli/test_app.py": "dfd48e31ececf49ce307abc422e35b4d5b97c95cf5feb96ac359f74b030b4a17", "tests/cli/test_app_extended.py": "a6257ce721f77fbbb29537d2e7d076864708ec6036b8b288012383263acda118", "tests/cli/test_builtins.py": "4f803025b90cb3439f8ceb69a54405f18c6f5059f5c7af4554d15c3b43545af7", "tests/cli/test_chat_command.py": "657cf8bf579d731b6291324e8859ca7d705778a7746475d501427ee9c33babf9", "tests/cli/test_commands.py": "5edbec4856bc2e82a85f0513323959443ab1127cc04960428213d699b9481d99", "tests/cli/test_commands_repro.py": "94a4e2760a164ddddd7cae26d2cadfac8170d0fac7007166d97f30bc0a39c895", "tests/cli/test_console.py": "071b6f45357e4e665ea3d94cc4fb5d825daf60a0c28d48be60a763491e46b851", "tests/cli/test_enhanced_tool_display.py": "be3d8584a8be1d34b7883a4d7aec6136f93447caa9c19cb69c9a34e696555dac", "tests/cli/test_input.py": "926a815894767d69c11be115190740a6ed702aa6dace744ad9d3192327a35ce8", "tests/cli/test_input_bindings.py": "c13b2c2b8d3ef8cd3bbafc57c6478000ceb9bf2d89e04fcf88625431f14e063a", "tests/cli/test_json_output.py": "430da766ceb73ff4702e9b1d89e0a092c091c9760b1426870700a05ff7849974", "tests/cli/test_keyboard_fixes.py": "ec0741997ea0a1a1a676f6b1bb8633d12d52683e1cdfbf921a64c243f0de266c", "tests/cli/test_keyboard_integration.py": "3281afacf541730d1afea178a02c44361618085d264bb35e0e5bd0158ec86760", "tests/cli/test_keyboard_interrupt.py": "1e7ffb089f7f80f85d63c246ccf64e3703835cf968b09142890b43a97c7296c3", "tests/cli/test_keyboard_verification.py": "297bf3173b9d58979d39e8c0f643d6754265eebf864969f369d5a348d9ac6aaf", "tests/cli/test_mcp_command.py": "b229047b6b025c1de365ec80ff796bd3dedb9dd77a2cc6b483c7f43c02b4fe9d", "tests/cli/test_repl.py": "410d43450e311fe78f2e3cf9aca8aea3241d72e04fb551f67e59b7e7c6887f5f", "tests/cli/test_repl_attribute_fix.py": "f1b2c01e508492eb4d9848c737e3f84dcf08b3175f469b2d7d7a92f8645dfb29", "tests/cli/test_repl_startup_message.py": "76c43b4f93e2dc49fa27e17fedf2da0a19b990ec1f809849836b2354d91d691d", "tests/cli/test_repl_toolbar.py": "e51a379687df996dbee876e870d77ac4015e1afcffa666a456bf2999fbf8000f", "tests/config/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tests/config/test_context.py": "bf727e05b11a75db30b75d1e96b9d4f1c007e0a670624f39c4a15c6b8375f137", "tests/config/test_schema.py": "24ea399212e5b2214ffb927b852eea312c35ae884f7b54e52b133777e77edcc4", "tests/config/test_settings.py": "cc6560eecd76928d428805a9b7685dc004ca9d842f01af13ec0b322622579d10", "tests/conftest.py": "bd62befbd3272202da55c981c4a1b3f9658803e355042a2add457ae500fd3616", "tests/core/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tests/core/test_automatic_compaction.py": "fde6b3339489dec79f558677c1b915f64772ee82798ccefc29b51f1e373f13f6", "tests/core/test_events.py": "294a43c1d77d6315aaed0af89991049413dd560009047f672213710886c3fb10", "tests/core/test_session.py": "ab7385e6610bbabf5ec77dd4d6eebf9c4c926b24b7124ce521db11f716a6ae39", "tests/core/test_session_manager.py": "34f99c69190ed0a043f17a9eb5f0ae4464789d6d1037a441b9962645ebbccce0", "tests/e2e/test_context_safety.py": "41ba3ba4f9094a3ea530a9ad00edfb9c8e70d15f7263aae9ca5ba5ca857a4e2d", "tests/e2e/test_tool_fix.py": "619ad693994e1431a2a9599de8675060adc3f866eba86cc4022cb65a4d9d9c9e", "tests/empty_message_validation/test_empty_messages.py": "a5424b350c66082d5af9913db6a09c89fe2c818dd22aca45bf3a944509ea1f21", "tests/extensions/__init__.py": "cf3a12987fade1f95fdefa753e935567eb59423a27599b5bc52916d43775bb36", "tests/extensions/test_base.py": "181c19fdad0af9669ce4a7b5dbb2d08b9449c8166d11bb1fd201a7599be21419", "tests/extensions/test_command.py": "dc0fa67d9158243227f1f6b6658e042377537ad1cc8d11552c34c0bc28b17316", "tests/extensions/test_manager.py": "2fb13ba2f09a31c69ff41e79b47645ed03818003ff9027759c70aa6ecbd515a9", "tests/integration/test_tool_integration.py": "cd9556edacf29af4b4c145be1331a3baae676911fc6b38e0c87419c5dde9e3f9", "tests/mcp/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tests/mcp/test_client.py": "fe1f9c6f9b1948d9351c954f28d6d0eb03b29cef121630e617524d71fc5a72d7", "tests/mcp/test_config.py": "5fb6914fe7308aa6050b7d2997180b5f0528289eb8b68034b0ffb7179890b214", "tests/mcp/test_manager.py": "c55c000015d46fbd435465aef6d2a5ebd135881c5a64bcb7202fd130ea8c6987", "tests/mcp/test_tool.py": "d39d18ac205907b649e477eede46effc6e71c42f94f277ca8fa46d6d9f5a1bd0", "tests/providers/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tests/providers/test_anthropic.py": "a0334a27ad228bc63d2eb0359bc1a41c52d98047c9f1e8758c131b0fb1ef82e2", "tests/providers/test_base.py": "78a2eb74193747d92809929139bbf8e40786d7e990c83b92283b39ae6314bd24", "tests/providers/test_deepseek.py": "334d4c1de1e44d774a48e62efb07a2359877d9f537381524543aaf90ad75002b", "tests/providers/test_ollama.py": "6bbfe1ea2b06418a74eccf4f1a04be5ae2a2ee78f6f99215d873a9a0fe896727", "tests/providers/test_openai_compat.py": "3a3ef9998bf199fcf470e3eee77f2406afd0d685e9ac73c2b338b07c77160061", "tests/providers/test_registry.py": "7f6c90ec6e8f73ce175f1c5189d1a9a1ca4af2851b98a28dcc7ca1908236e49b", "tests/skills/test_executor.py": "5c59f5de71f44d0bb95bd80a5cede689b47ef78c3410172650ecd55723ecb450", "tests/skills/test_learner.py": "5abb83d279d712ac38c50bc9eb62980925de209e2cae1d620d77594aafc050c2", "tests/skills/test_markdown_skills.py": "96caf1c75b6f4c8257a94fe30ea8041413d7f86662be330b9f00db3e7f5b45e7", "tests/skills/test_models.py": "bada7b4b035c4816fa84f63d66f11da186484204187b2c7411d7e2ae3823c368", "tests/skills/test_store.py": "223727c79fd5b9c32129b4bb8fad84a1171178ca5057a23efbc4f1b8a6369ab3", "tests/skills/test_store_extended.py": "4d19c797e4d06180ddb9228544eb1169418f0c9a969c5c3edbf079423c738e1a", "tests/test_coverage_suite.py": "568bf304e7e1e40adc50bcb5b545c5c5f6626f95eebcbc333195bc6f396e8b5f", "tests/test_main.py": "310d21d5770708e34ea4988c0c9b8d0dae8b7c52f0f8d8f8a0c4428fa8960dbb", "tests/test_version.py": "5ed97404f6abbbfd18a82543532c29b6f5153b05bf0ac497550a2ab98e122e5a", "tests/tools/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tests/tools/test_ask_user_tool.py": "c8b65f5472a0272366d23bc4aa7ad00504bd85225b251731f92d32bf5fe00c47", "tests/tools/test_base.py": "3122e30c31fa258e95d3b72a53db7ac97b1e5c1cbe3f648b76df93b9138c5556", "tests/tools/test_directory_tools.py": "2152be54fb877c57f26fcdba14f7f47ac8635ed2c3f1b2d6ef36d125a215d5ee", "tests/tools/test_file_tools.py": "aa4aac1fd829cc8c60ea205a8f518535c62bc7c3a72e76e20e580d8a7898d35c", "tests/tools/test_grep_tool.py": "61343cddbf5500bb39e8e01be639f9b373575bfb0c8d017c652057054063ae64", "tests/tools/test_plan_mode_enforcement.py": "7f1e933192f2e486462099b767f2d0483b86b5d413f6515840500959c8803d61", "tests/tools/test_registry.py": "91f388fa13670d62fcb9e450ce65d73542a2a104d3b3387aafae21e6fb97d24f", "tests/tools/test_shell_tool.py": "ec988aa8a61cca94a5decdd274fbab7e86c545244aefc4feb44494f7c25c256e", "tests/tools/test_web_fetch_tool.py": "43586b2775d680ca5415c2e2a72a5315102a3f379a83c4fde929684b0f3179cb", "tests/ui_integration/INTERACTIVE_SESSION_TESTS.md": "e4e75166e6d1506166b54f529a409321eb27a3e74d5e10ab76ed1a4a46827499", "tests/ui_integration/__init__.py": "f1fcbe7c6709f61813521e114a5ad0a0e0aff087cc54040def9ace046fe586e2", "tests/ui_integration/conftest.py": "a10bdf9f81100b44cba94cf109659eaefa88e9c3f297510a9f6439dc17e29b57", "tests/ui_integration/test_agent.py": "c3678ae7abbfeb539caa662170e4c8c4d06888a24258a8c767ae11bcfc8f5a8d", "tests/ui_integration/test_compaction_llm.py": "637871587c7cd199c972dfaf15f118bdc35f06c60da80ccfcc6160ff63840e97", "tests/ui_integration/test_events.py": "0d47928ae6794ccc85c71acdbf03a59a5c83b333f724a059a41a35dae5599a74", "tests/ui_integration/test_llm.py": "d74196c45db76ddb4cd1ad9af0a3f1607ab7b27ff7407e5561e5d6cb6d450eb6", "tests/ui_integration/test_mcp.py": "cec577984152bcb6c6a050a9d9f39da99769f6fb2ce596a1b999454fa6a12bfe", "tests/ui_integration/test_plan_mode.py": "9daceefd09aa3de82e2b674e14fc68afe4e09049459364b630e358bb82bd1b15", "tests/ui_integration/test_repl_e2e.py": "76cbc407374e558b5dbdfe83e1db65f020caa9a4575357a4499d75bacf96afe9", "tests/ui_integration/test_repl_integration.py": "14f8067587a27165d1a1ffd35130fba3246d344b7604d34cabf54e2d69e26028", "tests/ui_integration/test_session.py": "618bcf49be8d18079e53064ffd71fe6558dffe625709e2baca4f87f4db60f91e", "tests/ui_integration/test_skills.py": "33d9c7ee871e6f2bf9c6f79843924c710401172b222289335d775ef163b18896", "tests/ui_integration/test_slash_commands.py": "9fe6e183fa7a5caa726d96d191bc907fba7ba914a91905dd6ffe81fb5ee3ea51", "tests/ui_integration/test_tokens_llm.py": "b735242f47f9881d642b47d43c4d24ff032b1dcfdb5b92174d2db1375ab17879", "tests/ui_integration/test_tool_calls.py": "9cb72c14bda5db8e459d25b93ca95ce62ba941b6fa7f1ae5b7c95c31ecdc59c9", "tests/ui_integration/test_tool_integration.py": "b32fde0ec001b195a4763d991b4af77dcad93b0142f2a99db1fb7c0df1181d43", "tests/utils/test_compaction.py": "738e6e8fd2beb91af4b19197a618451b39ecf97643782c7d3c5819d65c227140", "tests/utils/test_token_counter_extended.py": "5cb5559001e1df7f3c63264daba99b74a2e2718b298b35e203cacada3537acef", "tests/utils/test_tool_sequence_compaction.py": "e7db8dabea47fe70093b7d6302509f7abe9bc92e1845a1c572345ee192684144", "tests/utils/test_validation.py": "6474498b394e549a6d784ea53af692c8a0304b6dfeae7a751d71bf19e239ec5b"}, "model_name": "BAAI/bge-small-en-v1.5", "chunk_size": 512}
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.10] - 2026-01-28
11
+
12
+ ### Added
13
+
14
+ - **RAG Home Directory Storage**
15
+ - RAG indices now stored in `~/.henchman/rag_indices/` instead of project directories
16
+ - Automatic migration of existing project-based indices to home directory
17
+ - Repository identification using git remote URLs and paths for consistent caching
18
+ - New `/rag clear-all` command to clear ALL RAG indices
19
+ - New `/rag cleanup` command to remove old project-based indices
20
+
21
+ ### Changed
22
+
23
+ - **RAG Configuration**
24
+ - Removed `index_path` setting from RagSettings
25
+ - Added `cache_dir` setting for custom cache location (defaults to `~/.henchman/rag_indices/`)
26
+ - Updated RAG system to use centralized cache instead of project-based storage
27
+
28
+ ### Fixed
29
+
30
+ - **Code Quality**
31
+ - Updated all RAG tests to work with new home directory storage
32
+ - Fixed test assertions for manifest file locations
33
+ - Enhanced test coverage for repository identification
34
+
10
35
  ## [0.1.9] - 2026-01-28
11
36
 
12
37
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: henchman-ai
3
- Version: 0.1.9
3
+ Version: 0.1.10
4
4
  Summary: A model-agnostic AI agent CLI - your AI henchman for the terminal
5
5
  Project-URL: Homepage, https://github.com/MGPowerlytics/henchman-ai
6
6
  Project-URL: Repository, https://github.com/MGPowerlytics/henchman-ai
@@ -25,7 +25,9 @@ Requires-Python: >=3.10
25
25
  Requires-Dist: aiohttp>=3.9
26
26
  Requires-Dist: anthropic>=0.40
27
27
  Requires-Dist: anyio>=4.0
28
+ Requires-Dist: chromadb>=0.4
28
29
  Requires-Dist: click>=8.0
30
+ Requires-Dist: fastembed>=0.3
29
31
  Requires-Dist: httpx>=0.27
30
32
  Requires-Dist: mcp>=1.0
31
33
  Requires-Dist: openai>=1.40
@@ -0,0 +1,138 @@
1
+ # RAG Home Directory Migration
2
+
3
+ ## Summary
4
+ Modified the RAG (Retrieval-Augmented Generation) system to store indices in the user's home directory (`~/.henchman/rag_indices/`) instead of project directories (`.henchman/rag_index/`).
5
+
6
+ ## Problem
7
+ The original implementation stored RAG data in project directories, which:
8
+ 1. Polluted git status with vector database files
9
+ 2. Created duplicate indices for the same repository in different locations
10
+ 3. Caused permission issues in shared or read-only directories
11
+ 4. Left artifacts behind when projects were deleted
12
+ 5. Wasted disk space with multiple copies
13
+
14
+ ## Solution
15
+ Move RAG storage to a centralized cache in the user's home directory with repository-specific subdirectories.
16
+
17
+ ## Changes Made
18
+
19
+ ### 1. New Module: `src/henchman/rag/repo_id.py`
20
+ - **Repository identification**: Computes unique IDs for git repositories using remote URLs and paths
21
+ - **Cache directory management**: Functions to get repository-specific cache directories
22
+ - **Migration utilities**: Tools to migrate old project-based indices to new location
23
+
24
+ ### 2. Updated Configuration Schema: `src/henchman/config/schema.py`
25
+ - **Removed**: `index_path` setting (no longer needed)
26
+ - **Added**: `cache_dir` setting (optional custom cache location)
27
+ - **Default**: Uses `~/.henchman/rag_indices/` if not specified
28
+
29
+ ### 3. Updated RAG System: `src/henchman/rag/system.py`
30
+ - **Modified initialization**: Uses home directory cache instead of project directory
31
+ - **Added migration**: Automatically migrates old indices on first run
32
+ - **Updated paths**: All references to index paths updated to use new location
33
+
34
+ ### 4. Updated Indexer: `src/henchman/rag/indexer.py`
35
+ - **Added manifest_path parameter**: Allows custom manifest file location
36
+ - **Updated initialization**: Accepts manifest path from RagSystem
37
+
38
+ ### 5. Enhanced CLI Commands: `src/henchman/cli/commands/rag.py`
39
+ - **Added `/rag clear-all`**: Clears ALL RAG indices from cache
40
+ - **Added `/rag cleanup`**: Removes old project-based indices
41
+ - **Updated status display**: Shows new cache directory location
42
+
43
+ ### 6. Updated Exports: `src/henchman/rag/__init__.py`
44
+ - **Added new exports**: Repository ID utilities and migration functions
45
+
46
+ ## Directory Structure
47
+
48
+ ### Old Structure (Project-based)
49
+ ```
50
+ project/
51
+ ├── .henchman/
52
+ │ ├── rag_index/ # ChromaDB files
53
+ │ └── rag_manifest.json # Index metadata
54
+ └── ... (project files)
55
+ ```
56
+
57
+ ### New Structure (Home directory-based)
58
+ ```
59
+ ~/.henchman/
60
+ ├── config.yaml
61
+ ├── skills/
62
+ ├── extensions/
63
+ └── rag_indices/ # Centralized cache
64
+ ├── {repo_hash_1}/ # Repository-specific
65
+ │ ├── chroma/ # ChromaDB files
66
+ │ └── manifest.json # Index metadata
67
+ ├── {repo_hash_2}/
68
+ │ ├── chroma/
69
+ │ └── manifest.json
70
+ └── ...
71
+ ```
72
+
73
+ ## Repository Identification
74
+ Uses a deterministic hash based on:
75
+ 1. **Git remote URL** (if available) - most stable identifier
76
+ 2. **Git revision + path** (if no remote)
77
+ 3. **Absolute path** (fallback)
78
+
79
+ This ensures:
80
+ - Same repository → same cache location across different checkouts
81
+ - Different repositories → different cache locations
82
+ - No conflicts between repositories
83
+
84
+ ## Migration Process
85
+ 1. **Automatic migration**: On first run, existing project-based indices are moved to home directory
86
+ 2. **Cleanup command**: `/rag cleanup` removes old project-based indices
87
+ 3. **Backward compatible**: Old code paths still work during transition
88
+
89
+ ## New CLI Commands
90
+
91
+ ### `/rag status`
92
+ Shows index statistics including new cache location.
93
+
94
+ ### `/rag clear`
95
+ Clears current project's index (as before).
96
+
97
+ ### `/rag clear-all`
98
+ **NEW**: Clears ALL RAG indices from cache directory (requires confirmation).
99
+
100
+ ### `/rag cleanup`
101
+ **NEW**: Removes old project-based indices (`.henchman/rag_index/` and `rag_manifest.json`).
102
+
103
+ ## Benefits
104
+
105
+ 1. **Clean projects**: No RAG artifacts in project directories
106
+ 2. **Shared cache**: One index per repository across all locations
107
+ 3. **Space efficient**: No duplicate indices
108
+ 4. **Easy management**: Centralized location for all indices
109
+ 5. **Better permissions**: User home directory always writable
110
+ 6. **Automatic cleanup**: Old indices don't linger after project deletion
111
+
112
+ ## Configuration
113
+
114
+ ### Default (recommended)
115
+ ```yaml
116
+ rag:
117
+ enabled: true
118
+ # Uses ~/.henchman/rag_indices/
119
+ ```
120
+
121
+ ### Custom Cache Location
122
+ ```yaml
123
+ rag:
124
+ enabled: true
125
+ cache_dir: "/path/to/custom/cache"
126
+ ```
127
+
128
+ ## Testing
129
+ - All existing tests pass
130
+ - Added comprehensive integration tests
131
+ - Verified migration functionality
132
+ - Tested repository identification
133
+
134
+ ## Notes
135
+ - The change is backward compatible with automatic migration
136
+ - Users can manually clean up old indices with `/rag cleanup`
137
+ - Cache directory is created on first use
138
+ - Repository IDs are deterministic and stable
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "henchman-ai"
7
- version = "0.1.9"
7
+ version = "0.1.10"
8
8
  description = "A model-agnostic AI agent CLI - your AI henchman for the terminal"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -41,6 +41,8 @@ dependencies = [
41
41
  "mcp>=1.0",
42
42
  "aiohttp>=3.9",
43
43
  "tiktoken>=0.5",
44
+ "fastembed>=0.3",
45
+ "chromadb>=0.4",
44
46
  ]
45
47
 
46
48
  [project.optional-dependencies]
@@ -67,6 +67,7 @@ def _run_interactive(output_format: str, plan_mode: bool = False) -> None:
67
67
  """
68
68
  from henchman.cli.repl import Repl, ReplConfig
69
69
  from henchman.config import ContextLoader, load_settings
70
+ from henchman.rag import initialize_rag
70
71
 
71
72
  provider = _get_provider()
72
73
  settings = load_settings()
@@ -83,6 +84,12 @@ def _run_interactive(output_format: str, plan_mode: bool = False) -> None:
83
84
  settings=settings
84
85
  )
85
86
 
87
+ # Initialize RAG system
88
+ rag_system = initialize_rag(settings.rag, console=console)
89
+ if rag_system:
90
+ repl.tool_registry.register(rag_system.search_tool)
91
+ repl.rag_system = rag_system
92
+
86
93
  # Set plan mode if requested
87
94
  if plan_mode and repl.session:
88
95
  repl.session.plan_mode = True
@@ -111,10 +118,12 @@ def _run_headless(prompt: str, output_format: str, plan_mode: bool = False) -> N
111
118
  """
112
119
  from henchman.cli.json_output import JsonOutputRenderer
113
120
  from henchman.cli.repl import Repl, ReplConfig
114
- from henchman.config import ContextLoader
121
+ from henchman.config import ContextLoader, load_settings
115
122
  from henchman.core.events import EventType
123
+ from henchman.rag import initialize_rag
116
124
 
117
125
  provider = _get_provider()
126
+ settings = load_settings()
118
127
 
119
128
  # Load context from MLG.md files
120
129
  context_loader = ContextLoader()
@@ -126,7 +135,13 @@ def _run_headless(prompt: str, output_format: str, plan_mode: bool = False) -> N
126
135
  system_prompt += PLAN_MODE_PROMPT
127
136
 
128
137
  config = ReplConfig(system_prompt=system_prompt)
129
- repl = Repl(provider=provider, console=console, config=config)
138
+ repl = Repl(provider=provider, console=console, config=config, settings=settings)
139
+
140
+ # Initialize RAG system
141
+ rag_system = initialize_rag(settings.rag) # No console output in headless
142
+ if rag_system:
143
+ repl.tool_registry.register(rag_system.search_tool)
144
+ repl.rag_system = rag_system
130
145
 
131
146
  # Set plan mode if requested
132
147
  if plan_mode and repl.session: # pragma: no cover
@@ -7,6 +7,7 @@ from __future__ import annotations
7
7
 
8
8
  from henchman.cli.commands import Command, CommandContext
9
9
  from henchman.cli.commands.plan import PlanCommand
10
+ from henchman.cli.commands.rag import RagCommand
10
11
  from henchman.cli.commands.skill import SkillCommand
11
12
  from henchman.cli.commands.unlimited import UnlimitedCommand
12
13
 
@@ -50,6 +51,7 @@ class HelpCommand(Command):
50
51
  ctx.console.print("\n[bold blue]Henchman-AI Commands[/]\n")
51
52
  ctx.console.print(" /help - Show this help message")
52
53
  ctx.console.print(" /plan - Toggle Plan Mode (Read-Only)")
54
+ ctx.console.print(" /rag - Manage semantic search index")
53
55
  ctx.console.print(" /skill - Manage and execute learned skills")
54
56
  ctx.console.print(" /quit - Exit the CLI")
55
57
  ctx.console.print(" /clear - Clear the screen")
@@ -205,6 +207,7 @@ def get_builtin_commands() -> list[Command]:
205
207
  ClearCommand(),
206
208
  ToolsCommand(),
207
209
  PlanCommand(),
210
+ RagCommand(),
208
211
  SkillCommand(),
209
212
  UnlimitedCommand(),
210
213
  ]
@@ -0,0 +1,209 @@
1
+ """RAG system management command.
2
+
3
+ This module provides the /rag command for managing the RAG index.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import shutil
9
+ from pathlib import Path
10
+ from typing import TYPE_CHECKING
11
+
12
+ from henchman.cli.commands import Command, CommandContext
13
+
14
+ if TYPE_CHECKING:
15
+ from henchman.rag.system import RagSystem
16
+
17
+
18
+ class RagCommand(Command):
19
+ """/rag command for RAG index management."""
20
+
21
+ @property
22
+ def name(self) -> str:
23
+ """Command name.
24
+
25
+ Returns:
26
+ Command name string.
27
+ """
28
+ return "rag"
29
+
30
+ @property
31
+ def description(self) -> str:
32
+ """Command description.
33
+
34
+ Returns:
35
+ Description string.
36
+ """
37
+ return "Manage RAG (semantic search) index"
38
+
39
+ @property
40
+ def usage(self) -> str:
41
+ """Command usage.
42
+
43
+ Returns:
44
+ Usage string.
45
+ """
46
+ return "/rag <status|reindex|clear|clear-all|cleanup>"
47
+
48
+ async def execute(self, ctx: CommandContext) -> None:
49
+ """Execute the rag command.
50
+
51
+ Args:
52
+ ctx: Command context.
53
+ """
54
+ if not ctx.args:
55
+ await self._show_help(ctx)
56
+ return
57
+
58
+ subcommand = ctx.args[0].lower()
59
+ if subcommand == "status":
60
+ await self._status(ctx)
61
+ elif subcommand == "reindex":
62
+ await self._reindex(ctx)
63
+ elif subcommand == "clear":
64
+ await self._clear(ctx)
65
+ elif subcommand == "clear-all":
66
+ await self._clear_all(ctx)
67
+ elif subcommand == "cleanup":
68
+ await self._cleanup(ctx)
69
+ else:
70
+ await self._show_help(ctx)
71
+
72
+ async def _show_help(self, ctx: CommandContext) -> None:
73
+ """Show help for /rag command."""
74
+ ctx.console.print("\n[bold blue]RAG Index Commands[/]\n")
75
+ ctx.console.print(" /rag status - Show index statistics")
76
+ ctx.console.print(" /rag reindex - Force full reindex of all files")
77
+ ctx.console.print(" /rag clear - Clear current project's index")
78
+ ctx.console.print(" /rag clear-all - Clear ALL RAG indices")
79
+ ctx.console.print(" /rag cleanup - Clean up old project-based indices")
80
+ ctx.console.print("")
81
+
82
+ def _get_rag_system(self, ctx: CommandContext) -> RagSystem | None:
83
+ """Get the RAG system from context.
84
+
85
+ Args:
86
+ ctx: Command context.
87
+
88
+ Returns:
89
+ RagSystem if available, None otherwise.
90
+ """
91
+ # The RAG system is stored on the repl object
92
+ repl = getattr(ctx, "repl", None)
93
+ if repl is None:
94
+ return None
95
+ return getattr(repl, "rag_system", None)
96
+
97
+ async def _status(self, ctx: CommandContext) -> None:
98
+ """Show RAG index status."""
99
+ rag_system = self._get_rag_system(ctx)
100
+
101
+ if rag_system is None:
102
+ ctx.console.print(
103
+ "[yellow]RAG not available. "
104
+ "Make sure you're in a git repository and RAG is enabled.[/]"
105
+ )
106
+ return
107
+
108
+ stats = rag_system.get_stats()
109
+ ctx.console.print("\n[bold blue]RAG Index Status[/]\n")
110
+ ctx.console.print(f" Git root: {rag_system.git_root}")
111
+ ctx.console.print(f" Index directory: {rag_system.index_dir}")
112
+ ctx.console.print(f" Embedding model: {rag_system.settings.embedding_model}")
113
+ ctx.console.print(f" Chunk size: {rag_system.settings.chunk_size} tokens")
114
+ ctx.console.print(f" Files indexed: {stats.files_unchanged}")
115
+ ctx.console.print(f" Total chunks: {stats.total_chunks}")
116
+ ctx.console.print("")
117
+
118
+ async def _reindex(self, ctx: CommandContext) -> None:
119
+ """Force full reindex."""
120
+ rag_system = self._get_rag_system(ctx)
121
+
122
+ if rag_system is None:
123
+ ctx.console.print(
124
+ "[yellow]RAG not available. "
125
+ "Make sure you're in a git repository and RAG is enabled.[/]"
126
+ )
127
+ return
128
+
129
+ ctx.console.print("[dim]Forcing full reindex...[/]")
130
+ stats = rag_system.index(console=ctx.console, force=True)
131
+ ctx.console.print(
132
+ f"[green]Reindex complete: {stats.files_added} files, "
133
+ f"{stats.total_chunks} chunks[/]"
134
+ )
135
+
136
+ async def _clear(self, ctx: CommandContext) -> None:
137
+ """Clear the RAG index."""
138
+ rag_system = self._get_rag_system(ctx)
139
+
140
+ if rag_system is None:
141
+ ctx.console.print(
142
+ "[yellow]RAG not available. "
143
+ "Make sure you're in a git repository and RAG is enabled.[/]"
144
+ )
145
+ return
146
+
147
+ rag_system.clear()
148
+ ctx.console.print("[green]Current project's RAG index cleared[/]")
149
+
150
+ async def _clear_all(self, ctx: CommandContext) -> None:
151
+ """Clear ALL RAG indices from the cache directory."""
152
+ from henchman.rag.repo_id import get_rag_cache_dir
153
+
154
+ cache_dir = get_rag_cache_dir()
155
+
156
+ if not cache_dir.exists():
157
+ ctx.console.print("[yellow]No RAG cache directory found[/]")
158
+ return
159
+
160
+ # Ask for confirmation
161
+ ctx.console.print("[yellow]Warning: This will delete ALL RAG indices![/]")
162
+ confirm = await ctx.repl.ask_user(
163
+ "Are you sure you want to delete ALL RAG indices? (yes/no): "
164
+ )
165
+
166
+ if confirm and confirm.lower() in ("yes", "y"):
167
+ try:
168
+ shutil.rmtree(cache_dir)
169
+ ctx.console.print(f"[green]Cleared all RAG indices from {cache_dir}[/]")
170
+ except Exception as e:
171
+ ctx.console.print(f"[red]Error clearing indices: {e}[/]")
172
+ else:
173
+ ctx.console.print("[dim]Operation cancelled[/]")
174
+
175
+ async def _cleanup(self, ctx: CommandContext) -> None:
176
+ """Clean up old project-based RAG indices."""
177
+ from henchman.rag.system import find_git_root
178
+
179
+ # Find git root if we're in a repository
180
+ git_root = find_git_root()
181
+ if not git_root:
182
+ ctx.console.print("[yellow]Not in a git repository[/]")
183
+ return
184
+
185
+ old_index_dir = git_root / ".henchman" / "rag_index"
186
+ old_manifest = git_root / ".henchman" / "rag_manifest.json"
187
+
188
+ removed = []
189
+
190
+ if old_index_dir.exists():
191
+ try:
192
+ shutil.rmtree(old_index_dir)
193
+ removed.append(f"Index directory: {old_index_dir}")
194
+ except Exception as e:
195
+ ctx.console.print(f"[yellow]Error removing {old_index_dir}: {e}[/]")
196
+
197
+ if old_manifest.exists():
198
+ try:
199
+ old_manifest.unlink()
200
+ removed.append(f"Manifest file: {old_manifest}")
201
+ except Exception as e:
202
+ ctx.console.print(f"[yellow]Error removing {old_manifest}: {e}[/]")
203
+
204
+ if removed:
205
+ ctx.console.print("[green]Cleaned up old project-based RAG indices:[/]")
206
+ for item in removed:
207
+ ctx.console.print(f" • {item}")
208
+ else:
209
+ ctx.console.print("[dim]No old project-based RAG indices found[/]")
@@ -8,6 +8,7 @@ from __future__ import annotations
8
8
  from collections.abc import AsyncIterator
9
9
  from dataclasses import dataclass
10
10
  from pathlib import Path
11
+ from typing import TYPE_CHECKING
11
12
 
12
13
  from rich.console import Console
13
14
 
@@ -21,6 +22,9 @@ from henchman.core.session import Session, SessionManager, SessionMessage
21
22
  from henchman.providers.base import ModelProvider, ToolCall
22
23
  from henchman.tools.registry import ToolRegistry
23
24
 
25
+ if TYPE_CHECKING:
26
+ from henchman.config.schema import Settings
27
+
24
28
 
25
29
  @dataclass
26
30
  class ReplConfig:
@@ -60,7 +64,7 @@ class Repl:
60
64
  provider: ModelProvider,
61
65
  console: Console | None = None,
62
66
  config: ReplConfig | None = None,
63
- settings: object | None = None,
67
+ settings: Settings | None = None,
64
68
  ) -> None:
65
69
  """Initialize the REPL.
66
70
 
@@ -68,7 +72,7 @@ class Repl:
68
72
  provider: Model provider for LLM interactions.
69
73
  console: Rich console for output.
70
74
  config: REPL configuration.
71
- settings: Application settings (currently unused, reserved for future).
75
+ settings: Application settings for context limits, etc.
72
76
  """
73
77
  self.provider = provider
74
78
  self.console = console or Console()
@@ -80,12 +84,28 @@ class Repl:
80
84
  self.tool_registry = ToolRegistry()
81
85
  self._register_builtin_tools()
82
86
 
87
+ # Determine max_tokens from settings
88
+ # Apply compaction_threshold to get the actual limit
89
+ max_tokens = 0
90
+ model_name: str | None = None
91
+ if settings:
92
+ context = settings.context
93
+ if context.max_tokens > 0:
94
+ # Apply threshold: compact when we reach threshold% of max
95
+ max_tokens = int(context.max_tokens * context.compaction_threshold)
96
+
97
+ # Get model name from provider if available
98
+ if hasattr(provider, "default_model"):
99
+ model_name = provider.default_model
100
+
83
101
  # Initialize agent
84
102
  self.agent = Agent(
85
103
  provider=provider,
86
104
  tool_registry=self.tool_registry,
87
105
  system_prompt=self.config.system_prompt,
88
106
  base_tool_iterations=self.config.base_tool_iterations,
107
+ max_tokens=max_tokens,
108
+ model=model_name,
89
109
  )
90
110
 
91
111
  # Initialize command registry
@@ -106,6 +126,9 @@ class Repl:
106
126
  self.session_manager: SessionManager | None = None
107
127
  self.session: Session | None = None
108
128
 
129
+ # RAG system (set externally by app.py)
130
+ self.rag_system: object | None = None
131
+
109
132
  def _get_toolbar_status(self) -> list[tuple[str, str]]:
110
133
  """Get status bar content."""
111
134
  from henchman.utils.tokens import TokenCounter
@@ -5,8 +5,10 @@ This module provides configuration loading and context file discovery.
5
5
 
6
6
  from henchman.config.context import ContextLoader
7
7
  from henchman.config.schema import (
8
+ ContextSettings,
8
9
  McpServerConfig,
9
10
  ProviderSettings,
11
+ RagSettings,
10
12
  Settings,
11
13
  ToolSettings,
12
14
  UISettings,
@@ -16,8 +18,10 @@ from henchman.config.settings import ConfigError, deep_merge, load_settings
16
18
  __all__ = [
17
19
  "ConfigError",
18
20
  "ContextLoader",
21
+ "ContextSettings",
19
22
  "McpServerConfig",
20
23
  "ProviderSettings",
24
+ "RagSettings",
21
25
  "Settings",
22
26
  "ToolSettings",
23
27
  "UISettings",