henchman-ai 0.1.15__tar.gz → 0.1.16__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.15 → henchman_ai-0.1.16}/PKG-INFO +1 -1
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/pyproject.toml +1 -1
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/providers/anthropic.py +99 -71
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/version.py +1 -1
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/test_anthropic_ratelimit.py +42 -2
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/.github/copilot-instructions.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/.github/workflows/ci.yml +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/.github/workflows/docs.yml +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/.github/workflows/publish.yml +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/.gitignore +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/ALPHA_TEST_LOG.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/BETA_TESTING_ISSUES.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/BETA_TESTING_ISSUES2.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/BETA_TESTING_ISSUES3.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/CHANGELOG.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/CONTRIBUTING.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/LICENSE +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125050554038512/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125050555035824/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125050555125200/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125051893219152/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125080879298512/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125080879878832/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125080880913088/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125081401798976/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125246043105824/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125246043924496/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125246044001472/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/125247627445840/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/126367803948160/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/126368206535376/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/126368218825504/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/126368326698240/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/129118288064016/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/129118289735760/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/129118290807072/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/129118485247328/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/131782863223120/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/131782952758032/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/131782953186608/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/131783467925184/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/131953655609296/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/131953656855104/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/131954146008512/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/131954155550192/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/133226809006208/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/133226810375248/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/133226812410672/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/133227143444000/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/133999527639808/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/133999929687216/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/133999955332368/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134000027622176/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134508512171968/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134508512231200/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134508512485616/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134508855764000/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134604944477792/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134604945877536/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134604946059776/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134605456585744/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134618534097648/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134618535070656/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134619942883056/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134620110571280/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134745693453872/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134745694538112/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134746088611312/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/134746194079344/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/138555538485184/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/138555538874752/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/138555539451408/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/138556062045760/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/139088593563008/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/139088594086144/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/139088594201216/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/139088659820192/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/139391159286624/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/139391160298352/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/139391160361968/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/139391778658240/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/140323476876816/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/140323493157376/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/140323629475472/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/140324020609984/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/140365102460192/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/140365132965952/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/140365156415680/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/MagicMock/mock.rag.cache_dir/140365231305696/b0c5ce5844ad8acc/.rag.lock +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/PROJECT_PLAN.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/README.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/README_enhanced.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/RELEASE_CHECKLIST.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/TASK_COMPLETION_SUMMARY.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/debug_compaction.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/docs/api.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/docs/configuration.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/docs/extensions.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/docs/getting-started.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/docs/index.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/docs/mcp.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/docs/providers.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/docs/tools.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/evals/README.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/evals/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/evals/conftest.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/evals/helpers.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/evals/test_answer_vs_action.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/evals/test_coding_tasks.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/evals/test_edit_precision.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/evals/test_skills_memory.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/evals/test_tool_selection.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/fix_repl.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/fix_repl_simple.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/mkdocs.yml +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/replace_method.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/reproduce_400_error.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/run_interactive_tests.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/scripts/build_docs.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/scripts/ci.sh +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/scripts/run_evals.sh +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/__main__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/app.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/builtins.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/chat.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/extensions.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/mcp.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/model.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/plan.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/rag.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/skill.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/commands/unlimited.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/console.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/input.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/json_output.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/prompts.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/repl.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/repl.py.backup +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/cli/repl.py.backup2 +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/config/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/config/context.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/config/schema.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/config/settings.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/core/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/core/agent.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/core/agent.py.backup +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/core/events.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/core/session.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/core/turn.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/extensions/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/extensions/base.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/extensions/manager.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/mcp/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/mcp/client.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/mcp/config.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/mcp/manager.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/mcp/tool.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/providers/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/providers/base.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/providers/deepseek.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/providers/ollama.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/providers/openai_compat.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/providers/openai_compat.py.backup +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/providers/registry.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/rag/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/rag/chunker.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/rag/concurrency.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/rag/embedder.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/rag/indexer.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/rag/repo_id.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/rag/store.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/rag/system.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/skills/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/skills/executor.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/skills/learner.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/skills/models.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/skills/store.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/base.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/ask_user.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/file_edit.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/file_read.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/file_write.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/glob_tool.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/grep.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/ls.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/rag_search.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/shell.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/web_fetch.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/builtins/web_search.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/tools/registry.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/utils/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/utils/compaction.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/utils/ratelimit.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/utils/retry.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/utils/tokens.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/src/henchman/utils/validation.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/test_compaction.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/test_compaction_fix.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/test_fixes.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/test_output.txt +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/test_run.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572362825280/b0c5ce5844ad8acc/manifest.json +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572765096208/b0c5ce5844ad8acc/manifest.json +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572822401392/b0c5ce5844ad8acc/manifest.json +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/125572896176320/b0c5ce5844ad8acc/manifest.json +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520285986352/b0c5ce5844ad8acc/manifest.json +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520286228656/b0c5ce5844ad8acc/manifest.json +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520287933552/b0c5ce5844ad8acc/manifest.json +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/data_level0.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/header.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/length.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/88b10860-7f3a-42c9-a3aa-20e09850b445/link_lists.bin +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/chroma/chroma.sqlite3 +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/MagicMock/mock.rag.cache_dir/135520588106160/b0c5ce5844ad8acc/manifest.json +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/commands/test_model.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/commands/test_model_integration.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/commands/test_plan.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/commands/test_plan_branch.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/commands/test_session_resume_id.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/commands/test_skill.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/commands/test_skill_extended.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/commands/test_unlimited.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_app.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_app_extended.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_builtins.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_chat_command.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_cli_smoke.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_commands.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_commands_repro.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_console.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_console_confirm.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_enhanced_tool_display.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_input.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_input_bindings.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_interrupt.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_json_output.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_keyboard_fixes.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_keyboard_integration.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_keyboard_interrupt.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_keyboard_verification.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_loop_protection.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_mcp_command.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_repl.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_repl_attribute_fix.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_repl_startup_message.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/cli/test_repl_toolbar.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/config/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/config/test_context.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/config/test_schema.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/config/test_settings.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/conftest.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/core/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/core/test_automatic_compaction.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/core/test_events.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/core/test_session.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/core/test_session_manager.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/core/test_streaming_tool_calls.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/core/test_turn_state.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/e2e/test_context_safety.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/e2e/test_plan_mode_workflow.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/e2e/test_tool_fix.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/empty_message_validation/test_empty_messages.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/extensions/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/extensions/test_base.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/extensions/test_command.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/extensions/test_manager.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/integration/test_anthropic_functional.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/integration/test_context_limits.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/integration/test_tool_integration.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/mcp/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/mcp/test_client.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/mcp/test_config.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/mcp/test_manager.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/mcp/test_tool.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/test_413_error_handling.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/test_anthropic.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/test_anthropic_validation.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/test_base.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/test_deepseek.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/test_ollama.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/test_openai_compat.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/providers/test_registry.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_chunker.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_concurrency.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_concurrency_smoke.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_embedder.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_indexer.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_rag_command.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_rag_concurrency_integration.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_rag_search_tool.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_repo_id.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_store.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/rag/test_system.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/skills/test_executor.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/skills/test_learner.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/skills/test_markdown_skills.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/skills/test_models.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/skills/test_store.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/skills/test_store_extended.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/smoke/test_escape_key_behavior.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/smoke/test_large_file_handling.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/test_coverage_suite.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/test_main.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/test_version.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_ask_user_tool.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_base.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_directory_tools.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_file_tools.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_grep_tool.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_plan_mode_enforcement.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_registry.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_shell_advanced.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_shell_tool.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/tools/test_web_fetch_tool.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/INTERACTIVE_SESSION_TESTS.md +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/__init__.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/conftest.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_agent.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_compaction_llm.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_events.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_llm.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_mcp.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_plan_mode.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_repl_e2e.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_repl_integration.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_session.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_skills.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_slash_commands.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_tokens_llm.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_tool_calls.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/ui_integration/test_tool_integration.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_compaction.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_compaction_edge_cases.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_compaction_validation.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_multi_turn_tool_calls.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_protected_zone.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_retry.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_summarization.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_tiktoken_integration.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_token_counter_extended.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_tool_sequence_compaction.py +0 -0
- {henchman_ai-0.1.15 → henchman_ai-0.1.16}/tests/utils/test_validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: henchman-ai
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.16
|
|
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
|
|
@@ -4,12 +4,13 @@ This provider uses the Anthropic SDK to communicate with Claude models.
|
|
|
4
4
|
Unlike OpenAI-compatible APIs, Anthropic has its own message format.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import asyncio
|
|
7
8
|
import json
|
|
8
9
|
import os
|
|
9
10
|
from collections.abc import AsyncIterator
|
|
10
11
|
from typing import Any
|
|
11
12
|
|
|
12
|
-
from anthropic import AsyncAnthropic
|
|
13
|
+
from anthropic import AsyncAnthropic, RateLimitError
|
|
13
14
|
|
|
14
15
|
from henchman.providers.base import (
|
|
15
16
|
FinishReason,
|
|
@@ -54,6 +55,7 @@ class AnthropicProvider(ModelProvider):
|
|
|
54
55
|
model: str = "claude-sonnet-4-20250514",
|
|
55
56
|
max_tokens: int = 8192,
|
|
56
57
|
tokens_per_minute: int = 30000,
|
|
58
|
+
max_retries: int = 3,
|
|
57
59
|
) -> None:
|
|
58
60
|
"""Initialize the Anthropic provider.
|
|
59
61
|
|
|
@@ -62,10 +64,12 @@ class AnthropicProvider(ModelProvider):
|
|
|
62
64
|
model: Default model to use.
|
|
63
65
|
max_tokens: Maximum tokens in response.
|
|
64
66
|
tokens_per_minute: Maximum tokens per minute (rate limit).
|
|
67
|
+
max_retries: Maximum number of retries for rate limits.
|
|
65
68
|
"""
|
|
66
69
|
self.api_key = api_key or os.getenv("ANTHROPIC_API_KEY", "")
|
|
67
70
|
self.default_model = model
|
|
68
71
|
self.max_tokens = max_tokens
|
|
72
|
+
self.max_retries = max_retries
|
|
69
73
|
self._client = AsyncAnthropic(api_key=self.api_key or "placeholder")
|
|
70
74
|
self._rate_limiter = AsyncRateLimiter(tokens_per_minute)
|
|
71
75
|
|
|
@@ -194,10 +198,6 @@ class AnthropicProvider(ModelProvider):
|
|
|
194
198
|
if not (message.content or '').strip():
|
|
195
199
|
raise ValueError(f"Message with role '{message.role}' cannot have empty content")
|
|
196
200
|
|
|
197
|
-
# Rate limiting: wait for capacity based on input tokens
|
|
198
|
-
input_tokens = TokenCounter.count_messages(messages, model=self.default_model)
|
|
199
|
-
await self._rate_limiter.wait_for_capacity(input_tokens)
|
|
200
|
-
|
|
201
201
|
system_prompt, formatted_messages = self._format_messages(messages)
|
|
202
202
|
|
|
203
203
|
params: dict[str, Any] = {
|
|
@@ -213,71 +213,99 @@ class AnthropicProvider(ModelProvider):
|
|
|
213
213
|
if tools:
|
|
214
214
|
params["tools"] = [self._format_tool(t) for t in tools]
|
|
215
215
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
216
|
+
input_tokens = TokenCounter.count_messages(messages, model=self.default_model)
|
|
217
|
+
retries = 0
|
|
218
|
+
while True:
|
|
219
|
+
try:
|
|
220
|
+
# Rate limiting: wait for capacity based on input tokens
|
|
221
|
+
await self._rate_limiter.wait_for_capacity(input_tokens)
|
|
222
|
+
|
|
223
|
+
total_output_tokens = 0
|
|
224
|
+
async with self._client.messages.stream(**params) as stream:
|
|
225
|
+
pending_tool_calls: dict[str, dict[str, Any]] = {}
|
|
226
|
+
current_tool_id: str | None = None
|
|
227
|
+
|
|
228
|
+
async for event in stream:
|
|
229
|
+
content: str | None = None
|
|
230
|
+
thinking: str | None = None
|
|
231
|
+
tool_calls: list[ToolCall] | None = None
|
|
232
|
+
finish_reason: FinishReason | None = None
|
|
233
|
+
|
|
234
|
+
if event.type == "content_block_start":
|
|
235
|
+
block = event.content_block
|
|
236
|
+
if block.type == "tool_use":
|
|
237
|
+
current_tool_id = block.id
|
|
238
|
+
pending_tool_calls[block.id] = {
|
|
239
|
+
"id": block.id,
|
|
240
|
+
"name": block.name,
|
|
241
|
+
"arguments": "",
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
elif event.type == "content_block_delta":
|
|
245
|
+
delta = event.delta
|
|
246
|
+
if delta.type == "text_delta":
|
|
247
|
+
content = delta.text
|
|
248
|
+
total_output_tokens += TokenCounter.count_text(content, model=self.default_model)
|
|
249
|
+
elif delta.type == "thinking_delta":
|
|
250
|
+
thinking = delta.thinking
|
|
251
|
+
total_output_tokens += TokenCounter.count_text(thinking, model=self.default_model)
|
|
252
|
+
elif delta.type == "input_json_delta" and current_tool_id:
|
|
253
|
+
pending_tool_calls[current_tool_id]["arguments"] += delta.partial_json
|
|
254
|
+
# Note: we don't count JSON tokens precisely here as they come in,
|
|
255
|
+
# but we could count the delta text.
|
|
256
|
+
total_output_tokens += TokenCounter.count_text(delta.partial_json, model=self.default_model)
|
|
257
|
+
|
|
258
|
+
elif event.type == "content_block_stop":
|
|
259
|
+
current_tool_id = None
|
|
260
|
+
|
|
261
|
+
elif event.type == "message_delta":
|
|
262
|
+
finish_reason = self._parse_finish_reason(event.delta.stop_reason)
|
|
263
|
+
|
|
264
|
+
# Emit completed tool calls
|
|
265
|
+
if finish_reason == FinishReason.TOOL_CALLS and pending_tool_calls:
|
|
266
|
+
tool_calls = []
|
|
267
|
+
for tc_data in pending_tool_calls.values():
|
|
268
|
+
try:
|
|
269
|
+
arguments = json.loads(tc_data["arguments"]) if tc_data["arguments"] else {}
|
|
270
|
+
except json.JSONDecodeError:
|
|
271
|
+
arguments = {}
|
|
272
|
+
tool_calls.append(
|
|
273
|
+
ToolCall(
|
|
274
|
+
id=tc_data["id"],
|
|
275
|
+
name=tc_data["name"],
|
|
276
|
+
arguments=arguments,
|
|
277
|
+
)
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Only yield if we have meaningful content
|
|
281
|
+
if content is not None or thinking is not None or tool_calls or finish_reason:
|
|
282
|
+
yield StreamChunk(
|
|
283
|
+
content=content,
|
|
284
|
+
tool_calls=tool_calls,
|
|
285
|
+
finish_reason=finish_reason,
|
|
286
|
+
thinking=thinking,
|
|
271
287
|
)
|
|
272
288
|
|
|
273
|
-
#
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
289
|
+
# Record final usage
|
|
290
|
+
await self._rate_limiter.add_usage(input_tokens + total_output_tokens)
|
|
291
|
+
break # Success, exit retry loop
|
|
292
|
+
|
|
293
|
+
except RateLimitError as e:
|
|
294
|
+
retries += 1
|
|
295
|
+
if retries > self.max_retries:
|
|
296
|
+
raise
|
|
297
|
+
|
|
298
|
+
# Hit rate limit, wait and retry
|
|
299
|
+
# Extract wait time from headers if available, otherwise use exponential backoff
|
|
300
|
+
wait_time = 5.0 * (2 ** (retries - 1)) # Default backoff
|
|
301
|
+
|
|
302
|
+
# Log to console if possible
|
|
303
|
+
from rich.console import Console
|
|
304
|
+
Console().print(f"[yellow]Rate limit reached (429). Retrying in {wait_time:.1f}s... (Attempt {retries}/{self.max_retries})[/yellow]")
|
|
305
|
+
|
|
306
|
+
await asyncio.sleep(wait_time)
|
|
307
|
+
# After sleeping, we loop back and try again.
|
|
308
|
+
# The rate limiter's wait_for_capacity will be called again if we move it inside the loop,
|
|
309
|
+
# but we already called it once. However, Anthropic says we are OVER the limit,
|
|
310
|
+
# so we should probably record that usage or just wait.
|
|
311
|
+
# Let's move the wait_for_capacity INSIDE the retry loop.
|
|
@@ -5,8 +5,8 @@ import time
|
|
|
5
5
|
import pytest
|
|
6
6
|
from unittest.mock import MagicMock, patch, AsyncMock
|
|
7
7
|
|
|
8
|
-
from henchman.providers.anthropic import AnthropicProvider
|
|
9
|
-
from henchman.providers.base import Message
|
|
8
|
+
from henchman.providers.anthropic import AnthropicProvider, RateLimitError
|
|
9
|
+
from henchman.providers.base import Message, StreamChunk, FinishReason
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@pytest.mark.asyncio
|
|
@@ -74,3 +74,43 @@ async def test_anthropic_rate_limiting_delays():
|
|
|
74
74
|
pass
|
|
75
75
|
|
|
76
76
|
assert mock_sleep.called
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@pytest.mark.asyncio
|
|
80
|
+
async def test_anthropic_rate_limit_retry():
|
|
81
|
+
"""Test that AnthropicProvider retries on RateLimitError."""
|
|
82
|
+
limit = 100
|
|
83
|
+
messages = [Message(role="user", content="Hello")]
|
|
84
|
+
|
|
85
|
+
with patch('henchman.providers.anthropic.AsyncAnthropic') as mock_anthropic:
|
|
86
|
+
mock_client = MagicMock()
|
|
87
|
+
mock_anthropic.return_value = mock_client
|
|
88
|
+
|
|
89
|
+
provider = AnthropicProvider(api_key="test", tokens_per_minute=limit, max_retries=2)
|
|
90
|
+
|
|
91
|
+
# Setup mock stream for successful call
|
|
92
|
+
mock_stream = AsyncMock()
|
|
93
|
+
|
|
94
|
+
async def mock_aiter():
|
|
95
|
+
yield MagicMock(type="content_block_delta", delta=MagicMock(type="text_delta", text="Success"))
|
|
96
|
+
yield MagicMock(type="message_delta", delta=MagicMock(stop_reason="end_turn"))
|
|
97
|
+
|
|
98
|
+
mock_stream.__aenter__.return_value = mock_aiter()
|
|
99
|
+
|
|
100
|
+
# First call fails, second succeeds
|
|
101
|
+
# Anthropic SDK RateLimitError needs a message and response
|
|
102
|
+
error_response = MagicMock()
|
|
103
|
+
error_response.status_code = 429
|
|
104
|
+
rate_limit_error = RateLimitError(message="Rate limit hit", response=error_response, body={})
|
|
105
|
+
|
|
106
|
+
mock_client.messages.stream.side_effect = [rate_limit_error, mock_stream]
|
|
107
|
+
|
|
108
|
+
with patch('asyncio.sleep', new_callable=AsyncMock) as mock_sleep:
|
|
109
|
+
chunks = []
|
|
110
|
+
async for chunk in provider.chat_completion_stream(messages):
|
|
111
|
+
chunks.append(chunk)
|
|
112
|
+
|
|
113
|
+
assert mock_client.messages.stream.call_count == 2
|
|
114
|
+
assert mock_sleep.call_count == 1
|
|
115
|
+
assert any(c.content == "Success" for c in chunks)
|
|
116
|
+
assert any(c.finish_reason == FinishReason.STOP for c in chunks)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|