agent-cli 0.98.4__tar.gz → 0.99.0__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.98.4 → agent_cli-0.99.0}/PKG-INFO +16 -1
- {agent_cli-0.98.4 → agent_cli-0.99.0}/README.md +15 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/transcribe.py +44 -7
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/opts.py +25 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/services/asr.py +206 -2
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/transcribe.md +22 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/installation/macos-app.md +6 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/AgentCommand.swift +21 -3
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/AgentRuntime.swift +78 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/AppDelegate.swift +4 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/ConfigurableHotkeyController.swift +52 -0
- agent_cli-0.99.0/macos/AgentCLI/Sources/AgentCLI/LiveTranscriptionPreview.swift +110 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/RecordingIndicatorController.swift +9 -1
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/Shortcuts.swift +24 -2
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/TranscriptionSettings.swift +5 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/VoiceLevelOverlay.swift +86 -9
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Tests/AgentCLITests/AgentCommandTests.swift +40 -3
- agent_cli-0.99.0/macos/AgentCLI/Tests/AgentCLITests/LivePreviewSwiftTestingTests.swift +62 -0
- agent_cli-0.99.0/macos/AgentCLI/Tests/AgentCLITests/LiveTranscriptionPreviewTests.swift +24 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Tests/AgentCLITests/VoiceLevelMeterTests.swift +13 -1
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/appcast.xml +32 -31
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_transcribe.py +156 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_transcribe_recovery.py +14 -6
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_asr.py +211 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_macos_app.py +30 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.claude/skills/agent-cli-dev/SKILL.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.claude/skills/agent-cli-dev/examples.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.claude-plugin/README.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.claude-plugin/marketplace.json +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.claude-plugin/plugin.json +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.claude-plugin/skills/agent-cli-dev/SKILL.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.claude-plugin/skills/agent-cli-dev/examples.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.cursorrules +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.dockerignore +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.env.example +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/logo.svg +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/release-drafter.yml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/renovate.json +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/scripts/check_extras_sync.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/scripts/check_plugin_skill_sync.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/scripts/normalize_appcast.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/scripts/sync_extras.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/scripts/sync_requirements.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/workflows/automerge.yml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/workflows/docker.yml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/workflows/docs.yml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/workflows/markdown-code-runner.yml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/workflows/pytest.yml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/workflows/release-drafter.yml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/workflows/release.yml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.github/workflows/toc.yaml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.gitignore +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.jscpd.json +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.pre-commit-config.yaml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.prompts/docs-review.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/.prompts/pr-review.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/CLAUDE.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/LICENSE +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/LLAMA_SERVER_USAGE.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/__main__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_extras.json +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_overrides/nemo-whisper.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/.gitkeep +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/audio.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/diarization.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/faster-whisper.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/kokoro.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/llm.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/memory.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/mlx-whisper.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/nemo-whisper.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/piper.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/rag.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/server.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/speed.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/vad.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/vectordb.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/whisper-transformers.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_requirements/wyoming.txt +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/_tools.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/_voice_agent_common.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/assistant.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/autocorrect.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/chat.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/diarize_live_session.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/memory/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/memory/add.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/memory/proxy.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/rag_proxy.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/speak.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/speakers.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/transcribe_live.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/agents/voice_edit.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/api.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/cli.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/config.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/config_cmd.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/constants.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/alignment.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/audio.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/audio_format.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/chroma.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/deps.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/diarization.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/openai_proxy.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/process.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/reranker.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/speaker_identity.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/sse.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/transcription_logger.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/utils.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/vad.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/core/watch.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/daemon/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/daemon/cli.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/_branch_name.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/_config.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/_output.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/cleanup.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/cli.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/aider.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/base.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/claude.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/codex.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/copilot.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/gemini.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/opencode.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/coding_agents/registry.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/base.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/cursor.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/emacs.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/jetbrains.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/nano.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/neovim.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/registry.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/sublime.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/vim.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/vscode.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/editors/zed.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/hooks.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/launch.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/project.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/registry.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/skill/SKILL.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/skill/examples.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/apple_terminal.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/base.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/gnome.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/iterm2.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/kitty.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/registry.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/tmux.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/warp.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/terminals/zellij.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/dev/worktree.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/docs_gen.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/example-config.toml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/install/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/install/common.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/install/extras.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/install/hotkeys.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/install/launchd.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/install/service_config.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/install/services.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/install/systemd.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_files.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_filters.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_git.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_indexer.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_ingest.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_persistence.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_prompt.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_retrieval.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_store.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_streaming.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/_tasks.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/api.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/client.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/engine.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/entities.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/memory/models.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/py.typed +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/_indexer.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/_indexing.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/_prompt.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/_retriever.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/_store.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/_utils.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/api.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/client.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/engine.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/rag/models.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/.runtime/.gitkeep +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/run-openwakeword.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/setup-linux.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/setup-macos.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/setup-windows.ps1 +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/scripts/start-all-services.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/cli.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/common.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/model_manager.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/model_registry.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/proxy/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/proxy/api.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/streaming.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/tts/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/tts/api.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/tts/backends/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/tts/backends/base.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/tts/backends/kokoro.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/tts/backends/piper.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/tts/model_manager.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/tts/model_registry.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/tts/wyoming_handler.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/api.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/backends/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/backends/base.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/backends/mlx.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/backends/nemo.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/backends/transformers.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/languages.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/model_manager.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/model_registry.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/server/whisper/wyoming_handler.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/services/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/services/_wyoming_utils.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/services/llm.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/services/tts.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/agent_cli/services/wake_word.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docker/docker-compose.yml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docker/memory-proxy.Dockerfile +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docker/rag-proxy.Dockerfile +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docker/transcribe-proxy.Dockerfile +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docker/tts.Dockerfile +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docker/whisper.Dockerfile +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/CNAME +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/architecture/index.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/architecture/memory.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/architecture/rag.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/assistant.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/autocorrect.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/chat.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/config.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/daemon.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/dev.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/diarize-live-session.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/index.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/install-extras.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/install-hotkeys.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/install-services.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/memory.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/rag-proxy.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/server/index.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/server/transcribe-proxy.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/server/tts.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/server/whisper.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/speak.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/speakers.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/start-services.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/transcribe-live.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/commands/voice-edit.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/configuration.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/getting-started.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/iOS_Shortcut_Guide.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/index.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/installation/docker.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/installation/index.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/installation/linux.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/installation/macos.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/installation/nixos.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/installation/windows.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/logo-avatar.svg +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/logo-clean.svg +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/run_markdown_code_runner.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/docs/system-integration.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/example.agent-cli-config.toml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/justfile +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Package.resolved +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Package.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/README.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Resources/AgentCLI.entitlements +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Resources/Info.plist +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Resources/dmg-background.svg +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/AgentCLIApp.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/AgentCommandRunner.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/AppMetadata.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/AppUpdater.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/BootstrapState.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/CommandResult.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/FocusedTextTarget.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/LoginItemController.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/MenuActivityStatus.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/MenuActivityStatusRow.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/MenuActivityTracker.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/MenuBarIcon.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/RecentTranscriptionReader.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/RecordingSoundSettings.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/RuntimeSettings.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/SettingsWindowController.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/StatusMenuController.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Sources/AgentCLI/TranscriptPasteController.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Tests/AgentCLITests/ConfigurableHotkeyControllerTests.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Tests/AgentCLITests/LoginItemControllerTests.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Tests/AgentCLITests/RecentTranscriptionReaderTests.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Tests/AgentCLITests/RecordingIndicatorControllerTests.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/AgentCLI/Tests/AgentCLITests/ShortcutDefaultsTests.swift +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/build-macos-app.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/macos/test-macos-app-e2e.sh +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/pyproject.toml +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/reddit.md +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/shell.nix +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_fix_my_text.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_interactive.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_interactive_extra.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_memory_add.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_speak.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_speak_e2e.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_speakers.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_transcribe_agent.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_transcribe_e2e.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_transcribe_live.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_tts_common.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_tts_common_extra.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_voice_agent_common.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_voice_edit.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_voice_edit_e2e.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/agents/test_wake_word_assistant.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/conftest.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/core/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/core/test_audio.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/core/test_audio_format.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/core/test_audio_levels.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/core/test_chroma.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/core/test_sse.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/core/test_vad.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/core/test_watch.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_cleanup.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_cli.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_coding_agents.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_editors.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_hooks.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_launch.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_project.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_terminals.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_verification.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/dev/test_worktree.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/install/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/install/test_extras.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/install/test_launchd.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_api_health.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_api_integration_liveish.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_client.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_engine.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_files.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_filters.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_git_integration.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_indexer.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_memory_integration.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_proxy_passthrough.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_store.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/memory/test_utils.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/mocks/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/mocks/audio.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/mocks/llm.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/mocks/wyoming.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/__init__.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_api.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_engine.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_history.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_indexer.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_indexing.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_rag_client.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_rag_integration_liveish.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_rag_proxy_passthrough.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_retriever.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_store.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/rag/test_utils.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_alignment.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_api.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_api_integration.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_asr_recovery.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_audio_e2e.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_cli.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_config.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_config_cmd.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_daemon.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_diarization.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_diarize_live_session.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_docs_gen.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_env_vars.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_faster_whisper_backend.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_json_output.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_llm.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_llm_gemini.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_memory_tools.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_mlx_backend.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_nemo_backend.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_normalize_appcast.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_process_manager.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_requires_extras.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_server_streaming.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_server_tts.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_server_whisper.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_services.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_speaker_identity.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_tools.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_transformers_backend.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_tts.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_utils.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_wake_word.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/tests/test_wyoming_utils.py +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/uv.lock +0 -0
- {agent_cli-0.98.4 → agent_cli-0.99.0}/zensical.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.99.0
|
|
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>
|
|
@@ -1031,6 +1031,21 @@ the `[defaults]` section of your configuration file.
|
|
|
1031
1031
|
│ provide context for │
|
|
1032
1032
|
│ LLM cleanup. │
|
|
1033
1033
|
╰────────────────────────────────────────────────────────────────────────────────────────╯
|
|
1034
|
+
╭─ Live Preview ─────────────────────────────────────────────────────────────────────────╮
|
|
1035
|
+
│ --live-preview-log PATH Write rolling live transcription │
|
|
1036
|
+
│ preview events to JSONL while │
|
|
1037
|
+
│ recording. │
|
|
1038
|
+
│ --live-preview-interval FLOAT Seconds between live preview │
|
|
1039
|
+
│ retranscriptions. │
|
|
1040
|
+
│ [default: 2.0] │
|
|
1041
|
+
│ --live-preview-window FLOAT Seconds of recent audio to include │
|
|
1042
|
+
│ in each live preview │
|
|
1043
|
+
│ retranscription. │
|
|
1044
|
+
│ [default: 15.0] │
|
|
1045
|
+
│ --live-preview-console,--live-previ… Print rolling live transcription │
|
|
1046
|
+
│ preview updates to the terminal │
|
|
1047
|
+
│ while recording. │
|
|
1048
|
+
╰────────────────────────────────────────────────────────────────────────────────────────╯
|
|
1034
1049
|
╭─ Diarization ──────────────────────────────────────────────────────────────────────────╮
|
|
1035
1050
|
│ --diarize --no-diarize Enable speaker │
|
|
1036
1051
|
│ diarization │
|
|
@@ -923,6 +923,21 @@ the `[defaults]` section of your configuration file.
|
|
|
923
923
|
│ provide context for │
|
|
924
924
|
│ LLM cleanup. │
|
|
925
925
|
╰────────────────────────────────────────────────────────────────────────────────────────╯
|
|
926
|
+
╭─ Live Preview ─────────────────────────────────────────────────────────────────────────╮
|
|
927
|
+
│ --live-preview-log PATH Write rolling live transcription │
|
|
928
|
+
│ preview events to JSONL while │
|
|
929
|
+
│ recording. │
|
|
930
|
+
│ --live-preview-interval FLOAT Seconds between live preview │
|
|
931
|
+
│ retranscriptions. │
|
|
932
|
+
│ [default: 2.0] │
|
|
933
|
+
│ --live-preview-window FLOAT Seconds of recent audio to include │
|
|
934
|
+
│ in each live preview │
|
|
935
|
+
│ retranscription. │
|
|
936
|
+
│ [default: 15.0] │
|
|
937
|
+
│ --live-preview-console,--live-previ… Print rolling live transcription │
|
|
938
|
+
│ preview updates to the terminal │
|
|
939
|
+
│ while recording. │
|
|
940
|
+
╰────────────────────────────────────────────────────────────────────────────────────────╯
|
|
926
941
|
╭─ Diarization ──────────────────────────────────────────────────────────────────────────╮
|
|
927
942
|
│ --diarize --no-diarize Enable speaker │
|
|
928
943
|
│ diarization │
|
|
@@ -365,13 +365,20 @@ async def _async_main( # noqa: PLR0912, PLR0915, C901
|
|
|
365
365
|
emit_output: bool = True,
|
|
366
366
|
raise_diarization_errors: bool = False,
|
|
367
367
|
audio_level_callback: Callable[[bytes], None] | None = None,
|
|
368
|
+
live_preview_log: Path | None = None,
|
|
369
|
+
live_preview_interval: float = 2.0,
|
|
370
|
+
live_preview_window: float = 15.0,
|
|
371
|
+
live_preview_console: bool = False,
|
|
368
372
|
) -> TranscriptResult:
|
|
369
373
|
"""Unified async entry point for both live and file-based transcription."""
|
|
370
374
|
start_time = time.monotonic()
|
|
371
375
|
transcript: str | None
|
|
372
376
|
saved_recording_path: Path | None = None
|
|
377
|
+
live_preview_console_active = (
|
|
378
|
+
live_preview_console and audio_file_path is None and provider_cfg.asr_provider == "wyoming"
|
|
379
|
+
)
|
|
373
380
|
|
|
374
|
-
with maybe_live(not general_cfg.quiet) as live:
|
|
381
|
+
with maybe_live(not general_cfg.quiet and not live_preview_console_active) as live:
|
|
375
382
|
if audio_file_path:
|
|
376
383
|
# File-based transcription
|
|
377
384
|
# Determine if we can use native format support (skip PCM conversion)
|
|
@@ -447,6 +454,17 @@ async def _async_main( # noqa: PLR0912, PLR0915, C901
|
|
|
447
454
|
openai_asr_cfg,
|
|
448
455
|
gemini_asr_cfg,
|
|
449
456
|
)
|
|
457
|
+
live_preview_config = (
|
|
458
|
+
asr.LivePreviewConfig(
|
|
459
|
+
log_file=live_preview_log,
|
|
460
|
+
interval_seconds=live_preview_interval,
|
|
461
|
+
window_seconds=live_preview_window,
|
|
462
|
+
console=live_preview_console,
|
|
463
|
+
)
|
|
464
|
+
if (live_preview_log or live_preview_console)
|
|
465
|
+
and provider_cfg.asr_provider == "wyoming"
|
|
466
|
+
else None
|
|
467
|
+
)
|
|
450
468
|
transcript = await live_transcriber(
|
|
451
469
|
logger=LOGGER,
|
|
452
470
|
stop_event=stop_event,
|
|
@@ -456,6 +474,7 @@ async def _async_main( # noqa: PLR0912, PLR0915, C901
|
|
|
456
474
|
extra_instructions=extra_instructions,
|
|
457
475
|
recording_path_callback=_set_saved_recording_path,
|
|
458
476
|
audio_level_callback=audio_level_callback,
|
|
477
|
+
live_preview_config=live_preview_config,
|
|
459
478
|
)
|
|
460
479
|
|
|
461
480
|
elapsed = time.monotonic() - start_time
|
|
@@ -650,6 +669,10 @@ def transcribe( # noqa: PLR0912, PLR0911, PLR0915, C901
|
|
|
650
669
|
print_args: bool = opts.PRINT_ARGS,
|
|
651
670
|
transcription_log: Path | None = opts.TRANSCRIPTION_LOG,
|
|
652
671
|
voice_level_log: Path | None = opts.VOICE_LEVEL_LOG,
|
|
672
|
+
live_preview_log: Path | None = opts.LIVE_PREVIEW_LOG,
|
|
673
|
+
live_preview_interval: float = opts.LIVE_PREVIEW_INTERVAL,
|
|
674
|
+
live_preview_window: float = opts.LIVE_PREVIEW_WINDOW,
|
|
675
|
+
live_preview_console: bool = opts.LIVE_PREVIEW_CONSOLE,
|
|
653
676
|
# --- Diarization Options ---
|
|
654
677
|
diarize: bool = opts.DIARIZE,
|
|
655
678
|
diarize_format: opts.DiarizeFormat = opts.DIARIZE_FORMAT,
|
|
@@ -697,18 +720,24 @@ def transcribe( # noqa: PLR0912, PLR0911, PLR0915, C901
|
|
|
697
720
|
|
|
698
721
|
setup_logging(log_level, log_file, quiet=effective_quiet)
|
|
699
722
|
|
|
723
|
+
enroll_speakers = _option_default(enroll_speakers)
|
|
724
|
+
identify_speakers = _option_default(identify_speakers)
|
|
725
|
+
remember_unknown_speakers = _option_default(remember_unknown_speakers)
|
|
726
|
+
speaker_profiles_file = _option_default(speaker_profiles_file)
|
|
727
|
+
speaker_match_threshold = _option_default(speaker_match_threshold)
|
|
728
|
+
live_preview_log = _option_default(live_preview_log)
|
|
729
|
+
live_preview_interval = _option_default(live_preview_interval)
|
|
730
|
+
live_preview_window = _option_default(live_preview_window)
|
|
731
|
+
live_preview_console = _option_default(live_preview_console)
|
|
732
|
+
|
|
700
733
|
# Expand user path for transcription log
|
|
701
734
|
if transcription_log:
|
|
702
735
|
transcription_log = transcription_log.expanduser()
|
|
703
736
|
voice_level_log = _option_default(voice_level_log)
|
|
704
737
|
if voice_level_log:
|
|
705
738
|
voice_level_log = voice_level_log.expanduser()
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
identify_speakers = _option_default(identify_speakers)
|
|
709
|
-
remember_unknown_speakers = _option_default(remember_unknown_speakers)
|
|
710
|
-
speaker_profiles_file = _option_default(speaker_profiles_file)
|
|
711
|
-
speaker_match_threshold = _option_default(speaker_match_threshold)
|
|
739
|
+
if live_preview_log:
|
|
740
|
+
live_preview_log = live_preview_log.expanduser()
|
|
712
741
|
|
|
713
742
|
# Validate diarization options
|
|
714
743
|
if not diarize and (enroll_speakers or remember_unknown_speakers):
|
|
@@ -850,6 +879,10 @@ def transcribe( # noqa: PLR0912, PLR0911, PLR0915, C901
|
|
|
850
879
|
diarization_cfg=diarization_cfg,
|
|
851
880
|
emit_output=not json_output,
|
|
852
881
|
raise_diarization_errors=diarize,
|
|
882
|
+
live_preview_log=live_preview_log,
|
|
883
|
+
live_preview_interval=live_preview_interval,
|
|
884
|
+
live_preview_window=live_preview_window,
|
|
885
|
+
live_preview_console=live_preview_console,
|
|
853
886
|
),
|
|
854
887
|
)
|
|
855
888
|
except ImportError as exc:
|
|
@@ -942,6 +975,10 @@ def transcribe( # noqa: PLR0912, PLR0911, PLR0915, C901
|
|
|
942
975
|
audio_level_callback=audio_level_writer.write_chunk
|
|
943
976
|
if audio_level_writer
|
|
944
977
|
else None,
|
|
978
|
+
live_preview_log=live_preview_log,
|
|
979
|
+
live_preview_interval=live_preview_interval,
|
|
980
|
+
live_preview_window=live_preview_window,
|
|
981
|
+
live_preview_console=live_preview_console,
|
|
945
982
|
),
|
|
946
983
|
)
|
|
947
984
|
except ImportError as exc:
|
|
@@ -436,6 +436,31 @@ VOICE_LEVEL_LOG: Path | None = typer.Option(
|
|
|
436
436
|
hidden=True,
|
|
437
437
|
rich_help_panel="General Options",
|
|
438
438
|
)
|
|
439
|
+
LIVE_PREVIEW_LOG: Path | None = typer.Option(
|
|
440
|
+
None,
|
|
441
|
+
"--live-preview-log",
|
|
442
|
+
help="Write rolling live transcription preview events to JSONL while recording.",
|
|
443
|
+
rich_help_panel="Live Preview",
|
|
444
|
+
)
|
|
445
|
+
LIVE_PREVIEW_INTERVAL: float = typer.Option(
|
|
446
|
+
2.0,
|
|
447
|
+
"--live-preview-interval",
|
|
448
|
+
help="Seconds between live preview retranscriptions.",
|
|
449
|
+
rich_help_panel="Live Preview",
|
|
450
|
+
)
|
|
451
|
+
LIVE_PREVIEW_WINDOW: float = typer.Option(
|
|
452
|
+
15.0,
|
|
453
|
+
"--live-preview-window",
|
|
454
|
+
help="Seconds of recent audio to include in each live preview retranscription.",
|
|
455
|
+
rich_help_panel="Live Preview",
|
|
456
|
+
)
|
|
457
|
+
LIVE_PREVIEW_CONSOLE: bool = typer.Option(
|
|
458
|
+
False, # noqa: FBT003
|
|
459
|
+
"--live-preview-console",
|
|
460
|
+
"--live-preview-stdout",
|
|
461
|
+
help="Print rolling live transcription preview updates to the terminal while recording.",
|
|
462
|
+
rich_help_panel="Live Preview",
|
|
463
|
+
)
|
|
439
464
|
|
|
440
465
|
# --- Server Options ---
|
|
441
466
|
SERVER_HOST: str = typer.Option(
|
|
@@ -4,7 +4,10 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import io
|
|
7
|
+
import json
|
|
7
8
|
import wave
|
|
9
|
+
from contextlib import suppress
|
|
10
|
+
from dataclasses import dataclass
|
|
8
11
|
from datetime import UTC, datetime
|
|
9
12
|
from functools import partial
|
|
10
13
|
from pathlib import Path
|
|
@@ -18,7 +21,7 @@ from agent_cli.core.audio import (
|
|
|
18
21
|
setup_input_stream,
|
|
19
22
|
)
|
|
20
23
|
from agent_cli.core.audio_format import check_ffmpeg_available, convert_audio_to_wyoming_format
|
|
21
|
-
from agent_cli.core.utils import manage_send_receive_tasks
|
|
24
|
+
from agent_cli.core.utils import err_console, manage_send_receive_tasks
|
|
22
25
|
from agent_cli.services import (
|
|
23
26
|
transcribe_audio_gemini,
|
|
24
27
|
transcribe_audio_openai,
|
|
@@ -37,6 +40,176 @@ if TYPE_CHECKING:
|
|
|
37
40
|
from agent_cli.core.utils import InteractiveStopEvent
|
|
38
41
|
|
|
39
42
|
|
|
43
|
+
@dataclass(frozen=True)
|
|
44
|
+
class LivePreviewConfig:
|
|
45
|
+
"""Configuration for rolling transcription previews."""
|
|
46
|
+
|
|
47
|
+
log_file: Path | None = None
|
|
48
|
+
interval_seconds: float = 2.0
|
|
49
|
+
window_seconds: float = 15.0
|
|
50
|
+
min_audio_seconds: float = 1.0
|
|
51
|
+
console: bool = False
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def max_audio_bytes(self) -> int:
|
|
55
|
+
"""Maximum number of PCM bytes to keep in the rolling preview window."""
|
|
56
|
+
return int(
|
|
57
|
+
self.window_seconds
|
|
58
|
+
* constants.AUDIO_RATE
|
|
59
|
+
* constants.AUDIO_CHANNELS
|
|
60
|
+
* constants.AUDIO_FORMAT_WIDTH,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def min_audio_bytes(self) -> int:
|
|
65
|
+
"""Minimum number of PCM bytes before attempting a preview."""
|
|
66
|
+
return int(
|
|
67
|
+
self.min_audio_seconds
|
|
68
|
+
* constants.AUDIO_RATE
|
|
69
|
+
* constants.AUDIO_CHANNELS
|
|
70
|
+
* constants.AUDIO_FORMAT_WIDTH,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _write_live_preview_event(
|
|
75
|
+
log_file: Path,
|
|
76
|
+
*,
|
|
77
|
+
event_type: str,
|
|
78
|
+
revision: int,
|
|
79
|
+
text: str,
|
|
80
|
+
) -> None:
|
|
81
|
+
"""Append one live preview event to a JSONL log."""
|
|
82
|
+
entry = {
|
|
83
|
+
"timestamp": datetime.now(UTC).isoformat(),
|
|
84
|
+
"type": event_type,
|
|
85
|
+
"revision": revision,
|
|
86
|
+
"text": text,
|
|
87
|
+
"is_final": event_type == "final",
|
|
88
|
+
}
|
|
89
|
+
log_file.parent.mkdir(parents=True, exist_ok=True)
|
|
90
|
+
with log_file.open("a", encoding="utf-8") as f:
|
|
91
|
+
f.write(json.dumps(entry, ensure_ascii=False) + "\n")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _print_live_preview_event(
|
|
95
|
+
*,
|
|
96
|
+
event_type: str,
|
|
97
|
+
revision: int,
|
|
98
|
+
text: str,
|
|
99
|
+
) -> None:
|
|
100
|
+
"""Print one live preview event to the terminal."""
|
|
101
|
+
label = "final" if event_type == "final" else f"live #{revision}"
|
|
102
|
+
err_console.print(f"[dim]{label}:[/dim] {text}")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class LivePreviewStreamer:
|
|
106
|
+
"""Periodically transcribe a rolling audio window and write preview events."""
|
|
107
|
+
|
|
108
|
+
def __init__(
|
|
109
|
+
self,
|
|
110
|
+
preview_config: LivePreviewConfig,
|
|
111
|
+
*,
|
|
112
|
+
wyoming_asr_cfg: config.WyomingASR,
|
|
113
|
+
logger: logging.Logger,
|
|
114
|
+
extra_instructions: str | None = None,
|
|
115
|
+
) -> None:
|
|
116
|
+
"""Initialize the preview streamer."""
|
|
117
|
+
self.config = preview_config
|
|
118
|
+
self.wyoming_asr_cfg = wyoming_asr_cfg
|
|
119
|
+
self.logger = logger
|
|
120
|
+
self.extra_instructions = extra_instructions
|
|
121
|
+
self._audio = bytearray()
|
|
122
|
+
self._lock = asyncio.Lock()
|
|
123
|
+
self._stop_event = asyncio.Event()
|
|
124
|
+
self._revision = 0
|
|
125
|
+
self._last_text = ""
|
|
126
|
+
|
|
127
|
+
def reset_log(self) -> None:
|
|
128
|
+
"""Clear the preview log for a new recording session."""
|
|
129
|
+
if self.config.log_file is None:
|
|
130
|
+
return
|
|
131
|
+
self.config.log_file.parent.mkdir(parents=True, exist_ok=True)
|
|
132
|
+
self.config.log_file.write_text("", encoding="utf-8")
|
|
133
|
+
|
|
134
|
+
async def add_chunk(self, chunk: bytes) -> None:
|
|
135
|
+
"""Add a microphone audio chunk to the rolling preview buffer."""
|
|
136
|
+
async with self._lock:
|
|
137
|
+
self._audio.extend(chunk)
|
|
138
|
+
max_bytes = max(0, self.config.max_audio_bytes)
|
|
139
|
+
if max_bytes and len(self._audio) > max_bytes:
|
|
140
|
+
del self._audio[: len(self._audio) - max_bytes]
|
|
141
|
+
|
|
142
|
+
async def run(self) -> None:
|
|
143
|
+
"""Run the periodic preview loop until stopped."""
|
|
144
|
+
while not self._stop_event.is_set():
|
|
145
|
+
try:
|
|
146
|
+
await asyncio.wait_for(self._stop_event.wait(), self.config.interval_seconds)
|
|
147
|
+
break
|
|
148
|
+
except TimeoutError:
|
|
149
|
+
pass
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
await self.emit_partial()
|
|
153
|
+
except asyncio.CancelledError:
|
|
154
|
+
raise
|
|
155
|
+
except Exception:
|
|
156
|
+
self.logger.exception("Live transcription preview failed")
|
|
157
|
+
|
|
158
|
+
async def emit_partial(self) -> None:
|
|
159
|
+
"""Transcribe the current rolling window and write a partial if changed."""
|
|
160
|
+
snapshot = await self._audio_snapshot()
|
|
161
|
+
if len(snapshot) < self.config.min_audio_bytes:
|
|
162
|
+
return
|
|
163
|
+
|
|
164
|
+
text = await _transcribe_recorded_audio_wyoming(
|
|
165
|
+
audio_data=snapshot,
|
|
166
|
+
wyoming_asr_cfg=self.wyoming_asr_cfg,
|
|
167
|
+
logger=self.logger,
|
|
168
|
+
quiet=True,
|
|
169
|
+
extra_instructions=self.extra_instructions,
|
|
170
|
+
)
|
|
171
|
+
text = text.strip()
|
|
172
|
+
if not text or text == self._last_text:
|
|
173
|
+
return
|
|
174
|
+
if self._stop_event.is_set():
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
self._revision += 1
|
|
178
|
+
self._last_text = text
|
|
179
|
+
self._publish_event(event_type="partial", revision=self._revision, text=text)
|
|
180
|
+
|
|
181
|
+
def request_stop(self) -> None:
|
|
182
|
+
"""Stop partial preview emission without writing the final transcript."""
|
|
183
|
+
self._stop_event.set()
|
|
184
|
+
|
|
185
|
+
async def stop(self, final_text: str | None = None) -> None:
|
|
186
|
+
"""Stop previewing and optionally append the final transcript."""
|
|
187
|
+
self.request_stop()
|
|
188
|
+
final_text = (final_text or "").strip()
|
|
189
|
+
if final_text:
|
|
190
|
+
self._revision += 1
|
|
191
|
+
self._publish_event(event_type="final", revision=self._revision, text=final_text)
|
|
192
|
+
|
|
193
|
+
def _publish_event(self, *, event_type: str, revision: int, text: str) -> None:
|
|
194
|
+
if self.config.log_file is not None:
|
|
195
|
+
_write_live_preview_event(
|
|
196
|
+
self.config.log_file,
|
|
197
|
+
event_type=event_type,
|
|
198
|
+
revision=revision,
|
|
199
|
+
text=text,
|
|
200
|
+
)
|
|
201
|
+
if self.config.console:
|
|
202
|
+
_print_live_preview_event(
|
|
203
|
+
event_type=event_type,
|
|
204
|
+
revision=revision,
|
|
205
|
+
text=text,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
async def _audio_snapshot(self) -> bytes:
|
|
209
|
+
async with self._lock:
|
|
210
|
+
return bytes(self._audio)
|
|
211
|
+
|
|
212
|
+
|
|
40
213
|
def _get_transcriptions_dir() -> Path:
|
|
41
214
|
"""Get the directory for storing transcription recordings."""
|
|
42
215
|
config_dir = Path.home() / ".config" / "agent-cli" / "transcriptions"
|
|
@@ -247,6 +420,7 @@ async def _send_audio(
|
|
|
247
420
|
initial_prompt: str | None = None,
|
|
248
421
|
recording_path_callback: Callable[[Path], None] | None = None,
|
|
249
422
|
audio_level_callback: Callable[[bytes], None] | None = None,
|
|
423
|
+
live_preview_callback: Callable[[bytes], Awaitable[None]] | None = None,
|
|
250
424
|
) -> None:
|
|
251
425
|
"""Read from mic and send to Wyoming server."""
|
|
252
426
|
from wyoming.asr import Transcribe # noqa: PLC0415
|
|
@@ -272,6 +446,8 @@ async def _send_audio(
|
|
|
272
446
|
chunk,
|
|
273
447
|
logger,
|
|
274
448
|
)
|
|
449
|
+
if live_preview_callback is not None:
|
|
450
|
+
await live_preview_callback(chunk)
|
|
275
451
|
await client.write_event(AudioChunk(audio=chunk, **constants.WYOMING_AUDIO_CONFIG).event())
|
|
276
452
|
|
|
277
453
|
try:
|
|
@@ -482,9 +658,22 @@ async def _transcribe_live_audio_wyoming(
|
|
|
482
658
|
extra_instructions: str | None = None,
|
|
483
659
|
recording_path_callback: Callable[[Path], None] | None = None,
|
|
484
660
|
audio_level_callback: Callable[[bytes], None] | None = None,
|
|
661
|
+
live_preview_config: LivePreviewConfig | None = None,
|
|
485
662
|
**_kwargs: object,
|
|
486
663
|
) -> str | None:
|
|
487
664
|
"""Unified ASR transcription function."""
|
|
665
|
+
live_preview = (
|
|
666
|
+
LivePreviewStreamer(
|
|
667
|
+
live_preview_config,
|
|
668
|
+
wyoming_asr_cfg=wyoming_asr_cfg,
|
|
669
|
+
logger=logger,
|
|
670
|
+
extra_instructions=extra_instructions,
|
|
671
|
+
)
|
|
672
|
+
if live_preview_config is not None
|
|
673
|
+
else None
|
|
674
|
+
)
|
|
675
|
+
live_preview_task: asyncio.Task[None] | None = None
|
|
676
|
+
final_transcript: str | None = None
|
|
488
677
|
try:
|
|
489
678
|
async with wyoming_client_context(
|
|
490
679
|
wyoming_asr_cfg.asr_wyoming_ip,
|
|
@@ -500,6 +689,9 @@ async def _transcribe_live_audio_wyoming(
|
|
|
500
689
|
|
|
501
690
|
stream_config = setup_input_stream(audio_input_cfg.input_device_index)
|
|
502
691
|
with open_audio_stream(stream_config) as stream:
|
|
692
|
+
if live_preview is not None:
|
|
693
|
+
live_preview.reset_log()
|
|
694
|
+
live_preview_task = asyncio.create_task(live_preview.run())
|
|
503
695
|
_, recv_task = await manage_send_receive_tasks(
|
|
504
696
|
_send_audio(
|
|
505
697
|
client,
|
|
@@ -512,6 +704,7 @@ async def _transcribe_live_audio_wyoming(
|
|
|
512
704
|
initial_prompt=effective_prompt,
|
|
513
705
|
recording_path_callback=recording_path_callback,
|
|
514
706
|
audio_level_callback=audio_level_callback,
|
|
707
|
+
live_preview_callback=live_preview.add_chunk if live_preview else None,
|
|
515
708
|
),
|
|
516
709
|
_receive_transcript(
|
|
517
710
|
client,
|
|
@@ -521,10 +714,21 @@ async def _transcribe_live_audio_wyoming(
|
|
|
521
714
|
),
|
|
522
715
|
return_when=asyncio.ALL_COMPLETED,
|
|
523
716
|
)
|
|
524
|
-
|
|
717
|
+
result = recv_task.result()
|
|
718
|
+
final_transcript = result
|
|
719
|
+
return result
|
|
525
720
|
except (ConnectionRefusedError, Exception):
|
|
526
721
|
logger.warning("Failed to connect to Wyoming ASR server")
|
|
527
722
|
return None
|
|
723
|
+
finally:
|
|
724
|
+
if live_preview is not None:
|
|
725
|
+
live_preview.request_stop()
|
|
726
|
+
if live_preview_task is not None:
|
|
727
|
+
live_preview_task.cancel()
|
|
728
|
+
with suppress(asyncio.CancelledError):
|
|
729
|
+
await live_preview_task
|
|
730
|
+
if live_preview is not None:
|
|
731
|
+
await live_preview.stop(final_transcript)
|
|
528
732
|
|
|
529
733
|
|
|
530
734
|
async def _transcribe_live_audio_buffered(
|
|
@@ -187,6 +187,15 @@ The `--from-file` option supports multiple audio formats:
|
|
|
187
187
|
| `--print-args` | `false` | Print the command line arguments, including variables taken from the configuration file. |
|
|
188
188
|
| `--transcription-log` | - | Append transcripts to JSONL file (timestamp, hostname, model, raw/processed text). Recent entries provide context for LLM cleanup. |
|
|
189
189
|
|
|
190
|
+
### Live Preview
|
|
191
|
+
|
|
192
|
+
| Option | Default | Description |
|
|
193
|
+
|--------|---------|-------------|
|
|
194
|
+
| `--live-preview-log` | - | Write rolling live transcription preview events to JSONL while recording. |
|
|
195
|
+
| `--live-preview-interval` | `2.0` | Seconds between live preview retranscriptions. |
|
|
196
|
+
| `--live-preview-window` | `15.0` | Seconds of recent audio to include in each live preview retranscription. |
|
|
197
|
+
| `--live-preview-console, --live-preview-stdout` | `false` | Print rolling live transcription preview updates to the terminal while recording. |
|
|
198
|
+
|
|
190
199
|
### Diarization
|
|
191
200
|
|
|
192
201
|
| Option | Default | Description |
|
|
@@ -227,6 +236,19 @@ agent-cli transcribe --toggle
|
|
|
227
236
|
cmd + shift + r : /path/to/agent-cli transcribe --toggle --input-device-index 1
|
|
228
237
|
```
|
|
229
238
|
|
|
239
|
+
### Live Preview
|
|
240
|
+
|
|
241
|
+
Use live preview options when another UI should display provisional transcription text during a recording. The transcriber periodically reprocesses the most recent audio window, so preview text can rewrite earlier words until the final transcription is ready.
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
agent-cli transcribe --toggle \
|
|
245
|
+
--live-preview-log ~/.config/agent-cli/live-preview.jsonl \
|
|
246
|
+
--live-preview-interval 1 \
|
|
247
|
+
--live-preview-window 10
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
For terminal testing, add `--live-preview-console` to print each rolling update while recording. The macOS menu bar app uses the JSONL log when **Show Live Transcription Preview** is enabled in Settings; that setting is off by default.
|
|
251
|
+
|
|
230
252
|
### Transcription Log
|
|
231
253
|
|
|
232
254
|
Log all transcriptions with timestamps:
|
|
@@ -45,6 +45,12 @@ The first transcription can take longer because AgentCLI installs the private CL
|
|
|
45
45
|
|
|
46
46
|
Open **Settings...** from the menu bar app to change shortcuts, enable **Start at Login**, or switch runtime modes.
|
|
47
47
|
|
|
48
|
+
## Live Transcription Preview
|
|
49
|
+
|
|
50
|
+
The menu bar app can show provisional transcription text above the recording meter while you speak. Enable **Show Live Transcription Preview** in **Settings...** to turn it on.
|
|
51
|
+
|
|
52
|
+
This setting is off by default. When enabled, AgentCLI writes rolling preview events to `~/.config/agent-cli/live-preview.jsonl` and updates the overlay during toggle or hold-to-transcribe recordings. Preview text is best-effort and may revise earlier words as more audio arrives; the final transcript is still produced and inserted after recording stops.
|
|
53
|
+
|
|
48
54
|
## Runtime Modes
|
|
49
55
|
|
|
50
56
|
By default, the app manages its own private `agent-cli` install so the menu bar workflow is zero-config and does not depend on your shell PATH.
|
|
@@ -19,6 +19,7 @@ struct AgentCommand {
|
|
|
19
19
|
let forceBootstrap: Bool
|
|
20
20
|
let bootstrapRequirement: AgentBootstrapRequirement
|
|
21
21
|
let showsRecordingIndicator: Bool
|
|
22
|
+
let supportsLivePreviewOverlay: Bool
|
|
22
23
|
let startNotificationTitle: String?
|
|
23
24
|
let startNotificationBody: String?
|
|
24
25
|
let finishNotificationTitle: String?
|
|
@@ -32,6 +33,7 @@ struct AgentCommand {
|
|
|
32
33
|
forceBootstrap: Bool = false,
|
|
33
34
|
bootstrapRequirement: AgentBootstrapRequirement = .cliRuntime,
|
|
34
35
|
showsRecordingIndicator: Bool = false,
|
|
36
|
+
supportsLivePreviewOverlay: Bool = false,
|
|
35
37
|
startNotificationTitle: String? = nil,
|
|
36
38
|
startNotificationBody: String? = nil,
|
|
37
39
|
finishNotificationTitle: String? = nil
|
|
@@ -44,6 +46,7 @@ struct AgentCommand {
|
|
|
44
46
|
self.forceBootstrap = forceBootstrap
|
|
45
47
|
self.bootstrapRequirement = bootstrapRequirement
|
|
46
48
|
self.showsRecordingIndicator = showsRecordingIndicator
|
|
49
|
+
self.supportsLivePreviewOverlay = supportsLivePreviewOverlay
|
|
47
50
|
self.startNotificationTitle = startNotificationTitle
|
|
48
51
|
self.startNotificationBody = startNotificationBody
|
|
49
52
|
self.finishNotificationTitle = finishNotificationTitle
|
|
@@ -51,18 +54,32 @@ struct AgentCommand {
|
|
|
51
54
|
|
|
52
55
|
func resolvedArguments(
|
|
53
56
|
extraInstructions: String?,
|
|
57
|
+
livePreviewOverlayEnabled: Bool = TranscriptionSettings.isLivePreviewOverlayEnabled(),
|
|
54
58
|
transcriptionDaemonArguments: [String]? = nil
|
|
55
59
|
) -> [String] {
|
|
56
60
|
if appliesTranscriptionDaemonSettings {
|
|
57
61
|
return transcriptionDaemonArguments ?? arguments
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
|
|
64
|
+
var resolved = arguments
|
|
65
|
+
|
|
66
|
+
if supportsLivePreviewOverlay && livePreviewOverlayEnabled {
|
|
67
|
+
resolved += [
|
|
68
|
+
"--live-preview-log",
|
|
69
|
+
LiveTranscriptionPreview.defaultLogPath,
|
|
70
|
+
"--live-preview-interval",
|
|
71
|
+
"1",
|
|
72
|
+
"--live-preview-window",
|
|
73
|
+
"10",
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
guard appliesTranscriptionExtraInstructions else { return resolved }
|
|
61
78
|
|
|
62
79
|
let trimmedInstructions = extraInstructions?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
|
63
|
-
guard !trimmedInstructions.isVisiblyBlank else { return
|
|
80
|
+
guard !trimmedInstructions.isVisiblyBlank else { return resolved }
|
|
64
81
|
|
|
65
|
-
return
|
|
82
|
+
return resolved + ["--extra-instructions", trimmedInstructions]
|
|
66
83
|
}
|
|
67
84
|
|
|
68
85
|
var menuActivityTitle: String {
|
|
@@ -84,6 +101,7 @@ struct AgentCommand {
|
|
|
84
101
|
appliesTranscriptionExtraInstructions: true,
|
|
85
102
|
bootstrapRequirement: .transcription,
|
|
86
103
|
showsRecordingIndicator: true,
|
|
104
|
+
supportsLivePreviewOverlay: true,
|
|
87
105
|
startNotificationTitle: "Transcription Started",
|
|
88
106
|
startNotificationBody: "Recording audio. Toggle transcription again to stop and transcribe.",
|
|
89
107
|
finishNotificationTitle: "Transcription Finished"
|