agent-cli 0.76.4__tar.gz → 0.76.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. {agent_cli-0.76.4 → agent_cli-0.76.5}/PKG-INFO +15 -15
  2. {agent_cli-0.76.4 → agent_cli-0.76.5}/README.md +14 -14
  3. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/deps.py +191 -85
  4. agent_cli-0.76.5/agent_cli/install/extras.py +104 -0
  5. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/conftest.py +4 -4
  6. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/install/test_extras.py +4 -3
  7. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_requires_extras.py +39 -42
  8. agent_cli-0.76.4/agent_cli/install/extras.py +0 -209
  9. {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude/skills/agent-cli-dev/SKILL.md +0 -0
  10. {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude/skills/agent-cli-dev/examples.md +0 -0
  11. {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/README.md +0 -0
  12. {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/marketplace.json +0 -0
  13. {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/plugin.json +0 -0
  14. {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/skills/agent-cli-dev/SKILL.md +0 -0
  15. {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/skills/agent-cli-dev/examples.md +0 -0
  16. {agent_cli-0.76.4 → agent_cli-0.76.5}/.cursorrules +0 -0
  17. {agent_cli-0.76.4 → agent_cli-0.76.5}/.dockerignore +0 -0
  18. {agent_cli-0.76.4 → agent_cli-0.76.5}/.env.example +0 -0
  19. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/logo.svg +0 -0
  20. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/release-drafter.yml +0 -0
  21. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/renovate.json +0 -0
  22. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/scripts/check_extras_sync.py +0 -0
  23. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/scripts/sync_requirements.py +0 -0
  24. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/automerge.yml +0 -0
  25. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/docker.yml +0 -0
  26. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/docs.yml +0 -0
  27. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/markdown-code-runner.yml +0 -0
  28. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/pytest.yml +0 -0
  29. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/release-drafter.yml +0 -0
  30. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/release.yml +0 -0
  31. {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/toc.yaml +0 -0
  32. {agent_cli-0.76.4 → agent_cli-0.76.5}/.gitignore +0 -0
  33. {agent_cli-0.76.4 → agent_cli-0.76.5}/.jscpd.json +0 -0
  34. {agent_cli-0.76.4 → agent_cli-0.76.5}/.pre-commit-config.yaml +0 -0
  35. {agent_cli-0.76.4 → agent_cli-0.76.5}/.prompts/docs-review.md +0 -0
  36. {agent_cli-0.76.4 → agent_cli-0.76.5}/.prompts/pr-review.md +0 -0
  37. {agent_cli-0.76.4 → agent_cli-0.76.5}/CLAUDE.md +0 -0
  38. {agent_cli-0.76.4 → agent_cli-0.76.5}/LICENSE +0 -0
  39. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/__init__.py +0 -0
  40. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/__main__.py +0 -0
  41. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_extras.json +0 -0
  42. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/.gitkeep +0 -0
  43. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/audio.txt +0 -0
  44. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/faster-whisper.txt +0 -0
  45. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/kokoro.txt +0 -0
  46. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/llm.txt +0 -0
  47. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/memory.txt +0 -0
  48. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/mlx-whisper.txt +0 -0
  49. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/piper.txt +0 -0
  50. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/rag.txt +0 -0
  51. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/server.txt +0 -0
  52. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/speed.txt +0 -0
  53. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/vad.txt +0 -0
  54. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/whisper-transformers.txt +0 -0
  55. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/wyoming.txt +0 -0
  56. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_tools.py +0 -0
  57. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/__init__.py +0 -0
  58. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/_voice_agent_common.py +0 -0
  59. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/assistant.py +0 -0
  60. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/autocorrect.py +0 -0
  61. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/chat.py +0 -0
  62. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/memory/__init__.py +0 -0
  63. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/memory/add.py +0 -0
  64. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/memory/proxy.py +0 -0
  65. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/rag_proxy.py +0 -0
  66. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/speak.py +0 -0
  67. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/transcribe.py +0 -0
  68. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/transcribe_daemon.py +0 -0
  69. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/voice_edit.py +0 -0
  70. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/api.py +0 -0
  71. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/cli.py +0 -0
  72. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/config.py +0 -0
  73. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/config_cmd.py +0 -0
  74. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/constants.py +0 -0
  75. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/__init__.py +0 -0
  76. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/audio.py +0 -0
  77. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/audio_format.py +0 -0
  78. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/chroma.py +0 -0
  79. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/openai_proxy.py +0 -0
  80. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/process.py +0 -0
  81. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/reranker.py +0 -0
  82. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/sse.py +0 -0
  83. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/transcription_logger.py +0 -0
  84. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/utils.py +0 -0
  85. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/vad.py +0 -0
  86. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/watch.py +0 -0
  87. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/__init__.py +0 -0
  88. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/cli.py +0 -0
  89. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/__init__.py +0 -0
  90. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/aider.py +0 -0
  91. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/base.py +0 -0
  92. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/claude.py +0 -0
  93. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/codex.py +0 -0
  94. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
  95. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/copilot.py +0 -0
  96. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
  97. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/gemini.py +0 -0
  98. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/opencode.py +0 -0
  99. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/registry.py +0 -0
  100. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/__init__.py +0 -0
  101. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/base.py +0 -0
  102. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/cursor.py +0 -0
  103. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/emacs.py +0 -0
  104. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/jetbrains.py +0 -0
  105. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/nano.py +0 -0
  106. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/neovim.py +0 -0
  107. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/registry.py +0 -0
  108. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/sublime.py +0 -0
  109. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/vim.py +0 -0
  110. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/vscode.py +0 -0
  111. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/zed.py +0 -0
  112. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/project.py +0 -0
  113. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/registry.py +0 -0
  114. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/skill/SKILL.md +0 -0
  115. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/skill/examples.md +0 -0
  116. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/__init__.py +0 -0
  117. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/apple_terminal.py +0 -0
  118. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/base.py +0 -0
  119. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/gnome.py +0 -0
  120. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/iterm2.py +0 -0
  121. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/kitty.py +0 -0
  122. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/registry.py +0 -0
  123. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/tmux.py +0 -0
  124. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/warp.py +0 -0
  125. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/zellij.py +0 -0
  126. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/worktree.py +0 -0
  127. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/docs_gen.py +0 -0
  128. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/example-config.toml +0 -0
  129. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/install/__init__.py +0 -0
  130. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/install/common.py +0 -0
  131. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/install/hotkeys.py +0 -0
  132. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/install/services.py +0 -0
  133. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/__init__.py +0 -0
  134. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_files.py +0 -0
  135. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_filters.py +0 -0
  136. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_git.py +0 -0
  137. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_indexer.py +0 -0
  138. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_ingest.py +0 -0
  139. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_persistence.py +0 -0
  140. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_prompt.py +0 -0
  141. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_retrieval.py +0 -0
  142. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_store.py +0 -0
  143. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_streaming.py +0 -0
  144. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_tasks.py +0 -0
  145. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/api.py +0 -0
  146. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/client.py +0 -0
  147. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/engine.py +0 -0
  148. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/entities.py +0 -0
  149. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/models.py +0 -0
  150. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/opts.py +0 -0
  151. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/py.typed +0 -0
  152. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/__init__.py +0 -0
  153. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_indexer.py +0 -0
  154. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_indexing.py +0 -0
  155. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_prompt.py +0 -0
  156. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_retriever.py +0 -0
  157. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_store.py +0 -0
  158. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_utils.py +0 -0
  159. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/api.py +0 -0
  160. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/client.py +0 -0
  161. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/engine.py +0 -0
  162. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/models.py +0 -0
  163. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/.runtime/.gitkeep +0 -0
  164. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/__init__.py +0 -0
  165. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/check_plugin_skill_sync.py +0 -0
  166. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
  167. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
  168. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
  169. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
  170. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
  171. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
  172. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
  173. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
  174. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
  175. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
  176. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
  177. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
  178. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
  179. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
  180. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-openwakeword.sh +0 -0
  181. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-piper-windows.ps1 +0 -0
  182. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-piper.sh +0 -0
  183. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper-linux.sh +0 -0
  184. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper-macos.sh +0 -0
  185. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper-windows.ps1 +0 -0
  186. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper.sh +0 -0
  187. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run_faster_whisper_server.py +0 -0
  188. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
  189. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-linux.sh +0 -0
  190. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
  191. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-macos.sh +0 -0
  192. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-windows.ps1 +0 -0
  193. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
  194. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/start-all-services.sh +0 -0
  195. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/sync_extras.py +0 -0
  196. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/__init__.py +0 -0
  197. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/cli.py +0 -0
  198. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/common.py +0 -0
  199. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/model_manager.py +0 -0
  200. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/model_registry.py +0 -0
  201. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/proxy/__init__.py +0 -0
  202. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/proxy/api.py +0 -0
  203. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/streaming.py +0 -0
  204. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/__init__.py +0 -0
  205. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/api.py +0 -0
  206. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/backends/__init__.py +0 -0
  207. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/backends/base.py +0 -0
  208. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/backends/kokoro.py +0 -0
  209. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/backends/piper.py +0 -0
  210. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/model_manager.py +0 -0
  211. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/model_registry.py +0 -0
  212. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/wyoming_handler.py +0 -0
  213. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/__init__.py +0 -0
  214. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/api.py +0 -0
  215. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/__init__.py +0 -0
  216. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/base.py +0 -0
  217. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
  218. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/mlx.py +0 -0
  219. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/transformers.py +0 -0
  220. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/languages.py +0 -0
  221. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/model_manager.py +0 -0
  222. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/model_registry.py +0 -0
  223. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/wyoming_handler.py +0 -0
  224. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/__init__.py +0 -0
  225. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/_wyoming_utils.py +0 -0
  226. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/asr.py +0 -0
  227. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/llm.py +0 -0
  228. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/tts.py +0 -0
  229. {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/wake_word.py +0 -0
  230. {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/docker-compose.yml +0 -0
  231. {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/memory-proxy.Dockerfile +0 -0
  232. {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/rag-proxy.Dockerfile +0 -0
  233. {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/transcribe-proxy.Dockerfile +0 -0
  234. {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/tts.Dockerfile +0 -0
  235. {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/whisper.Dockerfile +0 -0
  236. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/CNAME +0 -0
  237. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/architecture/index.md +0 -0
  238. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/architecture/memory.md +0 -0
  239. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/architecture/rag.md +0 -0
  240. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/assistant.md +0 -0
  241. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/autocorrect.md +0 -0
  242. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/chat.md +0 -0
  243. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/config.md +0 -0
  244. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/dev.md +0 -0
  245. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/index.md +0 -0
  246. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/install-extras.md +0 -0
  247. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/install-hotkeys.md +0 -0
  248. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/install-services.md +0 -0
  249. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/memory.md +0 -0
  250. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/rag-proxy.md +0 -0
  251. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/server/index.md +0 -0
  252. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/server/transcribe-proxy.md +0 -0
  253. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/server/tts.md +0 -0
  254. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/server/whisper.md +0 -0
  255. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/speak.md +0 -0
  256. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/start-services.md +0 -0
  257. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/transcribe-daemon.md +0 -0
  258. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/transcribe.md +0 -0
  259. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/voice-edit.md +0 -0
  260. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/configuration.md +0 -0
  261. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/getting-started.md +0 -0
  262. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/iOS_Shortcut_Guide.md +0 -0
  263. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/index.md +0 -0
  264. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/docker.md +0 -0
  265. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/index.md +0 -0
  266. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/linux.md +0 -0
  267. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/macos.md +0 -0
  268. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/nixos.md +0 -0
  269. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/windows.md +0 -0
  270. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/logo-clean.svg +0 -0
  271. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
  272. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/run_markdown_code_runner.py +0 -0
  273. {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/system-integration.md +0 -0
  274. {agent_cli-0.76.4 → agent_cli-0.76.5}/example.agent-cli-config.toml +0 -0
  275. {agent_cli-0.76.4 → agent_cli-0.76.5}/justfile +0 -0
  276. {agent_cli-0.76.4 → agent_cli-0.76.5}/pyproject.toml +0 -0
  277. {agent_cli-0.76.4 → agent_cli-0.76.5}/shell.nix +0 -0
  278. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/__init__.py +0 -0
  279. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/__init__.py +0 -0
  280. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_fix_my_text.py +0 -0
  281. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_interactive.py +0 -0
  282. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_interactive_extra.py +0 -0
  283. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_memory_add.py +0 -0
  284. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_speak.py +0 -0
  285. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_speak_e2e.py +0 -0
  286. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe.py +0 -0
  287. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe_agent.py +0 -0
  288. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe_daemon.py +0 -0
  289. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe_e2e.py +0 -0
  290. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe_recovery.py +0 -0
  291. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_tts_common.py +0 -0
  292. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_tts_common_extra.py +0 -0
  293. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_voice_agent_common.py +0 -0
  294. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_voice_edit.py +0 -0
  295. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_voice_edit_e2e.py +0 -0
  296. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_wake_word_assistant.py +0 -0
  297. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/__init__.py +0 -0
  298. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_audio_format.py +0 -0
  299. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_chroma.py +0 -0
  300. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_sse.py +0 -0
  301. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_vad.py +0 -0
  302. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_watch.py +0 -0
  303. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/__init__.py +0 -0
  304. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_cli.py +0 -0
  305. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_coding_agents.py +0 -0
  306. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_editors.py +0 -0
  307. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_project.py +0 -0
  308. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_terminals.py +0 -0
  309. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_verification.py +0 -0
  310. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_worktree.py +0 -0
  311. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/install/__init__.py +0 -0
  312. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/__init__.py +0 -0
  313. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_api_health.py +0 -0
  314. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_api_integration_liveish.py +0 -0
  315. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_client.py +0 -0
  316. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_engine.py +0 -0
  317. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_files.py +0 -0
  318. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_filters.py +0 -0
  319. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_git_integration.py +0 -0
  320. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_indexer.py +0 -0
  321. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_memory_integration.py +0 -0
  322. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_proxy_passthrough.py +0 -0
  323. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_store.py +0 -0
  324. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_utils.py +0 -0
  325. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/mocks/__init__.py +0 -0
  326. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/mocks/audio.py +0 -0
  327. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/mocks/llm.py +0 -0
  328. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/mocks/wyoming.py +0 -0
  329. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/__init__.py +0 -0
  330. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_api.py +0 -0
  331. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_engine.py +0 -0
  332. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_history.py +0 -0
  333. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_indexer.py +0 -0
  334. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_indexing.py +0 -0
  335. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_rag_client.py +0 -0
  336. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_rag_integration_liveish.py +0 -0
  337. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_rag_proxy_passthrough.py +0 -0
  338. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_retriever.py +0 -0
  339. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_store.py +0 -0
  340. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_utils.py +0 -0
  341. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_api.py +0 -0
  342. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_api_integration.py +0 -0
  343. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_asr.py +0 -0
  344. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_asr_recovery.py +0 -0
  345. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_audio_e2e.py +0 -0
  346. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_cli.py +0 -0
  347. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_config.py +0 -0
  348. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_config_cmd.py +0 -0
  349. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_docs_gen.py +0 -0
  350. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_env_vars.py +0 -0
  351. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_json_output.py +0 -0
  352. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_llm.py +0 -0
  353. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_llm_gemini.py +0 -0
  354. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_memory_tools.py +0 -0
  355. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_mlx_backend.py +0 -0
  356. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_process_manager.py +0 -0
  357. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_server_streaming.py +0 -0
  358. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_server_tts.py +0 -0
  359. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_server_whisper.py +0 -0
  360. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_services.py +0 -0
  361. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_tools.py +0 -0
  362. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_transformers_backend.py +0 -0
  363. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_tts.py +0 -0
  364. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_utils.py +0 -0
  365. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_wake_word.py +0 -0
  366. {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_wyoming_utils.py +0 -0
  367. {agent_cli-0.76.4 → agent_cli-0.76.5}/uv.lock +0 -0
  368. {agent_cli-0.76.4 → agent_cli-0.76.5}/zensical.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-cli
3
- Version: 0.76.4
3
+ Version: 0.76.5
4
4
  Summary: A suite of AI-powered command-line tools for text correction, audio transcription, and voice assistance.
5
5
  Project-URL: Homepage, https://github.com/basnijholt/agent-cli
6
6
  Author-email: Bas Nijholt <bas@nijho.lt>
@@ -514,19 +514,19 @@ agent-cli install-extras rag memory vad
514
514
 
515
515
  Available extras:
516
516
 
517
- rag - RAG proxy server (ChromaDB, embeddings)
518
- memory - Long-term memory proxy (ChromaDB)
519
- vad - Voice Activity Detection (Silero VAD via ONNX)
520
- audio - Local audio recording/playback
521
- piper - Local Piper TTS engine
522
- • kokoro - Kokoro neural TTS engine
523
- • faster-whisper - Whisper ASR for CUDA/CPU
517
+ audio - Audio recording/playback
518
+ faster-whisper - Whisper ASR via CTranslate2
519
+ kokoro - Kokoro neural TTS (GPU)
520
+ llm - LLM framework (pydantic-ai)
521
+ memory - Long-term memory proxy
524
522
  • mlx-whisper - Whisper ASR for Apple Silicon
525
- whisper-transformers - Whisper ASR via HuggingFace transformers (safetensors)
526
- wyoming - Wyoming protocol for ASR/TTS servers
523
+ piper - Piper TTS (CPU)
524
+ rag - RAG proxy (ChromaDB, embeddings)
527
525
  • server - FastAPI server components
528
- • speed - Audio speed adjustment
529
- llm - LLM framework (pydantic-ai)
526
+ • speed - Audio speed adjustment (audiostretchy)
527
+ vad - Voice Activity Detection (Silero VAD via ONNX)
528
+ • whisper-transformers - Whisper ASR via HuggingFace transformers
529
+ • wyoming - Wyoming protocol support
530
530
 
531
531
  Examples:
532
532
 
@@ -538,9 +538,9 @@ agent-cli install-extras rag memory vad
538
538
 
539
539
 
540
540
  ╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
541
- │ extras [EXTRAS]... Extras to install: rag, memory, vad, audio, piper, kokoro,
542
- faster-whisper, mlx-whisper, whisper-transformers, wyoming, │
543
- server, speed, llm
541
+ │ extras [EXTRAS]... Extras to install: audio, faster-whisper, kokoro, llm,
542
+ memory, mlx-whisper, piper, rag, server, speed, vad,
543
+ whisper-transformers, wyoming
544
544
  ╰────────────────────────────────────────────────────────────────────────────────────────╯
545
545
  ╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
546
546
  │ --list -l Show available extras with descriptions (what each one enables) │
@@ -420,19 +420,19 @@ agent-cli install-extras rag memory vad
420
420
 
421
421
  Available extras:
422
422
 
423
- rag - RAG proxy server (ChromaDB, embeddings)
424
- memory - Long-term memory proxy (ChromaDB)
425
- vad - Voice Activity Detection (Silero VAD via ONNX)
426
- audio - Local audio recording/playback
427
- piper - Local Piper TTS engine
428
- • kokoro - Kokoro neural TTS engine
429
- • faster-whisper - Whisper ASR for CUDA/CPU
423
+ audio - Audio recording/playback
424
+ faster-whisper - Whisper ASR via CTranslate2
425
+ kokoro - Kokoro neural TTS (GPU)
426
+ llm - LLM framework (pydantic-ai)
427
+ memory - Long-term memory proxy
430
428
  • mlx-whisper - Whisper ASR for Apple Silicon
431
- whisper-transformers - Whisper ASR via HuggingFace transformers (safetensors)
432
- wyoming - Wyoming protocol for ASR/TTS servers
429
+ piper - Piper TTS (CPU)
430
+ rag - RAG proxy (ChromaDB, embeddings)
433
431
  • server - FastAPI server components
434
- • speed - Audio speed adjustment
435
- llm - LLM framework (pydantic-ai)
432
+ • speed - Audio speed adjustment (audiostretchy)
433
+ vad - Voice Activity Detection (Silero VAD via ONNX)
434
+ • whisper-transformers - Whisper ASR via HuggingFace transformers
435
+ • wyoming - Wyoming protocol support
436
436
 
437
437
  Examples:
438
438
 
@@ -444,9 +444,9 @@ agent-cli install-extras rag memory vad
444
444
 
445
445
 
446
446
  ╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
447
- │ extras [EXTRAS]... Extras to install: rag, memory, vad, audio, piper, kokoro,
448
- faster-whisper, mlx-whisper, whisper-transformers, wyoming, │
449
- server, speed, llm
447
+ │ extras [EXTRAS]... Extras to install: audio, faster-whisper, kokoro, llm,
448
+ memory, mlx-whisper, piper, rag, server, speed, vad,
449
+ whisper-transformers, wyoming
450
450
  ╰────────────────────────────────────────────────────────────────────────────────────────╯
451
451
  ╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
452
452
  │ --list -l Show available extras with descriptions (what each one enables) │
@@ -7,7 +7,9 @@ import importlib
7
7
  import json
8
8
  import os
9
9
  import shutil
10
+ import subprocess
10
11
  import sys
12
+ import tomllib
11
13
  from importlib.util import find_spec
12
14
  from pathlib import Path
13
15
  from typing import TYPE_CHECKING, TypeVar
@@ -15,7 +17,7 @@ from typing import TYPE_CHECKING, TypeVar
15
17
  import typer
16
18
 
17
19
  from agent_cli.config import load_config
18
- from agent_cli.core.utils import err_console, print_error_message
20
+ from agent_cli.core.utils import console, err_console, print_error_message
19
21
 
20
22
  if TYPE_CHECKING:
21
23
  from collections.abc import Callable
@@ -26,6 +28,9 @@ F = TypeVar("F", bound="Callable[..., object]")
26
28
  _REEXEC_MARKER = "_AGENT_CLI_REEXEC"
27
29
 
28
30
 
31
+ # -- Settings --
32
+
33
+
29
34
  def _get_auto_install_setting() -> bool:
30
35
  """Check if auto-install is enabled (default: True)."""
31
36
  if os.environ.get("AGENT_CLI_NO_AUTO_INSTALL", "").lower() in ("1", "true", "yes"):
@@ -33,6 +38,9 @@ def _get_auto_install_setting() -> bool:
33
38
  return load_config().get("settings", {}).get("auto_install_extras", True)
34
39
 
35
40
 
41
+ # -- Environment Detection --
42
+
43
+
36
44
  def _is_uvx_cache() -> bool:
37
45
  """Check if running from uvx cache (ephemeral) vs uv tool (persistent)."""
38
46
  # uvx uses ~/.cache/uv/archive-v0/... (or AppData\Local\uv\cache on Windows)
@@ -42,35 +50,7 @@ def _is_uvx_cache() -> bool:
42
50
  return "/cache/uv/" in prefix_str or "/archive-v" in prefix_str
43
51
 
44
52
 
45
- def _reexec(cmd: list[str], message: str) -> None:
46
- """Re-execute with a new command, preventing infinite loops."""
47
- if os.environ.get(_REEXEC_MARKER):
48
- return
49
- err_console.print(f"[yellow]{message}[/]")
50
- new_env = os.environ.copy()
51
- new_env[_REEXEC_MARKER] = "1"
52
- os.execvpe(cmd[0], cmd, new_env) # noqa: S606
53
-
54
-
55
- def _reexec_with_uvx_extras(extras: list[str]) -> bool:
56
- """Re-execute with uvx running agent-cli[extras] directly."""
57
- if os.environ.get(_REEXEC_MARKER) or not _is_uvx_cache():
58
- return False
59
- uvx_path = shutil.which("uvx")
60
- if not uvx_path:
61
- return False
62
- extras_str = ",".join(extras)
63
- # Run agent-cli[extras] directly with Python 3.13 (some deps lack 3.14 wheels)
64
- cmd = [uvx_path, "--python", "3.13", f"agent-cli[{extras_str}]", *sys.argv[1:]]
65
- _reexec(cmd, f"Re-running with extras: {extras_str}")
66
- return True # Never reached
67
-
68
-
69
- def _reexec_self() -> None:
70
- """Re-execute after auto-install so new packages are visible."""
71
- executable = shutil.which("agent-cli") or sys.executable
72
- _reexec([executable, *sys.argv[1:]], "Re-running with installed extras...")
73
-
53
+ # -- Package Checking --
74
54
 
75
55
  # Load extras from JSON file
76
56
  _EXTRAS_FILE = Path(__file__).parent.parent / "_extras.json"
@@ -88,7 +68,7 @@ def _check_package_installed(pkg: str) -> bool:
88
68
  return False
89
69
 
90
70
 
91
- def check_extra_installed(extra: str) -> bool:
71
+ def _check_extra_installed(extra: str) -> bool:
92
72
  """Check if packages for an extra are installed using find_spec (no actual import).
93
73
 
94
74
  Supports `|` syntax for alternatives: "piper|kokoro" means ANY of these extras.
@@ -96,7 +76,7 @@ def check_extra_installed(extra: str) -> bool:
96
76
  """
97
77
  # Handle "extra1|extra2" syntax - any of these extras is sufficient
98
78
  if "|" in extra:
99
- return any(check_extra_installed(e) for e in extra.split("|"))
79
+ return any(_check_extra_installed(e) for e in extra.split("|"))
100
80
 
101
81
  if extra not in EXTRAS:
102
82
  return False # Unknown extra, trigger install attempt to surface error
@@ -106,6 +86,9 @@ def check_extra_installed(extra: str) -> bool:
106
86
  return all(_check_package_installed(pkg) for pkg in packages)
107
87
 
108
88
 
89
+ # -- Formatting (for error messages) --
90
+
91
+
109
92
  def _format_extra_item(extra: str) -> str:
110
93
  """Format a single extra as a list item with description."""
111
94
  desc, _ = EXTRAS.get(extra, ("", []))
@@ -126,7 +109,7 @@ def _format_install_commands(extras: list[str]) -> list[str]:
126
109
  ]
127
110
 
128
111
 
129
- def get_install_hint(extra: str) -> str:
112
+ def _get_install_hint(extra: str) -> str:
130
113
  """Get install command hint for a single extra.
131
114
 
132
115
  Supports `|` syntax for alternatives: "piper|kokoro" shows both options.
@@ -162,7 +145,7 @@ def get_install_hint(extra: str) -> str:
162
145
  def get_combined_install_hint(extras: list[str]) -> str:
163
146
  """Get a combined install hint for multiple missing extras."""
164
147
  if len(extras) == 1:
165
- return get_install_hint(extras[0])
148
+ return _get_install_hint(extras[0])
166
149
 
167
150
  lines = ["This command requires the following extras:"]
168
151
  lines.extend(_format_extra_item(extra) for extra in extras)
@@ -171,91 +154,214 @@ def get_combined_install_hint(extras: list[str]) -> str:
171
154
  return "\n".join(lines)
172
155
 
173
156
 
174
- def _resolve_alternative(extra: str) -> str | None:
175
- """For an alternative extra like 'a|b|c', return the installed one or first option."""
176
- if "|" not in extra:
177
- return extra
178
- alternatives = extra.split("|")
179
- # Check if any alternative is already installed - use that one
180
- for alt in alternatives:
181
- if check_extra_installed(alt):
182
- return alt
183
- # None installed, return first option for installation
184
- return alternatives[0]
185
-
186
-
187
- def _try_auto_install(
188
- missing: list[str],
189
- all_required: tuple[str, ...] | None = None,
190
- ) -> bool:
191
- """Attempt to auto-install missing extras. Returns True if successful.
192
-
193
- If all_required is provided, ensures all those extras are installed
194
- (not just the missing ones) to handle uv tool reinstall properly.
195
- With --force, uv replaces the entire install, so we must include
196
- ALL required extras to avoid losing ones that were already installed.
157
+ # -- Installation --
158
+
159
+ _REQUIREMENTS_DIR = Path(__file__).parent.parent / "_requirements"
160
+
161
+
162
+ def available_extras() -> list[str]:
163
+ """List available extras based on requirements files."""
164
+ if not _REQUIREMENTS_DIR.exists():
165
+ return []
166
+ return sorted(p.stem for p in _REQUIREMENTS_DIR.glob("*.txt"))
167
+
168
+
169
+ def _requirements_path(extra: str) -> Path:
170
+ """Get the requirements file path for an extra."""
171
+ return _REQUIREMENTS_DIR / f"{extra}.txt"
172
+
173
+
174
+ def _in_virtualenv() -> bool:
175
+ """Check if running inside a virtual environment."""
176
+ return sys.prefix != sys.base_prefix
177
+
178
+
179
+ def is_uv_tool_install() -> bool:
180
+ """Check if running from a uv tool environment."""
181
+ receipt = Path(sys.prefix) / "uv-receipt.toml"
182
+ return receipt.exists()
183
+
184
+
185
+ def _get_current_uv_tool_extras() -> list[str]:
186
+ """Get extras currently configured in uv-receipt.toml."""
187
+ receipt = Path(sys.prefix) / "uv-receipt.toml"
188
+ if not receipt.exists():
189
+ return []
190
+ data = tomllib.loads(receipt.read_text())
191
+ requirements = data.get("tool", {}).get("requirements", [])
192
+ for req in requirements:
193
+ if req.get("name") == "agent-cli":
194
+ return req.get("extras", [])
195
+ return []
196
+
197
+
198
+ def _install_via_uv_tool(extras: list[str], *, quiet: bool = False) -> bool:
199
+ """Reinstall agent-cli via uv tool with the specified extras."""
200
+ extras_str = ",".join(extras)
201
+ package_spec = f"agent-cli[{extras_str}]"
202
+ # Cap at Python 3.13 for compatibility - onnxruntime doesn't support 3.14 yet
203
+ major, minor = sys.version_info[:2]
204
+ python_version = f"{major}.{min(minor, 13)}"
205
+ cmd = ["uv", "tool", "install", package_spec, "--force", "--python", python_version]
206
+ if quiet:
207
+ cmd.append("-q")
208
+ # Use stderr for status messages so they don't pollute stdout
209
+ cmd_str = " ".join(cmd).replace("[", r"\[")
210
+ err_console.print(f"Running: [cyan]{cmd_str}[/]")
211
+ result = subprocess.run(cmd, check=False)
212
+ return result.returncode == 0
213
+
214
+
215
+ def _install_cmd() -> list[str]:
216
+ """Build the install command with appropriate flags."""
217
+ in_venv = _in_virtualenv()
218
+ if shutil.which("uv"):
219
+ cmd = ["uv", "pip", "install", "--python", sys.executable]
220
+ if not in_venv:
221
+ cmd.append("--system")
222
+ return cmd
223
+ cmd = [sys.executable, "-m", "pip", "install"]
224
+ if not in_venv:
225
+ cmd.append("--user")
226
+ return cmd
227
+
228
+
229
+ def install_extras_impl(extras: list[str], *, quiet: bool = False) -> bool:
230
+ """Install extras. Returns True on success, False on failure."""
231
+ if is_uv_tool_install():
232
+ current_extras = _get_current_uv_tool_extras()
233
+ new_extras = sorted(set(current_extras) | set(extras))
234
+ return _install_via_uv_tool(new_extras, quiet=quiet)
235
+
236
+ cmd = _install_cmd()
237
+ for extra in extras:
238
+ req_file = _requirements_path(extra)
239
+ if not quiet:
240
+ console.print(f"Installing [cyan]{extra}[/]...")
241
+ result = subprocess.run(
242
+ [*cmd, "-r", str(req_file)],
243
+ check=False,
244
+ capture_output=quiet,
245
+ )
246
+ if result.returncode != 0:
247
+ return False
248
+ return True
249
+
250
+
251
+ def _install_extras_programmatic(extras: list[str], *, quiet: bool = False) -> bool:
252
+ """Install extras programmatically (for auto-install feature)."""
253
+ available = available_extras()
254
+ valid = [e for e in extras if e in available]
255
+ invalid = [e for e in extras if e not in available]
256
+ if invalid:
257
+ err_console.print(f"[yellow]Unknown extras (skipped): {', '.join(invalid)}[/]")
258
+ return bool(valid) and install_extras_impl(valid, quiet=quiet)
259
+
260
+
261
+ def _resolve_extras_for_install(extras: tuple[str, ...]) -> list[str]:
262
+ """Normalize extras: resolve 'a|b' alternatives to concrete extras.
263
+
264
+ For alternatives, uses the installed one if present, otherwise first option.
197
265
  """
198
- from agent_cli.install.extras import install_extras_programmatic # noqa: PLC0415
266
+ result = []
267
+ for extra in extras:
268
+ if "|" in extra:
269
+ alternatives = extra.split("|")
270
+ installed = next((a for a in alternatives if _check_extra_installed(a)), None)
271
+ result.append(installed or alternatives[0])
272
+ else:
273
+ result.append(extra)
274
+ return result
275
+
276
+
277
+ def _maybe_exec_with_marker(cmd: list[str], message: str) -> None:
278
+ """Re-execute with a new command, preventing infinite loops."""
279
+ if os.environ.get(_REEXEC_MARKER):
280
+ return
281
+ err_console.print(f"[yellow]{message}[/]")
282
+ new_env = os.environ.copy()
283
+ new_env[_REEXEC_MARKER] = "1"
284
+ os.execvpe(cmd[0], cmd, new_env) # noqa: S606
199
285
 
200
- # Use all required extras if provided, otherwise just missing
201
- extras_source = all_required if all_required is not None else missing
202
286
 
203
- # Resolve alternatives: use installed one if present, otherwise first option
204
- extras_to_install = []
205
- for extra in extras_source:
206
- resolved = _resolve_alternative(extra)
207
- if resolved:
208
- extras_to_install.append(resolved)
287
+ def _maybe_reexec_with_uvx(extras: list[str]) -> None:
288
+ """Try to re-execute with uvx running agent-cli[extras] directly.
209
289
 
210
- # Show only the missing ones in the message (resolved)
211
- missing_display = [_resolve_alternative(e) or e.split("|")[0] for e in missing]
290
+ If successful, replaces the current process (never returns).
291
+ If not in uvx cache or uvx unavailable, returns normally.
292
+ """
293
+ if os.environ.get(_REEXEC_MARKER) or not _is_uvx_cache():
294
+ return
295
+ uvx_path = shutil.which("uvx")
296
+ if not uvx_path:
297
+ return
298
+ extras_str = ",".join(extras)
299
+ # Run agent-cli[extras] directly with Python 3.13 (some deps lack 3.14 wheels)
300
+ cmd = [uvx_path, "--python", "3.13", f"agent-cli[{extras_str}]", *sys.argv[1:]]
301
+ _maybe_exec_with_marker(cmd, f"Re-running with extras: {extras_str}")
302
+
303
+
304
+ def _try_auto_install(missing_display: list[str], extras_to_install: list[str]) -> bool:
305
+ """Attempt to auto-install extras. Returns True if successful."""
212
306
  err_console.print(
213
307
  f"[yellow]Auto-installing missing extras: {', '.join(missing_display)}[/]",
214
308
  )
215
- return install_extras_programmatic(extras_to_install, quiet=True)
309
+ return _install_extras_programmatic(extras_to_install, quiet=True)
310
+
311
+
312
+ def _maybe_reexec_after_install() -> None:
313
+ """Re-execute after auto-install so new packages are visible."""
314
+ executable = shutil.which("agent-cli") or sys.executable
315
+ _maybe_exec_with_marker([executable, *sys.argv[1:]], "Re-running with installed extras...")
316
+
317
+
318
+ # -- Main Orchestration --
216
319
 
217
320
 
218
321
  def _check_and_install_extras(extras: tuple[str, ...]) -> list[str]:
219
322
  """Check for missing extras and attempt auto-install. Returns list of still-missing."""
220
- missing = [e for e in extras if not check_extra_installed(e)]
323
+ # 1. Check what's missing
324
+ missing = [e for e in extras if not _check_extra_installed(e)]
221
325
  if not missing:
222
326
  return []
223
327
 
328
+ # 2. Auto-install disabled? Show error and return missing
224
329
  if not _get_auto_install_setting():
225
330
  print_error_message(get_combined_install_hint(missing))
226
331
  return missing
227
332
 
228
- # Resolve alternatives: use installed one if present, otherwise first option
229
- extras_to_install = [_resolve_alternative(e) or e.split("|")[0] for e in extras]
333
+ # 3. Resolve alternatives for installation (normalize once)
334
+ extras_to_install = _resolve_extras_for_install(extras)
335
+ missing_display = _resolve_extras_for_install(tuple(missing))
230
336
 
231
- # For uvx cache environments, re-exec with --with flag
232
- # This replaces the current process if successful (never returns)
233
- _reexec_with_uvx_extras(extras_to_install)
337
+ # 4. Try uvx re-exec (replaces process if successful)
338
+ if _is_uvx_cache():
339
+ _maybe_reexec_with_uvx(extras_to_install) # may not return
234
340
 
235
- # Not in uvx (or re-exec failed), try normal auto-install
236
- if not _try_auto_install(missing, all_required=extras):
341
+ # 5. Try normal auto-install
342
+ if not _try_auto_install(missing_display, extras_to_install):
237
343
  print_error_message("Auto-install failed.\n" + get_combined_install_hint(missing))
238
344
  return missing
239
345
 
240
346
  err_console.print("[green]Installation complete![/]")
241
347
 
242
- # Re-exec ourselves so the new packages are visible
243
- # The newly installed version will run with all extras available
244
- # If re-exec succeeds, this never returns
245
- _reexec_self()
348
+ # 6. Re-exec to pick up new packages (may not return)
349
+ _maybe_reexec_after_install()
246
350
 
247
- # If we get here, re-exec was skipped (loop prevention) or failed
248
- # Check if extras are now available in this process
351
+ # 7. If we're here, re-exec was skipped - check if packages are now visible
249
352
  importlib.invalidate_caches()
250
- still_missing = [e for e in extras if not check_extra_installed(e)]
353
+ still_missing = [e for e in extras if not _check_extra_installed(e)]
251
354
  if still_missing:
252
355
  print_error_message(
253
- "Auto-install completed but some dependencies are still missing.\n"
356
+ "Extras installed but not visible (restart may be needed).\n"
254
357
  + get_combined_install_hint(still_missing),
255
358
  )
256
359
  return still_missing
257
360
 
258
361
 
362
+ # -- Decorator --
363
+
364
+
259
365
  def requires_extras(*extras: str) -> Callable[[F], F]:
260
366
  """Decorator to declare required extras for a command.
261
367
 
@@ -0,0 +1,104 @@
1
+ """Install optional extras at runtime with pinned versions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+
9
+ from agent_cli.cli import app
10
+ from agent_cli.core.deps import (
11
+ EXTRAS as _EXTRAS_META,
12
+ )
13
+ from agent_cli.core.deps import (
14
+ available_extras,
15
+ install_extras_impl,
16
+ is_uv_tool_install,
17
+ )
18
+ from agent_cli.core.utils import console, print_error_message
19
+
20
+ # Extract descriptions from the centralized EXTRAS metadata
21
+ EXTRAS: dict[str, str] = {name: desc for name, (desc, _) in _EXTRAS_META.items()}
22
+
23
+
24
+ @app.command("install-extras", rich_help_panel="Installation", no_args_is_help=True)
25
+ def install_extras(
26
+ extras: Annotated[
27
+ list[str] | None,
28
+ typer.Argument(
29
+ help="Extras to install: `audio`, `faster-whisper`, `kokoro`, `llm`, `memory`, "
30
+ "`mlx-whisper`, `piper`, `rag`, `server`, `speed`, `vad`, `whisper-transformers`, "
31
+ "`wyoming`",
32
+ ),
33
+ ] = None,
34
+ list_extras: Annotated[
35
+ bool,
36
+ typer.Option(
37
+ "--list",
38
+ "-l",
39
+ help="Show available extras with descriptions (what each one enables)",
40
+ ),
41
+ ] = False,
42
+ all_extras: Annotated[
43
+ bool,
44
+ typer.Option("--all", "-a", help="Install all available extras at once"),
45
+ ] = False,
46
+ ) -> None:
47
+ """Install optional dependencies with pinned, compatible versions.
48
+
49
+ Many agent-cli features require optional dependencies. This command installs
50
+ them with version pinning to ensure compatibility. Dependencies persist
51
+ across `uv tool upgrade` when installed via `uv tool`.
52
+
53
+ **Available extras:**
54
+ - `audio` - Audio recording/playback
55
+ - `faster-whisper` - Whisper ASR via CTranslate2
56
+ - `kokoro` - Kokoro neural TTS (GPU)
57
+ - `llm` - LLM framework (pydantic-ai)
58
+ - `memory` - Long-term memory proxy
59
+ - `mlx-whisper` - Whisper ASR for Apple Silicon
60
+ - `piper` - Piper TTS (CPU)
61
+ - `rag` - RAG proxy (ChromaDB, embeddings)
62
+ - `server` - FastAPI server components
63
+ - `speed` - Audio speed adjustment (audiostretchy)
64
+ - `vad` - Voice Activity Detection (Silero VAD via ONNX)
65
+ - `whisper-transformers` - Whisper ASR via HuggingFace transformers
66
+ - `wyoming` - Wyoming protocol support
67
+
68
+ **Examples:**
69
+
70
+ agent-cli install-extras rag # Install RAG dependencies
71
+ agent-cli install-extras memory vad # Install multiple extras
72
+ agent-cli install-extras --list # Show available extras
73
+ agent-cli install-extras --all # Install all extras
74
+
75
+ """
76
+ available = available_extras()
77
+
78
+ if list_extras:
79
+ console.print("[bold]Available extras:[/]")
80
+ for name in available:
81
+ desc = EXTRAS.get(name, "")
82
+ console.print(f" [cyan]{name}[/]: {desc}")
83
+ return
84
+
85
+ if all_extras:
86
+ extras = available
87
+
88
+ if not extras:
89
+ print_error_message("No extras specified. Use --list to see available, or --all.")
90
+ raise typer.Exit(1)
91
+
92
+ invalid = [e for e in extras if e not in available]
93
+ if invalid:
94
+ print_error_message(f"Unknown extras: {invalid}. Use --list to see available.")
95
+ raise typer.Exit(1)
96
+
97
+ if not install_extras_impl(extras):
98
+ print_error_message("Failed to install extras")
99
+ raise typer.Exit(1)
100
+
101
+ if is_uv_tool_install():
102
+ console.print("[green]Done! Extras will persist across uv tool upgrade.[/]")
103
+ else:
104
+ console.print("[green]Done![/]")
@@ -15,7 +15,7 @@ from rich.console import Console
15
15
  from agent_cli.core import deps
16
16
 
17
17
 
18
- def _mock_check_extra_installed(extra: str) -> bool: # noqa: ARG001
18
+ def _mock__check_extra_installed(extra: str) -> bool: # noqa: ARG001
19
19
  """Always return True for tests - all extras assumed available."""
20
20
  return True
21
21
 
@@ -27,7 +27,7 @@ def pytest_configure() -> None:
27
27
  import sounddevice during test collection, which triggers Pa_Initialize()
28
28
  and hangs on Windows CI without audio hardware.
29
29
 
30
- Also mocks check_extra_installed to always return True so tests that
30
+ Also mocks _check_extra_installed to always return True so tests that
31
31
  exercise command logic don't fail on missing optional dependencies.
32
32
  """
33
33
  if "sounddevice" not in sys.modules:
@@ -37,9 +37,9 @@ def pytest_configure() -> None:
37
37
  mock_sd.OutputStream = MagicMock()
38
38
  sys.modules["sounddevice"] = mock_sd
39
39
 
40
- # Mock check_extra_installed to always return True for tests
40
+ # Mock _check_extra_installed to always return True for tests
41
41
  # This allows tests to exercise command logic without needing all extras
42
- deps.check_extra_installed = _mock_check_extra_installed
42
+ deps._check_extra_installed = _mock__check_extra_installed
43
43
 
44
44
 
45
45
  def pytest_collection_modifyitems(items: list[pytest.Item]) -> None:
@@ -5,7 +5,8 @@ from __future__ import annotations
5
5
  import typing
6
6
 
7
7
  from agent_cli.core.deps import EXTRAS as EXTRAS_META
8
- from agent_cli.install.extras import EXTRAS, _available_extras, install_extras
8
+ from agent_cli.core.deps import available_extras
9
+ from agent_cli.install.extras import EXTRAS, install_extras
9
10
 
10
11
 
11
12
  def test_extras_dict_matches_requirements_files() -> None:
@@ -14,7 +15,7 @@ def test_extras_dict_matches_requirements_files() -> None:
14
15
  Extras defined in _extras.json may or may not have requirements files.
15
16
  Those with requirements files (in _requirements/) should have descriptions.
16
17
  """
17
- available = set(_available_extras())
18
+ available = set(available_extras())
18
19
  documented = set(EXTRAS.keys())
19
20
 
20
21
  # Only check that extras with requirements files have documentation
@@ -51,7 +52,7 @@ def test_install_extras_help_lists_all_extras() -> None:
51
52
  in install_extras() must be updated to include them. This test catches
52
53
  missing extras in the help text.
53
54
  """
54
- available = set(_available_extras())
55
+ available = set(available_extras())
55
56
  docstring = install_extras.__doc__ or ""
56
57
 
57
58
  # Get the argument help text from Annotated metadata