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.
- {agent_cli-0.76.4 → agent_cli-0.76.5}/PKG-INFO +15 -15
- {agent_cli-0.76.4 → agent_cli-0.76.5}/README.md +14 -14
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/deps.py +191 -85
- agent_cli-0.76.5/agent_cli/install/extras.py +104 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/conftest.py +4 -4
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/install/test_extras.py +4 -3
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_requires_extras.py +39 -42
- agent_cli-0.76.4/agent_cli/install/extras.py +0 -209
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude/skills/agent-cli-dev/SKILL.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude/skills/agent-cli-dev/examples.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/README.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/marketplace.json +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/plugin.json +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/skills/agent-cli-dev/SKILL.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.claude-plugin/skills/agent-cli-dev/examples.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.cursorrules +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.dockerignore +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.env.example +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/logo.svg +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/release-drafter.yml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/renovate.json +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/scripts/check_extras_sync.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/scripts/sync_requirements.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/automerge.yml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/docker.yml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/docs.yml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/markdown-code-runner.yml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/pytest.yml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/release-drafter.yml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/release.yml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.github/workflows/toc.yaml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.gitignore +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.jscpd.json +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.pre-commit-config.yaml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.prompts/docs-review.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/.prompts/pr-review.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/CLAUDE.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/LICENSE +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/__main__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_extras.json +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/.gitkeep +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/audio.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/faster-whisper.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/kokoro.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/llm.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/memory.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/mlx-whisper.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/piper.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/rag.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/server.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/speed.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/vad.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/whisper-transformers.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_requirements/wyoming.txt +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/_tools.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/_voice_agent_common.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/assistant.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/autocorrect.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/chat.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/memory/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/memory/add.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/memory/proxy.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/rag_proxy.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/speak.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/transcribe.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/transcribe_daemon.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/agents/voice_edit.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/api.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/cli.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/config.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/config_cmd.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/constants.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/audio.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/audio_format.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/chroma.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/openai_proxy.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/process.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/reranker.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/sse.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/transcription_logger.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/utils.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/vad.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/core/watch.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/cli.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/aider.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/base.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/claude.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/codex.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/copilot.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/gemini.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/opencode.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/registry.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/base.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/cursor.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/emacs.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/jetbrains.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/nano.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/neovim.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/registry.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/sublime.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/vim.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/vscode.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/editors/zed.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/project.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/registry.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/skill/SKILL.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/skill/examples.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/apple_terminal.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/base.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/gnome.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/iterm2.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/kitty.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/registry.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/tmux.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/warp.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/terminals/zellij.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/dev/worktree.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/docs_gen.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/example-config.toml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/install/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/install/common.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/install/hotkeys.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/install/services.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_files.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_filters.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_git.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_indexer.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_ingest.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_persistence.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_prompt.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_retrieval.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_store.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_streaming.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/_tasks.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/api.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/client.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/engine.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/entities.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/memory/models.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/opts.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/py.typed +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_indexer.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_indexing.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_prompt.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_retriever.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_store.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/_utils.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/api.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/client.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/engine.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/rag/models.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/.runtime/.gitkeep +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/check_plugin_skill_sync.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-openwakeword.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-piper-windows.ps1 +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-piper.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper-linux.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper-macos.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper-windows.ps1 +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/run_faster_whisper_server.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-linux.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-macos.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/setup-windows.ps1 +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/start-all-services.sh +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/scripts/sync_extras.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/cli.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/common.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/model_manager.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/model_registry.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/proxy/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/proxy/api.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/streaming.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/api.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/backends/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/backends/base.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/backends/kokoro.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/backends/piper.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/model_manager.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/model_registry.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/tts/wyoming_handler.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/api.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/base.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/mlx.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/transformers.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/languages.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/model_manager.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/model_registry.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/server/whisper/wyoming_handler.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/_wyoming_utils.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/asr.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/llm.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/tts.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/agent_cli/services/wake_word.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/docker-compose.yml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/memory-proxy.Dockerfile +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/rag-proxy.Dockerfile +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/transcribe-proxy.Dockerfile +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/tts.Dockerfile +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docker/whisper.Dockerfile +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/CNAME +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/architecture/index.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/architecture/memory.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/architecture/rag.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/assistant.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/autocorrect.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/chat.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/config.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/dev.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/index.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/install-extras.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/install-hotkeys.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/install-services.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/memory.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/rag-proxy.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/server/index.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/server/transcribe-proxy.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/server/tts.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/server/whisper.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/speak.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/start-services.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/transcribe-daemon.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/transcribe.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/commands/voice-edit.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/configuration.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/getting-started.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/iOS_Shortcut_Guide.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/index.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/docker.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/index.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/linux.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/macos.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/nixos.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/installation/windows.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/logo-clean.svg +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/run_markdown_code_runner.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/docs/system-integration.md +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/example.agent-cli-config.toml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/justfile +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/pyproject.toml +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/shell.nix +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_fix_my_text.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_interactive.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_interactive_extra.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_memory_add.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_speak.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_speak_e2e.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe_agent.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe_daemon.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe_e2e.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_transcribe_recovery.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_tts_common.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_tts_common_extra.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_voice_agent_common.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_voice_edit.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_voice_edit_e2e.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/agents/test_wake_word_assistant.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_audio_format.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_chroma.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_sse.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_vad.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/core/test_watch.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_cli.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_coding_agents.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_editors.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_project.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_terminals.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_verification.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/dev/test_worktree.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/install/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_api_health.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_api_integration_liveish.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_client.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_engine.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_files.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_filters.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_git_integration.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_indexer.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_memory_integration.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_proxy_passthrough.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_store.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/memory/test_utils.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/mocks/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/mocks/audio.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/mocks/llm.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/mocks/wyoming.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/__init__.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_api.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_engine.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_history.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_indexer.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_indexing.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_rag_client.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_rag_integration_liveish.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_rag_proxy_passthrough.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_retriever.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_store.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/rag/test_utils.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_api.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_api_integration.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_asr.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_asr_recovery.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_audio_e2e.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_cli.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_config.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_config_cmd.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_docs_gen.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_env_vars.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_json_output.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_llm.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_llm_gemini.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_memory_tools.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_mlx_backend.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_process_manager.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_server_streaming.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_server_tts.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_server_whisper.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_services.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_tools.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_transformers_backend.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_tts.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_utils.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_wake_word.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/tests/test_wyoming_utils.py +0 -0
- {agent_cli-0.76.4 → agent_cli-0.76.5}/uv.lock +0 -0
- {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.
|
|
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
|
-
•
|
|
518
|
-
•
|
|
519
|
-
•
|
|
520
|
-
•
|
|
521
|
-
•
|
|
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
|
-
•
|
|
526
|
-
•
|
|
523
|
+
• piper - Piper TTS (CPU)
|
|
524
|
+
• rag - RAG proxy (ChromaDB, embeddings)
|
|
527
525
|
• server - FastAPI server components
|
|
528
|
-
• speed - Audio speed adjustment
|
|
529
|
-
•
|
|
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:
|
|
542
|
-
│
|
|
543
|
-
│
|
|
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
|
-
•
|
|
424
|
-
•
|
|
425
|
-
•
|
|
426
|
-
•
|
|
427
|
-
•
|
|
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
|
-
•
|
|
432
|
-
•
|
|
429
|
+
• piper - Piper TTS (CPU)
|
|
430
|
+
• rag - RAG proxy (ChromaDB, embeddings)
|
|
433
431
|
• server - FastAPI server components
|
|
434
|
-
• speed - Audio speed adjustment
|
|
435
|
-
•
|
|
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:
|
|
448
|
-
│
|
|
449
|
-
│
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
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
|
-
|
|
204
|
-
|
|
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
|
-
|
|
211
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
229
|
-
extras_to_install =
|
|
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
|
-
#
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
#
|
|
236
|
-
if not _try_auto_install(
|
|
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
|
|
243
|
-
|
|
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
|
|
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
|
|
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
|
-
"
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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(
|
|
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(
|
|
55
|
+
available = set(available_extras())
|
|
55
56
|
docstring = install_extras.__doc__ or ""
|
|
56
57
|
|
|
57
58
|
# Get the argument help text from Annotated metadata
|