agent-cli 0.76.3__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.3 → agent_cli-0.76.5}/PKG-INFO +15 -15
- {agent_cli-0.76.3 → agent_cli-0.76.5}/README.md +14 -14
- agent_cli-0.76.5/agent_cli/core/deps.py +384 -0
- agent_cli-0.76.5/agent_cli/install/extras.py +104 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/conftest.py +4 -4
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/install/test_extras.py +4 -3
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_requires_extras.py +39 -42
- agent_cli-0.76.3/agent_cli/core/deps.py +0 -278
- agent_cli-0.76.3/agent_cli/install/extras.py +0 -209
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.claude/skills/agent-cli-dev/SKILL.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.claude/skills/agent-cli-dev/examples.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.claude-plugin/README.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.claude-plugin/marketplace.json +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.claude-plugin/plugin.json +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.claude-plugin/skills/agent-cli-dev/SKILL.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.claude-plugin/skills/agent-cli-dev/examples.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.cursorrules +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.dockerignore +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.env.example +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/logo.svg +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/release-drafter.yml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/renovate.json +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/scripts/check_extras_sync.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/scripts/sync_requirements.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/workflows/automerge.yml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/workflows/docker.yml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/workflows/docs.yml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/workflows/markdown-code-runner.yml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/workflows/pytest.yml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/workflows/release-drafter.yml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/workflows/release.yml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.github/workflows/toc.yaml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.gitignore +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.jscpd.json +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.pre-commit-config.yaml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.prompts/docs-review.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/.prompts/pr-review.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/CLAUDE.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/LICENSE +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/__main__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_extras.json +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/.gitkeep +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/audio.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/faster-whisper.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/kokoro.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/llm.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/memory.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/mlx-whisper.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/piper.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/rag.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/server.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/speed.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/vad.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/whisper-transformers.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_requirements/wyoming.txt +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/_tools.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/_voice_agent_common.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/assistant.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/autocorrect.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/chat.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/memory/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/memory/add.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/memory/proxy.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/rag_proxy.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/speak.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/transcribe.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/transcribe_daemon.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/agents/voice_edit.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/api.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/cli.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/config.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/config_cmd.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/constants.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/audio.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/audio_format.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/chroma.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/openai_proxy.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/process.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/reranker.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/sse.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/transcription_logger.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/utils.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/vad.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/core/watch.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/cli.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/aider.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/base.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/claude.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/codex.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/copilot.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/gemini.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/opencode.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/coding_agents/registry.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/base.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/cursor.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/emacs.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/jetbrains.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/nano.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/neovim.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/registry.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/sublime.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/vim.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/vscode.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/editors/zed.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/project.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/registry.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/skill/SKILL.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/skill/examples.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/apple_terminal.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/base.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/gnome.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/iterm2.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/kitty.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/registry.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/tmux.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/warp.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/terminals/zellij.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/dev/worktree.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/docs_gen.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/example-config.toml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/install/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/install/common.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/install/hotkeys.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/install/services.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_files.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_filters.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_git.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_indexer.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_ingest.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_persistence.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_prompt.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_retrieval.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_store.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_streaming.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/_tasks.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/api.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/client.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/engine.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/entities.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/memory/models.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/opts.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/py.typed +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/_indexer.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/_indexing.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/_prompt.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/_retriever.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/_store.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/_utils.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/api.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/client.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/engine.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/rag/models.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/.runtime/.gitkeep +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/check_plugin_skill_sync.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/run-openwakeword.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/run-piper-windows.ps1 +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/run-piper.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper-linux.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper-macos.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper-windows.ps1 +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/run-whisper.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/run_faster_whisper_server.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/setup-linux.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/setup-macos.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/setup-windows.ps1 +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/start-all-services.sh +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/scripts/sync_extras.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/cli.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/common.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/model_manager.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/model_registry.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/proxy/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/proxy/api.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/streaming.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/tts/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/tts/api.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/tts/backends/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/tts/backends/base.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/tts/backends/kokoro.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/tts/backends/piper.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/tts/model_manager.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/tts/model_registry.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/tts/wyoming_handler.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/api.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/base.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/mlx.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/backends/transformers.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/languages.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/model_manager.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/model_registry.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/server/whisper/wyoming_handler.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/services/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/services/_wyoming_utils.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/services/asr.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/services/llm.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/services/tts.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/agent_cli/services/wake_word.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docker/docker-compose.yml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docker/memory-proxy.Dockerfile +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docker/rag-proxy.Dockerfile +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docker/transcribe-proxy.Dockerfile +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docker/tts.Dockerfile +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docker/whisper.Dockerfile +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/CNAME +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/architecture/index.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/architecture/memory.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/architecture/rag.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/assistant.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/autocorrect.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/chat.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/config.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/dev.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/index.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/install-extras.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/install-hotkeys.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/install-services.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/memory.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/rag-proxy.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/server/index.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/server/transcribe-proxy.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/server/tts.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/server/whisper.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/speak.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/start-services.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/transcribe-daemon.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/transcribe.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/commands/voice-edit.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/configuration.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/getting-started.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/iOS_Shortcut_Guide.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/index.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/installation/docker.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/installation/index.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/installation/linux.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/installation/macos.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/installation/nixos.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/installation/windows.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/logo-clean.svg +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/run_markdown_code_runner.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/docs/system-integration.md +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/example.agent-cli-config.toml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/justfile +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/pyproject.toml +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/shell.nix +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_fix_my_text.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_interactive.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_interactive_extra.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_memory_add.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_speak.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_speak_e2e.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_transcribe.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_transcribe_agent.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_transcribe_daemon.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_transcribe_e2e.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_transcribe_recovery.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_tts_common.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_tts_common_extra.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_voice_agent_common.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_voice_edit.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_voice_edit_e2e.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/agents/test_wake_word_assistant.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/core/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/core/test_audio_format.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/core/test_chroma.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/core/test_sse.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/core/test_vad.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/core/test_watch.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/dev/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/dev/test_cli.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/dev/test_coding_agents.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/dev/test_editors.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/dev/test_project.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/dev/test_terminals.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/dev/test_verification.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/dev/test_worktree.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/install/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_api_health.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_api_integration_liveish.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_client.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_engine.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_files.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_filters.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_git_integration.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_indexer.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_memory_integration.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_proxy_passthrough.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_store.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/memory/test_utils.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/mocks/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/mocks/audio.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/mocks/llm.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/mocks/wyoming.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/__init__.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_api.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_engine.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_history.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_indexer.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_indexing.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_rag_client.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_rag_integration_liveish.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_rag_proxy_passthrough.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_retriever.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_store.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/rag/test_utils.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_api.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_api_integration.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_asr.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_asr_recovery.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_audio_e2e.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_cli.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_config.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_config_cmd.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_docs_gen.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_env_vars.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_json_output.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_llm.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_llm_gemini.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_memory_tools.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_mlx_backend.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_process_manager.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_server_streaming.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_server_tts.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_server_whisper.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_services.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_tools.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_transformers_backend.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_tts.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_utils.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_wake_word.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/tests/test_wyoming_utils.py +0 -0
- {agent_cli-0.76.3 → agent_cli-0.76.5}/uv.lock +0 -0
- {agent_cli-0.76.3 → 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) │
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
"""Helpers for optional dependency checks."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import functools
|
|
6
|
+
import importlib
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import shutil
|
|
10
|
+
import subprocess
|
|
11
|
+
import sys
|
|
12
|
+
import tomllib
|
|
13
|
+
from importlib.util import find_spec
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import TYPE_CHECKING, TypeVar
|
|
16
|
+
|
|
17
|
+
import typer
|
|
18
|
+
|
|
19
|
+
from agent_cli.config import load_config
|
|
20
|
+
from agent_cli.core.utils import console, err_console, print_error_message
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from collections.abc import Callable
|
|
24
|
+
|
|
25
|
+
F = TypeVar("F", bound="Callable[..., object]")
|
|
26
|
+
|
|
27
|
+
# Marker to prevent infinite re-exec loops
|
|
28
|
+
_REEXEC_MARKER = "_AGENT_CLI_REEXEC"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# -- Settings --
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _get_auto_install_setting() -> bool:
|
|
35
|
+
"""Check if auto-install is enabled (default: True)."""
|
|
36
|
+
if os.environ.get("AGENT_CLI_NO_AUTO_INSTALL", "").lower() in ("1", "true", "yes"):
|
|
37
|
+
return False
|
|
38
|
+
return load_config().get("settings", {}).get("auto_install_extras", True)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# -- Environment Detection --
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _is_uvx_cache() -> bool:
|
|
45
|
+
"""Check if running from uvx cache (ephemeral) vs uv tool (persistent)."""
|
|
46
|
+
# uvx uses ~/.cache/uv/archive-v0/... (or AppData\Local\uv\cache on Windows)
|
|
47
|
+
# uv tool uses ~/.local/share/uv/tools/... (or AppData\Local\uv\tools on Windows)
|
|
48
|
+
# Use as_posix() for cross-platform forward-slash paths
|
|
49
|
+
prefix_str = Path(sys.prefix).resolve().as_posix()
|
|
50
|
+
return "/cache/uv/" in prefix_str or "/archive-v" in prefix_str
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# -- Package Checking --
|
|
54
|
+
|
|
55
|
+
# Load extras from JSON file
|
|
56
|
+
_EXTRAS_FILE = Path(__file__).parent.parent / "_extras.json"
|
|
57
|
+
EXTRAS: dict[str, tuple[str, list[str]]] = {
|
|
58
|
+
k: (v[0], v[1]) for k, v in json.loads(_EXTRAS_FILE.read_text()).items()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _check_package_installed(pkg: str) -> bool:
|
|
63
|
+
"""Check if a single package is installed."""
|
|
64
|
+
top_module = pkg.split(".")[0]
|
|
65
|
+
try:
|
|
66
|
+
return find_spec(top_module) is not None
|
|
67
|
+
except (ValueError, ModuleNotFoundError):
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _check_extra_installed(extra: str) -> bool:
|
|
72
|
+
"""Check if packages for an extra are installed using find_spec (no actual import).
|
|
73
|
+
|
|
74
|
+
Supports `|` syntax for alternatives: "piper|kokoro" means ANY of these extras.
|
|
75
|
+
For regular extras, ALL packages must be installed.
|
|
76
|
+
"""
|
|
77
|
+
# Handle "extra1|extra2" syntax - any of these extras is sufficient
|
|
78
|
+
if "|" in extra:
|
|
79
|
+
return any(_check_extra_installed(e) for e in extra.split("|"))
|
|
80
|
+
|
|
81
|
+
if extra not in EXTRAS:
|
|
82
|
+
return False # Unknown extra, trigger install attempt to surface error
|
|
83
|
+
_, packages = EXTRAS[extra]
|
|
84
|
+
|
|
85
|
+
# All packages must be installed
|
|
86
|
+
return all(_check_package_installed(pkg) for pkg in packages)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# -- Formatting (for error messages) --
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _format_extra_item(extra: str) -> str:
|
|
93
|
+
"""Format a single extra as a list item with description."""
|
|
94
|
+
desc, _ = EXTRAS.get(extra, ("", []))
|
|
95
|
+
if desc:
|
|
96
|
+
return f" - '{extra}' ({desc})"
|
|
97
|
+
return f" - '{extra}'"
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _format_install_commands(extras: list[str]) -> list[str]:
|
|
101
|
+
"""Format install commands for one or more extras."""
|
|
102
|
+
combined = ",".join(extras)
|
|
103
|
+
extras_args = " ".join(extras)
|
|
104
|
+
return [
|
|
105
|
+
"Install with:",
|
|
106
|
+
f' [bold cyan]uv tool install -p 3.13 "agent-cli\\[{combined}]"[/bold cyan]',
|
|
107
|
+
" # or",
|
|
108
|
+
f" [bold cyan]agent-cli install-extras {extras_args}[/bold cyan]",
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _get_install_hint(extra: str) -> str:
|
|
113
|
+
"""Get install command hint for a single extra.
|
|
114
|
+
|
|
115
|
+
Supports `|` syntax for alternatives: "piper|kokoro" shows both options.
|
|
116
|
+
"""
|
|
117
|
+
# Handle "extra1|extra2" syntax - show all options
|
|
118
|
+
if "|" in extra:
|
|
119
|
+
alternatives = extra.split("|")
|
|
120
|
+
lines = ["This command requires one of:"]
|
|
121
|
+
lines.extend(_format_extra_item(alt) for alt in alternatives)
|
|
122
|
+
lines.append("")
|
|
123
|
+
lines.append("Install one with:")
|
|
124
|
+
lines.extend(
|
|
125
|
+
f' [bold cyan]uv tool install -p 3.13 "agent-cli\\[{alt}]"[/bold cyan]'
|
|
126
|
+
for alt in alternatives
|
|
127
|
+
)
|
|
128
|
+
lines.append(" # or")
|
|
129
|
+
lines.extend(
|
|
130
|
+
f" [bold cyan]agent-cli install-extras {alt}[/bold cyan]" for alt in alternatives
|
|
131
|
+
)
|
|
132
|
+
return "\n".join(lines)
|
|
133
|
+
|
|
134
|
+
desc, _ = EXTRAS.get(extra, ("", []))
|
|
135
|
+
header = f"This command requires the '{extra}' extra"
|
|
136
|
+
if desc:
|
|
137
|
+
header += f" ({desc})"
|
|
138
|
+
header += "."
|
|
139
|
+
|
|
140
|
+
lines = [header, ""]
|
|
141
|
+
lines.extend(_format_install_commands([extra]))
|
|
142
|
+
return "\n".join(lines)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def get_combined_install_hint(extras: list[str]) -> str:
|
|
146
|
+
"""Get a combined install hint for multiple missing extras."""
|
|
147
|
+
if len(extras) == 1:
|
|
148
|
+
return _get_install_hint(extras[0])
|
|
149
|
+
|
|
150
|
+
lines = ["This command requires the following extras:"]
|
|
151
|
+
lines.extend(_format_extra_item(extra) for extra in extras)
|
|
152
|
+
lines.append("")
|
|
153
|
+
lines.extend(_format_install_commands(extras))
|
|
154
|
+
return "\n".join(lines)
|
|
155
|
+
|
|
156
|
+
|
|
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.
|
|
265
|
+
"""
|
|
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
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def _maybe_reexec_with_uvx(extras: list[str]) -> None:
|
|
288
|
+
"""Try to re-execute with uvx running agent-cli[extras] directly.
|
|
289
|
+
|
|
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."""
|
|
306
|
+
err_console.print(
|
|
307
|
+
f"[yellow]Auto-installing missing extras: {', '.join(missing_display)}[/]",
|
|
308
|
+
)
|
|
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 --
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def _check_and_install_extras(extras: tuple[str, ...]) -> list[str]:
|
|
322
|
+
"""Check for missing extras and attempt auto-install. Returns list of still-missing."""
|
|
323
|
+
# 1. Check what's missing
|
|
324
|
+
missing = [e for e in extras if not _check_extra_installed(e)]
|
|
325
|
+
if not missing:
|
|
326
|
+
return []
|
|
327
|
+
|
|
328
|
+
# 2. Auto-install disabled? Show error and return missing
|
|
329
|
+
if not _get_auto_install_setting():
|
|
330
|
+
print_error_message(get_combined_install_hint(missing))
|
|
331
|
+
return missing
|
|
332
|
+
|
|
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))
|
|
336
|
+
|
|
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
|
|
340
|
+
|
|
341
|
+
# 5. Try normal auto-install
|
|
342
|
+
if not _try_auto_install(missing_display, extras_to_install):
|
|
343
|
+
print_error_message("Auto-install failed.\n" + get_combined_install_hint(missing))
|
|
344
|
+
return missing
|
|
345
|
+
|
|
346
|
+
err_console.print("[green]Installation complete![/]")
|
|
347
|
+
|
|
348
|
+
# 6. Re-exec to pick up new packages (may not return)
|
|
349
|
+
_maybe_reexec_after_install()
|
|
350
|
+
|
|
351
|
+
# 7. If we're here, re-exec was skipped - check if packages are now visible
|
|
352
|
+
importlib.invalidate_caches()
|
|
353
|
+
still_missing = [e for e in extras if not _check_extra_installed(e)]
|
|
354
|
+
if still_missing:
|
|
355
|
+
print_error_message(
|
|
356
|
+
"Extras installed but not visible (restart may be needed).\n"
|
|
357
|
+
+ get_combined_install_hint(still_missing),
|
|
358
|
+
)
|
|
359
|
+
return still_missing
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
# -- Decorator --
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def requires_extras(*extras: str) -> Callable[[F], F]:
|
|
366
|
+
"""Decorator to declare required extras for a command.
|
|
367
|
+
|
|
368
|
+
Auto-installs missing extras by default. Disable via AGENT_CLI_NO_AUTO_INSTALL=1
|
|
369
|
+
or config [settings] auto_install_extras = false.
|
|
370
|
+
"""
|
|
371
|
+
|
|
372
|
+
def decorator(func: F) -> F:
|
|
373
|
+
func._required_extras = extras # type: ignore[attr-defined]
|
|
374
|
+
|
|
375
|
+
@functools.wraps(func)
|
|
376
|
+
def wrapper(*args: object, **kwargs: object) -> object:
|
|
377
|
+
if _check_and_install_extras(extras):
|
|
378
|
+
raise typer.Exit(1)
|
|
379
|
+
return func(*args, **kwargs)
|
|
380
|
+
|
|
381
|
+
wrapper._required_extras = extras # type: ignore[attr-defined]
|
|
382
|
+
return wrapper # type: ignore[return-value]
|
|
383
|
+
|
|
384
|
+
return decorator
|
|
@@ -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
|