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.
- henchman_ai-0.1.10/.henchman/rag_index/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- henchman_ai-0.1.10/.henchman/rag_index/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- henchman_ai-0.1.10/.henchman/rag_index/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- henchman_ai-0.1.10/.henchman/rag_index/chroma.sqlite3 +0 -0
- henchman_ai-0.1.10/.henchman/rag_manifest.json +1 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/CHANGELOG.md +25 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/PKG-INFO +3 -1
- henchman_ai-0.1.10/RAG_HOME_DIRECTORY_MIGRATION.md +138 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/pyproject.toml +3 -1
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/app.py +17 -2
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/builtins.py +3 -0
- henchman_ai-0.1.10/src/henchman/cli/commands/rag.py +209 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/repl.py +25 -2
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/config/__init__.py +4 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/config/schema.py +60 -21
- henchman_ai-0.1.10/src/henchman/rag/__init__.py +38 -0
- henchman_ai-0.1.10/src/henchman/rag/chunker.py +206 -0
- henchman_ai-0.1.10/src/henchman/rag/embedder.py +148 -0
- henchman_ai-0.1.10/src/henchman/rag/indexer.py +373 -0
- henchman_ai-0.1.10/src/henchman/rag/repo_id.py +199 -0
- henchman_ai-0.1.10/src/henchman/rag/store.py +224 -0
- henchman_ai-0.1.10/src/henchman/rag/system.py +225 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/__init__.py +2 -0
- henchman_ai-0.1.10/src/henchman/tools/builtins/rag_search.py +146 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/version.py +1 -1
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/manifest.json +1 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/manifest.json +1 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/manifest.json +1 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/manifest.json +1 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/manifest.json +1 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/manifest.json +1 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/manifest.json +1 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- henchman_ai-0.1.10/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/manifest.json +1 -0
- henchman_ai-0.1.10/tests/__init__.py +0 -0
- henchman_ai-0.1.10/tests/cli/__init__.py +0 -0
- henchman_ai-0.1.10/tests/config/__init__.py +0 -0
- henchman_ai-0.1.10/tests/core/__init__.py +0 -0
- henchman_ai-0.1.10/tests/mcp/__init__.py +0 -0
- henchman_ai-0.1.10/tests/providers/__init__.py +0 -0
- henchman_ai-0.1.10/tests/rag/__init__.py +1 -0
- henchman_ai-0.1.10/tests/rag/test_chunker.py +166 -0
- henchman_ai-0.1.10/tests/rag/test_embedder.py +81 -0
- henchman_ai-0.1.10/tests/rag/test_indexer.py +240 -0
- henchman_ai-0.1.10/tests/rag/test_rag_command.py +137 -0
- henchman_ai-0.1.10/tests/rag/test_rag_search_tool.py +136 -0
- henchman_ai-0.1.10/tests/rag/test_store.py +234 -0
- henchman_ai-0.1.10/tests/rag/test_system.py +286 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/test_version.py +1 -1
- henchman_ai-0.1.10/tests/tools/__init__.py +0 -0
- henchman_ai-0.1.9/TOOL_CHAINING_DESIGN.md +0 -425
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/.github/copilot-instructions.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/.github/workflows/ci.yml +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/.github/workflows/publish.yml +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/.gitignore +0 -0
- /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
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/LICENSE +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/PROJECT_PLAN.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/README.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/TASK_COMPLETION_SUMMARY.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/debug_compaction.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/api.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/configuration.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/extensions.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/getting-started.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/index.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/mcp.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/providers.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/docs/tools.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/fix_repl.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/fix_repl_simple.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/mkdocs.yml +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/replace_method.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/reproduce_400_error.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/run_interactive_tests.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/scripts/ci.sh +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/__main__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/chat.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/extensions.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/mcp.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/plan.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/skill.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/commands/unlimited.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/console.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/input.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/json_output.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/prompts.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/repl.py.backup +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/cli/repl.py.backup2 +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/config/context.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/config/settings.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/agent.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/agent.py.backup +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/events.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/session.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/core/turn.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/extensions/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/extensions/base.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/extensions/manager.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/client.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/config.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/manager.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/mcp/tool.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/anthropic.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/base.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/deepseek.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/ollama.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/openai_compat.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/openai_compat.py.backup +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/providers/registry.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/executor.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/learner.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/models.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/skills/store.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/base.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/ask_user.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/file_edit.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/file_read.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/file_write.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/glob_tool.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/grep.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/ls.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/shell.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/builtins/web_fetch.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/tools/registry.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/compaction.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/retry.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/tokens.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/src/henchman/utils/validation.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_compaction.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_compaction_fix.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_fixes.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_output.txt +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/test_run.py +0 -0
- /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
- /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
- /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
- /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
- /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
- /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
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/commands/test_plan.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/commands/test_skill.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/commands/test_skill_extended.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/commands/test_unlimited.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_app.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_app_extended.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_builtins.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_chat_command.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_cli_smoke.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_commands.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_commands_repro.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_console.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_enhanced_tool_display.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_input.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_input_bindings.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_json_output.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_keyboard_fixes.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_keyboard_integration.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_keyboard_interrupt.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_keyboard_verification.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_loop_protection.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_mcp_command.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_repl.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_repl_attribute_fix.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_repl_startup_message.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/cli/test_repl_toolbar.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/config/test_context.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/config/test_schema.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/config/test_settings.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/conftest.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_automatic_compaction.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_events.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_session.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_session_manager.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_streaming_tool_calls.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/core/test_turn_state.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/e2e/test_context_safety.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/e2e/test_tool_fix.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/empty_message_validation/test_empty_messages.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/extensions/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/extensions/test_base.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/extensions/test_command.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/extensions/test_manager.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/integration/test_context_limits.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/integration/test_tool_integration.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/mcp/test_client.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/mcp/test_config.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/mcp/test_manager.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/mcp/test_tool.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_413_error_handling.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_anthropic.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_base.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_deepseek.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_ollama.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_openai_compat.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/providers/test_registry.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_executor.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_learner.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_markdown_skills.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_models.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_store.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/skills/test_store_extended.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/smoke/test_escape_key_behavior.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/smoke/test_large_file_handling.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/test_coverage_suite.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/test_main.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_ask_user_tool.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_base.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_directory_tools.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_file_tools.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_grep_tool.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_plan_mode_enforcement.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_registry.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_shell_tool.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/tools/test_web_fetch_tool.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/INTERACTIVE_SESSION_TESTS.md +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/__init__.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/conftest.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_agent.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_compaction_llm.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_events.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_llm.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_mcp.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_plan_mode.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_repl_e2e.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_repl_integration.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_session.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_skills.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_slash_commands.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_tokens_llm.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_tool_calls.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/ui_integration/test_tool_integration.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_compaction.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_compaction_edge_cases.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_compaction_validation.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_multi_turn_tool_calls.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_protected_zone.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_retry.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_summarization.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_tiktoken_integration.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_token_counter_extended.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_tool_sequence_compaction.py +0 -0
- {henchman_ai-0.1.9 → henchman_ai-0.1.10}/tests/utils/test_validation.py +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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.
|
|
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.
|
|
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:
|
|
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
|
|
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",
|