agent-cli 0.70.2__py3-none-any.whl → 0.72.1__py3-none-any.whl
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/_extras.json +4 -3
- agent_cli/_requirements/memory.txt +14 -1
- agent_cli/_requirements/rag.txt +14 -1
- agent_cli/_requirements/vad.txt +1 -85
- agent_cli/_requirements/wyoming.txt +71 -0
- agent_cli/agents/assistant.py +24 -28
- agent_cli/agents/autocorrect.py +30 -4
- agent_cli/agents/chat.py +45 -15
- agent_cli/agents/memory/__init__.py +19 -1
- agent_cli/agents/memory/add.py +3 -3
- agent_cli/agents/memory/proxy.py +20 -11
- agent_cli/agents/rag_proxy.py +42 -10
- agent_cli/agents/speak.py +23 -3
- agent_cli/agents/transcribe.py +21 -3
- agent_cli/agents/transcribe_daemon.py +34 -22
- agent_cli/agents/voice_edit.py +18 -10
- agent_cli/cli.py +25 -2
- agent_cli/config_cmd.py +30 -11
- agent_cli/core/deps.py +6 -3
- agent_cli/core/transcription_logger.py +1 -1
- agent_cli/core/vad.py +6 -24
- agent_cli/dev/cli.py +295 -65
- agent_cli/docs_gen.py +18 -8
- agent_cli/install/extras.py +44 -13
- agent_cli/install/hotkeys.py +22 -11
- agent_cli/install/services.py +54 -14
- agent_cli/opts.py +43 -22
- agent_cli/server/cli.py +128 -62
- agent_cli/server/proxy/api.py +77 -19
- agent_cli/services/__init__.py +46 -5
- {agent_cli-0.70.2.dist-info → agent_cli-0.72.1.dist-info}/METADATA +627 -246
- {agent_cli-0.70.2.dist-info → agent_cli-0.72.1.dist-info}/RECORD +35 -34
- {agent_cli-0.70.2.dist-info → agent_cli-0.72.1.dist-info}/WHEEL +0 -0
- {agent_cli-0.70.2.dist-info → agent_cli-0.72.1.dist-info}/entry_points.txt +0 -0
- {agent_cli-0.70.2.dist-info → agent_cli-0.72.1.dist-info}/licenses/LICENSE +0 -0
agent_cli/install/extras.py
CHANGED
|
@@ -14,7 +14,7 @@ import typer
|
|
|
14
14
|
|
|
15
15
|
from agent_cli.cli import app
|
|
16
16
|
from agent_cli.core.deps import EXTRAS as _EXTRAS_META
|
|
17
|
-
from agent_cli.core.utils import console, print_error_message
|
|
17
|
+
from agent_cli.core.utils import console, err_console, print_error_message
|
|
18
18
|
|
|
19
19
|
# Extract descriptions from the centralized EXTRAS metadata
|
|
20
20
|
EXTRAS: dict[str, str] = {name: desc for name, (desc, _) in _EXTRAS_META.items()}
|
|
@@ -69,7 +69,8 @@ def _install_via_uv_tool(extras: list[str], *, quiet: bool = False) -> bool:
|
|
|
69
69
|
cmd = ["uv", "tool", "install", package_spec, "--force", "--python", python_version]
|
|
70
70
|
if quiet:
|
|
71
71
|
cmd.append("-q")
|
|
72
|
-
|
|
72
|
+
# Use stderr for status messages so they don't pollute stdout (e.g., for hotkey notifications)
|
|
73
|
+
err_console.print(f"Running: [cyan]{' '.join(cmd)}[/]")
|
|
73
74
|
result = subprocess.run(cmd, check=False)
|
|
74
75
|
return result.returncode == 0
|
|
75
76
|
|
|
@@ -118,29 +119,59 @@ def install_extras_programmatic(extras: list[str], *, quiet: bool = False) -> bo
|
|
|
118
119
|
valid = [e for e in extras if e in available]
|
|
119
120
|
invalid = [e for e in extras if e not in available]
|
|
120
121
|
if invalid:
|
|
121
|
-
|
|
122
|
+
# Use stderr so warning doesn't pollute stdout (e.g., for hotkey notifications)
|
|
123
|
+
err_console.print(f"[yellow]Unknown extras (skipped): {', '.join(invalid)}[/]")
|
|
122
124
|
return bool(valid) and _install_extras_impl(valid, quiet=quiet)
|
|
123
125
|
|
|
124
126
|
|
|
125
127
|
@app.command("install-extras", rich_help_panel="Installation", no_args_is_help=True)
|
|
126
128
|
def install_extras(
|
|
127
|
-
extras: Annotated[
|
|
129
|
+
extras: Annotated[
|
|
130
|
+
list[str] | None,
|
|
131
|
+
typer.Argument(
|
|
132
|
+
help="Extras to install: `rag`, `memory`, `vad`, `audio`, `piper`, `kokoro`, "
|
|
133
|
+
"`faster-whisper`, `mlx-whisper`, `wyoming`, `server`, `speed`, `llm`",
|
|
134
|
+
),
|
|
135
|
+
] = None,
|
|
128
136
|
list_extras: Annotated[
|
|
129
137
|
bool,
|
|
130
|
-
typer.Option(
|
|
138
|
+
typer.Option(
|
|
139
|
+
"--list",
|
|
140
|
+
"-l",
|
|
141
|
+
help="Show available extras with descriptions (what each one enables)",
|
|
142
|
+
),
|
|
131
143
|
] = False,
|
|
132
144
|
all_extras: Annotated[
|
|
133
145
|
bool,
|
|
134
|
-
typer.Option("--all", "-a", help="Install all available extras"),
|
|
146
|
+
typer.Option("--all", "-a", help="Install all available extras at once"),
|
|
135
147
|
] = False,
|
|
136
148
|
) -> None:
|
|
137
|
-
"""Install optional
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
149
|
+
"""Install optional dependencies with pinned, compatible versions.
|
|
150
|
+
|
|
151
|
+
Many agent-cli features require optional dependencies. This command installs
|
|
152
|
+
them with version pinning to ensure compatibility. Dependencies persist
|
|
153
|
+
across `uv tool upgrade` when installed via `uv tool`.
|
|
154
|
+
|
|
155
|
+
**Available extras:**
|
|
156
|
+
- `rag` - RAG proxy server (ChromaDB, embeddings)
|
|
157
|
+
- `memory` - Long-term memory proxy (ChromaDB)
|
|
158
|
+
- `vad` - Voice Activity Detection (silero-vad)
|
|
159
|
+
- `audio` - Local audio recording/playback
|
|
160
|
+
- `piper` - Local Piper TTS engine
|
|
161
|
+
- `kokoro` - Kokoro neural TTS engine
|
|
162
|
+
- `faster-whisper` - Whisper ASR for CUDA/CPU
|
|
163
|
+
- `mlx-whisper` - Whisper ASR for Apple Silicon
|
|
164
|
+
- `wyoming` - Wyoming protocol for ASR/TTS servers
|
|
165
|
+
- `server` - FastAPI server components
|
|
166
|
+
- `speed` - Audio speed adjustment
|
|
167
|
+
- `llm` - LLM framework (pydantic-ai)
|
|
168
|
+
|
|
169
|
+
**Examples:**
|
|
170
|
+
|
|
171
|
+
agent-cli install-extras rag # Install RAG dependencies
|
|
172
|
+
agent-cli install-extras memory vad # Install multiple extras
|
|
173
|
+
agent-cli install-extras --list # Show available extras
|
|
174
|
+
agent-cli install-extras --all # Install all extras
|
|
144
175
|
|
|
145
176
|
"""
|
|
146
177
|
available = _available_extras()
|
agent_cli/install/hotkeys.py
CHANGED
|
@@ -13,20 +13,31 @@ from agent_cli.install.common import execute_installation_script, get_platform_s
|
|
|
13
13
|
def install_hotkeys() -> None:
|
|
14
14
|
"""Install system-wide hotkeys for agent-cli commands.
|
|
15
15
|
|
|
16
|
-
Sets up
|
|
16
|
+
Sets up three global hotkeys:
|
|
17
17
|
|
|
18
|
-
macOS
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
| Hotkey (macOS / Linux) | Action |
|
|
19
|
+
|-------------------------|-------------------------------------------------|
|
|
20
|
+
| Cmd/Super + Shift + R | Toggle voice transcription (start/stop) |
|
|
21
|
+
| Cmd/Super + Shift + A | Autocorrect clipboard text (grammar/spelling) |
|
|
22
|
+
| Cmd/Super + Shift + V | Voice edit clipboard text (voice commands) |
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
- Super+Shift+R: Toggle voice transcription
|
|
25
|
-
- Super+Shift+A: Autocorrect clipboard text
|
|
26
|
-
- Super+Shift+V: Voice edit clipboard text
|
|
24
|
+
**macOS** (fully automatic):
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
1. Installs `skhd` (hotkey daemon) and `terminal-notifier` via Homebrew
|
|
27
|
+
2. Creates config at `~/.config/skhd/skhdrc`
|
|
28
|
+
3. Starts skhd as a background service
|
|
29
|
+
4. May require Accessibility permissions: System Settings → Privacy & Security → Accessibility → enable 'skhd'
|
|
30
|
+
|
|
31
|
+
**Linux** (manual DE configuration):
|
|
32
|
+
|
|
33
|
+
1. Installs `libnotify` for notifications (if missing)
|
|
34
|
+
2. Prints binding instructions for your desktop environment
|
|
35
|
+
3. You manually add hotkeys pointing to the installed scripts
|
|
36
|
+
|
|
37
|
+
Supported Linux DEs: Hyprland, Sway, i3, GNOME, KDE, XFCE.
|
|
38
|
+
|
|
39
|
+
**Customizing hotkeys** (macOS): Edit `~/.config/skhd/skhdrc` and restart skhd:
|
|
40
|
+
`skhd --restart-service`
|
|
30
41
|
"""
|
|
31
42
|
script_name = get_platform_script("setup-macos-hotkeys.sh", "setup-linux-hotkeys.sh")
|
|
32
43
|
system = platform.system().lower()
|
agent_cli/install/services.py
CHANGED
|
@@ -20,13 +20,31 @@ from agent_cli.install.common import (
|
|
|
20
20
|
def install_services() -> None:
|
|
21
21
|
"""Install all required services (Ollama, Whisper, Piper, OpenWakeWord).
|
|
22
22
|
|
|
23
|
-
This command installs:
|
|
24
|
-
- Ollama (local LLM server)
|
|
25
|
-
- Wyoming Faster Whisper (speech-to-text)
|
|
26
|
-
- Wyoming Piper (text-to-speech)
|
|
27
|
-
- Wyoming OpenWakeWord (wake word detection)
|
|
23
|
+
This command installs the following services:
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
- **Ollama** - Local LLM server for text processing
|
|
26
|
+
- **Wyoming Faster Whisper** - Speech-to-text transcription
|
|
27
|
+
- **Wyoming Piper** - Text-to-speech synthesis
|
|
28
|
+
- **Wyoming OpenWakeWord** - Wake word detection ("ok nabu", etc.)
|
|
29
|
+
|
|
30
|
+
The appropriate installation method is used based on your operating system
|
|
31
|
+
(Homebrew on macOS, apt/pip on Linux).
|
|
32
|
+
|
|
33
|
+
**Requirements:**
|
|
34
|
+
|
|
35
|
+
- macOS: Homebrew must be installed
|
|
36
|
+
- Linux: Requires sudo access for system packages
|
|
37
|
+
|
|
38
|
+
**Examples:**
|
|
39
|
+
|
|
40
|
+
Install all services:
|
|
41
|
+
`agent-cli install-services`
|
|
42
|
+
|
|
43
|
+
**After installation:**
|
|
44
|
+
|
|
45
|
+
1. Start the services: `agent-cli start-services`
|
|
46
|
+
2. Test transcription: `agent-cli transcribe --list-devices`
|
|
47
|
+
3. Set up hotkeys (optional): `agent-cli install-hotkeys`
|
|
30
48
|
"""
|
|
31
49
|
script_name = get_platform_script("setup-macos.sh", "setup-linux.sh")
|
|
32
50
|
|
|
@@ -46,19 +64,41 @@ def start_services(
|
|
|
46
64
|
attach: bool = typer.Option(
|
|
47
65
|
True, # noqa: FBT003
|
|
48
66
|
"--attach/--no-attach",
|
|
49
|
-
help=
|
|
67
|
+
help=(
|
|
68
|
+
"Attach to the Zellij session after starting. "
|
|
69
|
+
"With `--no-attach`, services start in background and you can "
|
|
70
|
+
"reattach later with `zellij attach agent-cli`"
|
|
71
|
+
),
|
|
50
72
|
),
|
|
51
73
|
) -> None:
|
|
52
74
|
"""Start all agent-cli services in a Zellij session.
|
|
53
75
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
- Wyoming
|
|
58
|
-
- Wyoming
|
|
76
|
+
Starts these services, each in its own Zellij pane:
|
|
77
|
+
|
|
78
|
+
- **Ollama** - LLM server (port 11434)
|
|
79
|
+
- **Wyoming Whisper** - Speech-to-text (port 10300)
|
|
80
|
+
- **Wyoming Piper** - Text-to-speech (port 10200)
|
|
81
|
+
- **Wyoming OpenWakeWord** - Wake word detection (port 10400)
|
|
82
|
+
|
|
83
|
+
Services run in a Zellij terminal multiplexer session named `agent-cli`.
|
|
84
|
+
If a session already exists, the command attaches to it instead of
|
|
85
|
+
starting new services.
|
|
86
|
+
|
|
87
|
+
**Keyboard shortcuts:**
|
|
88
|
+
- `Ctrl-O d` - Detach (keeps services running in background)
|
|
89
|
+
- `Ctrl-Q` - Quit (stops all services)
|
|
90
|
+
- `Alt + arrows` - Navigate between panes
|
|
91
|
+
|
|
92
|
+
**Examples:**
|
|
93
|
+
|
|
94
|
+
Start services and attach:
|
|
95
|
+
`agent-cli start-services`
|
|
96
|
+
|
|
97
|
+
Start in background (for scripts or automation):
|
|
98
|
+
`agent-cli start-services --no-attach`
|
|
59
99
|
|
|
60
|
-
|
|
61
|
-
|
|
100
|
+
Reattach to running services:
|
|
101
|
+
`zellij attach agent-cli`
|
|
62
102
|
"""
|
|
63
103
|
try:
|
|
64
104
|
script_path = get_script_path("start-all-services.sh")
|
agent_cli/opts.py
CHANGED
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
4
|
from pathlib import Path
|
|
5
|
+
from typing import Literal
|
|
5
6
|
|
|
6
7
|
import typer
|
|
7
8
|
from typer.models import OptionInfo
|
|
8
9
|
|
|
9
10
|
from agent_cli.constants import DEFAULT_OPENAI_EMBEDDING_MODEL, DEFAULT_OPENAI_MODEL
|
|
10
11
|
|
|
12
|
+
LogLevel = Literal["debug", "info", "warning", "error"]
|
|
13
|
+
|
|
11
14
|
|
|
12
15
|
def with_default(option: OptionInfo, default: str) -> OptionInfo:
|
|
13
16
|
"""Create a copy of a typer Option with a different default value."""
|
|
@@ -20,18 +23,21 @@ def with_default(option: OptionInfo, default: str) -> OptionInfo:
|
|
|
20
23
|
LLM_PROVIDER: str = typer.Option(
|
|
21
24
|
"ollama",
|
|
22
25
|
"--llm-provider",
|
|
26
|
+
envvar="LLM_PROVIDER",
|
|
23
27
|
help="The LLM provider to use ('ollama', 'openai', 'gemini').",
|
|
24
28
|
rich_help_panel="Provider Selection",
|
|
25
29
|
)
|
|
26
30
|
ASR_PROVIDER: str = typer.Option(
|
|
27
31
|
"wyoming",
|
|
28
32
|
"--asr-provider",
|
|
33
|
+
envvar="ASR_PROVIDER",
|
|
29
34
|
help="The ASR provider to use ('wyoming', 'openai', 'gemini').",
|
|
30
35
|
rich_help_panel="Provider Selection",
|
|
31
36
|
)
|
|
32
37
|
TTS_PROVIDER: str = typer.Option(
|
|
33
38
|
"wyoming",
|
|
34
39
|
"--tts-provider",
|
|
40
|
+
envvar="TTS_PROVIDER",
|
|
35
41
|
help="The TTS provider to use ('wyoming', 'openai', 'kokoro', 'gemini').",
|
|
36
42
|
rich_help_panel="Provider Selection",
|
|
37
43
|
)
|
|
@@ -41,19 +47,22 @@ TTS_PROVIDER: str = typer.Option(
|
|
|
41
47
|
LLM: bool = typer.Option(
|
|
42
48
|
False, # noqa: FBT003
|
|
43
49
|
"--llm/--no-llm",
|
|
44
|
-
help="
|
|
50
|
+
help="Clean up transcript with LLM: fix errors, add punctuation, remove filler words. "
|
|
51
|
+
"Uses `--extra-instructions` if set (via CLI or config file).",
|
|
45
52
|
rich_help_panel="LLM Configuration",
|
|
46
53
|
)
|
|
47
54
|
# Ollama (local service)
|
|
48
55
|
LLM_OLLAMA_MODEL: str = typer.Option(
|
|
49
56
|
"gemma3:4b",
|
|
50
57
|
"--llm-ollama-model",
|
|
58
|
+
envvar="LLM_OLLAMA_MODEL",
|
|
51
59
|
help="The Ollama model to use. Default is gemma3:4b.",
|
|
52
60
|
rich_help_panel="LLM: Ollama",
|
|
53
61
|
)
|
|
54
62
|
LLM_OLLAMA_HOST: str = typer.Option(
|
|
55
63
|
"http://localhost:11434",
|
|
56
64
|
"--llm-ollama-host",
|
|
65
|
+
envvar="LLM_OLLAMA_HOST",
|
|
57
66
|
help="The Ollama server host. Default is http://localhost:11434.",
|
|
58
67
|
rich_help_panel="LLM: Ollama",
|
|
59
68
|
)
|
|
@@ -61,6 +70,7 @@ LLM_OLLAMA_HOST: str = typer.Option(
|
|
|
61
70
|
LLM_OPENAI_MODEL: str = typer.Option(
|
|
62
71
|
DEFAULT_OPENAI_MODEL,
|
|
63
72
|
"--llm-openai-model",
|
|
73
|
+
envvar="LLM_OPENAI_MODEL",
|
|
64
74
|
help="The OpenAI model to use for LLM tasks.",
|
|
65
75
|
rich_help_panel="LLM: OpenAI-compatible",
|
|
66
76
|
)
|
|
@@ -82,6 +92,7 @@ OPENAI_BASE_URL: str | None = typer.Option(
|
|
|
82
92
|
LLM_GEMINI_MODEL: str = typer.Option(
|
|
83
93
|
"gemini-3-flash-preview",
|
|
84
94
|
"--llm-gemini-model",
|
|
95
|
+
envvar="LLM_GEMINI_MODEL",
|
|
85
96
|
help="The Gemini model to use for LLM tasks.",
|
|
86
97
|
rich_help_panel="LLM: Gemini",
|
|
87
98
|
)
|
|
@@ -104,19 +115,19 @@ EMBEDDING_MODEL: str = typer.Option(
|
|
|
104
115
|
INPUT_DEVICE_INDEX: int | None = typer.Option(
|
|
105
116
|
None,
|
|
106
117
|
"--input-device-index",
|
|
107
|
-
help="
|
|
118
|
+
help="Audio input device index (see `--list-devices`). Uses system default if omitted.",
|
|
108
119
|
rich_help_panel="Audio Input",
|
|
109
120
|
)
|
|
110
121
|
INPUT_DEVICE_NAME: str | None = typer.Option(
|
|
111
122
|
None,
|
|
112
123
|
"--input-device-name",
|
|
113
|
-
help="
|
|
124
|
+
help="Select input device by name substring (e.g., `MacBook` or `USB`).",
|
|
114
125
|
rich_help_panel="Audio Input",
|
|
115
126
|
)
|
|
116
127
|
LIST_DEVICES: bool = typer.Option(
|
|
117
128
|
False, # noqa: FBT003
|
|
118
129
|
"--list-devices",
|
|
119
|
-
help="List available audio
|
|
130
|
+
help="List available audio devices with their indices and exit.",
|
|
120
131
|
is_eager=True,
|
|
121
132
|
rich_help_panel="Audio Input",
|
|
122
133
|
)
|
|
@@ -124,12 +135,14 @@ LIST_DEVICES: bool = typer.Option(
|
|
|
124
135
|
ASR_WYOMING_IP: str = typer.Option(
|
|
125
136
|
"localhost",
|
|
126
137
|
"--asr-wyoming-ip",
|
|
138
|
+
envvar="ASR_WYOMING_IP",
|
|
127
139
|
help="Wyoming ASR server IP address.",
|
|
128
140
|
rich_help_panel="Audio Input: Wyoming",
|
|
129
141
|
)
|
|
130
142
|
ASR_WYOMING_PORT: int = typer.Option(
|
|
131
143
|
10300,
|
|
132
144
|
"--asr-wyoming-port",
|
|
145
|
+
envvar="ASR_WYOMING_PORT",
|
|
133
146
|
help="Wyoming ASR server port.",
|
|
134
147
|
rich_help_panel="Audio Input: Wyoming",
|
|
135
148
|
)
|
|
@@ -137,18 +150,21 @@ ASR_WYOMING_PORT: int = typer.Option(
|
|
|
137
150
|
ASR_OPENAI_MODEL: str = typer.Option(
|
|
138
151
|
"whisper-1",
|
|
139
152
|
"--asr-openai-model",
|
|
153
|
+
envvar="ASR_OPENAI_MODEL",
|
|
140
154
|
help="The OpenAI model to use for ASR (transcription).",
|
|
141
155
|
rich_help_panel="Audio Input: OpenAI-compatible",
|
|
142
156
|
)
|
|
143
157
|
ASR_OPENAI_BASE_URL: str | None = typer.Option(
|
|
144
158
|
None,
|
|
145
159
|
"--asr-openai-base-url",
|
|
160
|
+
envvar="ASR_OPENAI_BASE_URL",
|
|
146
161
|
help="Custom base URL for OpenAI-compatible ASR API (e.g., for custom Whisper server: http://localhost:9898).",
|
|
147
162
|
rich_help_panel="Audio Input: OpenAI-compatible",
|
|
148
163
|
)
|
|
149
164
|
ASR_OPENAI_PROMPT: str | None = typer.Option(
|
|
150
165
|
None,
|
|
151
166
|
"--asr-openai-prompt",
|
|
167
|
+
envvar="ASR_OPENAI_PROMPT",
|
|
152
168
|
help="Custom prompt to guide transcription (optional).",
|
|
153
169
|
rich_help_panel="Audio Input: OpenAI-compatible",
|
|
154
170
|
)
|
|
@@ -156,6 +172,7 @@ ASR_OPENAI_PROMPT: str | None = typer.Option(
|
|
|
156
172
|
ASR_GEMINI_MODEL: str = typer.Option(
|
|
157
173
|
"gemini-3-flash-preview",
|
|
158
174
|
"--asr-gemini-model",
|
|
175
|
+
envvar="ASR_GEMINI_MODEL",
|
|
159
176
|
help="The Gemini model to use for ASR (transcription).",
|
|
160
177
|
rich_help_panel="Audio Input: Gemini",
|
|
161
178
|
)
|
|
@@ -165,7 +182,7 @@ ASR_GEMINI_MODEL: str = typer.Option(
|
|
|
165
182
|
WAKE_SERVER_IP: str = typer.Option(
|
|
166
183
|
"localhost",
|
|
167
184
|
"--wake-server-ip",
|
|
168
|
-
help="Wyoming wake word server IP
|
|
185
|
+
help="Wyoming wake word server IP (requires wyoming-openwakeword or similar).",
|
|
169
186
|
rich_help_panel="Wake Word",
|
|
170
187
|
)
|
|
171
188
|
WAKE_SERVER_PORT: int = typer.Option(
|
|
@@ -177,7 +194,7 @@ WAKE_SERVER_PORT: int = typer.Option(
|
|
|
177
194
|
WAKE_WORD: str = typer.Option(
|
|
178
195
|
"ok_nabu",
|
|
179
196
|
"--wake-word",
|
|
180
|
-
help="
|
|
197
|
+
help="Wake word to detect. Common options: `ok_nabu`, `hey_jarvis`, `alexa`. Must match a model loaded in your wake word server.",
|
|
181
198
|
rich_help_panel="Wake Word",
|
|
182
199
|
)
|
|
183
200
|
|
|
@@ -199,13 +216,13 @@ TTS_SPEED: float = typer.Option(
|
|
|
199
216
|
OUTPUT_DEVICE_INDEX: int | None = typer.Option(
|
|
200
217
|
None,
|
|
201
218
|
"--output-device-index",
|
|
202
|
-
help="
|
|
219
|
+
help="Audio output device index (see `--list-devices` for available devices).",
|
|
203
220
|
rich_help_panel="Audio Output",
|
|
204
221
|
)
|
|
205
222
|
OUTPUT_DEVICE_NAME: str | None = typer.Option(
|
|
206
223
|
None,
|
|
207
224
|
"--output-device-name",
|
|
208
|
-
help="
|
|
225
|
+
help="Partial match on device name (e.g., 'speakers', 'headphones').",
|
|
209
226
|
rich_help_panel="Audio Output",
|
|
210
227
|
)
|
|
211
228
|
# Wyoming (local service)
|
|
@@ -249,7 +266,7 @@ TTS_OPENAI_MODEL: str = typer.Option(
|
|
|
249
266
|
TTS_OPENAI_VOICE: str = typer.Option(
|
|
250
267
|
"alloy",
|
|
251
268
|
"--tts-openai-voice",
|
|
252
|
-
help="
|
|
269
|
+
help="Voice for OpenAI TTS (alloy, echo, fable, onyx, nova, shimmer).",
|
|
253
270
|
rich_help_panel="Audio Output: OpenAI-compatible",
|
|
254
271
|
)
|
|
255
272
|
TTS_OPENAI_BASE_URL: str | None = typer.Option(
|
|
@@ -299,21 +316,19 @@ TTS_GEMINI_VOICE: str = typer.Option(
|
|
|
299
316
|
STOP: bool = typer.Option(
|
|
300
317
|
False, # noqa: FBT003
|
|
301
318
|
"--stop",
|
|
302
|
-
help="Stop any running
|
|
319
|
+
help="Stop any running instance of this command.",
|
|
303
320
|
rich_help_panel="Process Management",
|
|
304
321
|
)
|
|
305
322
|
STATUS: bool = typer.Option(
|
|
306
323
|
False, # noqa: FBT003
|
|
307
324
|
"--status",
|
|
308
|
-
help="Check if
|
|
325
|
+
help="Check if an instance is currently running.",
|
|
309
326
|
rich_help_panel="Process Management",
|
|
310
327
|
)
|
|
311
328
|
TOGGLE: bool = typer.Option(
|
|
312
329
|
False, # noqa: FBT003
|
|
313
330
|
"--toggle",
|
|
314
|
-
help="
|
|
315
|
-
"If the process is running, it will be stopped. "
|
|
316
|
-
"If the process is not running, it will be started.",
|
|
331
|
+
help="Start if not running, stop if running. Ideal for hotkey binding.",
|
|
317
332
|
rich_help_panel="Process Management",
|
|
318
333
|
)
|
|
319
334
|
|
|
@@ -348,13 +363,15 @@ CLIPBOARD: bool = typer.Option(
|
|
|
348
363
|
help="Copy result to clipboard.",
|
|
349
364
|
rich_help_panel="General Options",
|
|
350
365
|
)
|
|
351
|
-
LOG_LEVEL:
|
|
352
|
-
"
|
|
366
|
+
LOG_LEVEL: LogLevel = typer.Option(
|
|
367
|
+
"warning",
|
|
353
368
|
"--log-level",
|
|
369
|
+
envvar="LOG_LEVEL",
|
|
354
370
|
help="Set logging level.",
|
|
355
371
|
case_sensitive=False,
|
|
356
372
|
rich_help_panel="General Options",
|
|
357
373
|
)
|
|
374
|
+
SERVER_LOG_LEVEL: LogLevel = with_default(LOG_LEVEL, "info")
|
|
358
375
|
LOG_FILE: str | None = typer.Option(
|
|
359
376
|
None,
|
|
360
377
|
"--log-file",
|
|
@@ -371,19 +388,20 @@ QUIET: bool = typer.Option(
|
|
|
371
388
|
JSON_OUTPUT: bool = typer.Option(
|
|
372
389
|
False, # noqa: FBT003
|
|
373
390
|
"--json",
|
|
374
|
-
help="Output result as JSON
|
|
391
|
+
help="Output result as JSON (implies `--quiet` and `--no-clipboard`).",
|
|
375
392
|
rich_help_panel="General Options",
|
|
376
393
|
)
|
|
377
394
|
SAVE_FILE: Path | None = typer.Option(
|
|
378
395
|
None,
|
|
379
396
|
"--save-file",
|
|
380
|
-
help="Save
|
|
397
|
+
help="Save audio to WAV file instead of playing through speakers.",
|
|
381
398
|
rich_help_panel="General Options",
|
|
382
399
|
)
|
|
383
400
|
TRANSCRIPTION_LOG: Path | None = typer.Option(
|
|
384
401
|
None,
|
|
385
402
|
"--transcription-log",
|
|
386
|
-
help="
|
|
403
|
+
help="Append transcripts to JSONL file (timestamp, hostname, model, raw/processed text). "
|
|
404
|
+
"Recent entries provide context for LLM cleanup.",
|
|
387
405
|
rich_help_panel="General Options",
|
|
388
406
|
)
|
|
389
407
|
|
|
@@ -399,18 +417,21 @@ SERVER_HOST: str = typer.Option(
|
|
|
399
417
|
FROM_FILE: Path | None = typer.Option(
|
|
400
418
|
None,
|
|
401
419
|
"--from-file",
|
|
402
|
-
help="Transcribe
|
|
420
|
+
help="Transcribe from audio file instead of microphone. "
|
|
421
|
+
"Supports wav, mp3, m4a, ogg, flac, aac, webm. "
|
|
422
|
+
"Requires `ffmpeg` for non-WAV formats with Wyoming.",
|
|
403
423
|
rich_help_panel="Audio Recovery",
|
|
404
424
|
)
|
|
405
425
|
LAST_RECORDING: int = typer.Option(
|
|
406
426
|
0,
|
|
407
427
|
"--last-recording",
|
|
408
|
-
help="
|
|
428
|
+
help="Re-transcribe a saved recording (1=most recent, 2=second-to-last, etc). "
|
|
429
|
+
"Useful after connection failures or to retry with different options.",
|
|
409
430
|
rich_help_panel="Audio Recovery",
|
|
410
431
|
)
|
|
411
432
|
SAVE_RECORDING: bool = typer.Option(
|
|
412
433
|
True, # noqa: FBT003
|
|
413
434
|
"--save-recording/--no-save-recording",
|
|
414
|
-
help="Save
|
|
435
|
+
help="Save recordings to ~/.cache/agent-cli/ for `--last-recording` recovery.",
|
|
415
436
|
rich_help_panel="Audio Recovery",
|
|
416
437
|
)
|