agent-cli 0.70.5__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/__init__.py +5 -0
- agent_cli/__main__.py +6 -0
- agent_cli/_extras.json +14 -0
- agent_cli/_requirements/.gitkeep +0 -0
- agent_cli/_requirements/audio.txt +79 -0
- agent_cli/_requirements/faster-whisper.txt +215 -0
- agent_cli/_requirements/kokoro.txt +425 -0
- agent_cli/_requirements/llm.txt +183 -0
- agent_cli/_requirements/memory.txt +355 -0
- agent_cli/_requirements/mlx-whisper.txt +222 -0
- agent_cli/_requirements/piper.txt +176 -0
- agent_cli/_requirements/rag.txt +402 -0
- agent_cli/_requirements/server.txt +154 -0
- agent_cli/_requirements/speed.txt +77 -0
- agent_cli/_requirements/vad.txt +155 -0
- agent_cli/_requirements/wyoming.txt +71 -0
- agent_cli/_tools.py +368 -0
- agent_cli/agents/__init__.py +23 -0
- agent_cli/agents/_voice_agent_common.py +136 -0
- agent_cli/agents/assistant.py +383 -0
- agent_cli/agents/autocorrect.py +284 -0
- agent_cli/agents/chat.py +496 -0
- agent_cli/agents/memory/__init__.py +31 -0
- agent_cli/agents/memory/add.py +190 -0
- agent_cli/agents/memory/proxy.py +160 -0
- agent_cli/agents/rag_proxy.py +128 -0
- agent_cli/agents/speak.py +209 -0
- agent_cli/agents/transcribe.py +671 -0
- agent_cli/agents/transcribe_daemon.py +499 -0
- agent_cli/agents/voice_edit.py +291 -0
- agent_cli/api.py +22 -0
- agent_cli/cli.py +106 -0
- agent_cli/config.py +503 -0
- agent_cli/config_cmd.py +307 -0
- agent_cli/constants.py +27 -0
- agent_cli/core/__init__.py +1 -0
- agent_cli/core/audio.py +461 -0
- agent_cli/core/audio_format.py +299 -0
- agent_cli/core/chroma.py +88 -0
- agent_cli/core/deps.py +191 -0
- agent_cli/core/openai_proxy.py +139 -0
- agent_cli/core/process.py +195 -0
- agent_cli/core/reranker.py +120 -0
- agent_cli/core/sse.py +87 -0
- agent_cli/core/transcription_logger.py +70 -0
- agent_cli/core/utils.py +526 -0
- agent_cli/core/vad.py +175 -0
- agent_cli/core/watch.py +65 -0
- agent_cli/dev/__init__.py +14 -0
- agent_cli/dev/cli.py +1588 -0
- agent_cli/dev/coding_agents/__init__.py +19 -0
- agent_cli/dev/coding_agents/aider.py +24 -0
- agent_cli/dev/coding_agents/base.py +167 -0
- agent_cli/dev/coding_agents/claude.py +39 -0
- agent_cli/dev/coding_agents/codex.py +24 -0
- agent_cli/dev/coding_agents/continue_dev.py +15 -0
- agent_cli/dev/coding_agents/copilot.py +24 -0
- agent_cli/dev/coding_agents/cursor_agent.py +48 -0
- agent_cli/dev/coding_agents/gemini.py +28 -0
- agent_cli/dev/coding_agents/opencode.py +15 -0
- agent_cli/dev/coding_agents/registry.py +49 -0
- agent_cli/dev/editors/__init__.py +19 -0
- agent_cli/dev/editors/base.py +89 -0
- agent_cli/dev/editors/cursor.py +15 -0
- agent_cli/dev/editors/emacs.py +46 -0
- agent_cli/dev/editors/jetbrains.py +56 -0
- agent_cli/dev/editors/nano.py +31 -0
- agent_cli/dev/editors/neovim.py +33 -0
- agent_cli/dev/editors/registry.py +59 -0
- agent_cli/dev/editors/sublime.py +20 -0
- agent_cli/dev/editors/vim.py +42 -0
- agent_cli/dev/editors/vscode.py +15 -0
- agent_cli/dev/editors/zed.py +20 -0
- agent_cli/dev/project.py +568 -0
- agent_cli/dev/registry.py +52 -0
- agent_cli/dev/skill/SKILL.md +141 -0
- agent_cli/dev/skill/examples.md +571 -0
- agent_cli/dev/terminals/__init__.py +19 -0
- agent_cli/dev/terminals/apple_terminal.py +82 -0
- agent_cli/dev/terminals/base.py +56 -0
- agent_cli/dev/terminals/gnome.py +51 -0
- agent_cli/dev/terminals/iterm2.py +84 -0
- agent_cli/dev/terminals/kitty.py +77 -0
- agent_cli/dev/terminals/registry.py +48 -0
- agent_cli/dev/terminals/tmux.py +58 -0
- agent_cli/dev/terminals/warp.py +132 -0
- agent_cli/dev/terminals/zellij.py +78 -0
- agent_cli/dev/worktree.py +856 -0
- agent_cli/docs_gen.py +417 -0
- agent_cli/example-config.toml +185 -0
- agent_cli/install/__init__.py +5 -0
- agent_cli/install/common.py +89 -0
- agent_cli/install/extras.py +174 -0
- agent_cli/install/hotkeys.py +48 -0
- agent_cli/install/services.py +87 -0
- agent_cli/memory/__init__.py +7 -0
- agent_cli/memory/_files.py +250 -0
- agent_cli/memory/_filters.py +63 -0
- agent_cli/memory/_git.py +157 -0
- agent_cli/memory/_indexer.py +142 -0
- agent_cli/memory/_ingest.py +408 -0
- agent_cli/memory/_persistence.py +182 -0
- agent_cli/memory/_prompt.py +91 -0
- agent_cli/memory/_retrieval.py +294 -0
- agent_cli/memory/_store.py +169 -0
- agent_cli/memory/_streaming.py +44 -0
- agent_cli/memory/_tasks.py +48 -0
- agent_cli/memory/api.py +113 -0
- agent_cli/memory/client.py +272 -0
- agent_cli/memory/engine.py +361 -0
- agent_cli/memory/entities.py +43 -0
- agent_cli/memory/models.py +112 -0
- agent_cli/opts.py +433 -0
- agent_cli/py.typed +0 -0
- agent_cli/rag/__init__.py +3 -0
- agent_cli/rag/_indexer.py +67 -0
- agent_cli/rag/_indexing.py +226 -0
- agent_cli/rag/_prompt.py +30 -0
- agent_cli/rag/_retriever.py +156 -0
- agent_cli/rag/_store.py +48 -0
- agent_cli/rag/_utils.py +218 -0
- agent_cli/rag/api.py +175 -0
- agent_cli/rag/client.py +299 -0
- agent_cli/rag/engine.py +302 -0
- agent_cli/rag/models.py +55 -0
- agent_cli/scripts/.runtime/.gitkeep +0 -0
- agent_cli/scripts/__init__.py +1 -0
- agent_cli/scripts/check_plugin_skill_sync.py +50 -0
- agent_cli/scripts/linux-hotkeys/README.md +63 -0
- agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +45 -0
- agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +58 -0
- agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +58 -0
- agent_cli/scripts/macos-hotkeys/README.md +45 -0
- agent_cli/scripts/macos-hotkeys/skhd-config-example +5 -0
- agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +12 -0
- agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +37 -0
- agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +37 -0
- agent_cli/scripts/nvidia-asr-server/README.md +99 -0
- agent_cli/scripts/nvidia-asr-server/pyproject.toml +27 -0
- agent_cli/scripts/nvidia-asr-server/server.py +255 -0
- agent_cli/scripts/nvidia-asr-server/shell.nix +32 -0
- agent_cli/scripts/nvidia-asr-server/uv.lock +4654 -0
- agent_cli/scripts/run-openwakeword.sh +11 -0
- agent_cli/scripts/run-piper-windows.ps1 +30 -0
- agent_cli/scripts/run-piper.sh +24 -0
- agent_cli/scripts/run-whisper-linux.sh +40 -0
- agent_cli/scripts/run-whisper-macos.sh +6 -0
- agent_cli/scripts/run-whisper-windows.ps1 +51 -0
- agent_cli/scripts/run-whisper.sh +9 -0
- agent_cli/scripts/run_faster_whisper_server.py +136 -0
- agent_cli/scripts/setup-linux-hotkeys.sh +72 -0
- agent_cli/scripts/setup-linux.sh +108 -0
- agent_cli/scripts/setup-macos-hotkeys.sh +61 -0
- agent_cli/scripts/setup-macos.sh +76 -0
- agent_cli/scripts/setup-windows.ps1 +63 -0
- agent_cli/scripts/start-all-services-windows.ps1 +53 -0
- agent_cli/scripts/start-all-services.sh +178 -0
- agent_cli/scripts/sync_extras.py +138 -0
- agent_cli/server/__init__.py +3 -0
- agent_cli/server/cli.py +721 -0
- agent_cli/server/common.py +222 -0
- agent_cli/server/model_manager.py +288 -0
- agent_cli/server/model_registry.py +225 -0
- agent_cli/server/proxy/__init__.py +3 -0
- agent_cli/server/proxy/api.py +444 -0
- agent_cli/server/streaming.py +67 -0
- agent_cli/server/tts/__init__.py +3 -0
- agent_cli/server/tts/api.py +335 -0
- agent_cli/server/tts/backends/__init__.py +82 -0
- agent_cli/server/tts/backends/base.py +139 -0
- agent_cli/server/tts/backends/kokoro.py +403 -0
- agent_cli/server/tts/backends/piper.py +253 -0
- agent_cli/server/tts/model_manager.py +201 -0
- agent_cli/server/tts/model_registry.py +28 -0
- agent_cli/server/tts/wyoming_handler.py +249 -0
- agent_cli/server/whisper/__init__.py +3 -0
- agent_cli/server/whisper/api.py +413 -0
- agent_cli/server/whisper/backends/__init__.py +89 -0
- agent_cli/server/whisper/backends/base.py +97 -0
- agent_cli/server/whisper/backends/faster_whisper.py +225 -0
- agent_cli/server/whisper/backends/mlx.py +270 -0
- agent_cli/server/whisper/languages.py +116 -0
- agent_cli/server/whisper/model_manager.py +157 -0
- agent_cli/server/whisper/model_registry.py +28 -0
- agent_cli/server/whisper/wyoming_handler.py +203 -0
- agent_cli/services/__init__.py +343 -0
- agent_cli/services/_wyoming_utils.py +64 -0
- agent_cli/services/asr.py +506 -0
- agent_cli/services/llm.py +228 -0
- agent_cli/services/tts.py +450 -0
- agent_cli/services/wake_word.py +142 -0
- agent_cli-0.70.5.dist-info/METADATA +2118 -0
- agent_cli-0.70.5.dist-info/RECORD +196 -0
- agent_cli-0.70.5.dist-info/WHEEL +4 -0
- agent_cli-0.70.5.dist-info/entry_points.txt +4 -0
- agent_cli-0.70.5.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Module for Wake Word Detection using Wyoming."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from functools import partial
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
from agent_cli import config, constants
|
|
10
|
+
from agent_cli.core.audio import read_from_queue
|
|
11
|
+
from agent_cli.core.utils import manage_send_receive_tasks
|
|
12
|
+
from agent_cli.services._wyoming_utils import wyoming_client_context
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
import logging
|
|
16
|
+
from collections.abc import Awaitable, Callable
|
|
17
|
+
|
|
18
|
+
from rich.live import Live
|
|
19
|
+
from wyoming.client import AsyncClient
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def create_wake_word_detector(
|
|
23
|
+
wake_word_cfg: config.WakeWord,
|
|
24
|
+
) -> Callable[..., Awaitable[str | None]]:
|
|
25
|
+
"""Return a wake word detector function."""
|
|
26
|
+
return partial(_detect_wake_word_from_queue, wake_word_cfg=wake_word_cfg)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
async def _send_audio_from_queue_for_wake_detection(
|
|
30
|
+
client: AsyncClient,
|
|
31
|
+
queue: asyncio.Queue,
|
|
32
|
+
logger: logging.Logger,
|
|
33
|
+
live: Live | None,
|
|
34
|
+
quiet: bool,
|
|
35
|
+
progress_message: str,
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Read from a queue and send to Wyoming wake word server."""
|
|
38
|
+
from wyoming.audio import AudioChunk, AudioStart, AudioStop # noqa: PLC0415
|
|
39
|
+
|
|
40
|
+
await client.write_event(AudioStart(**constants.WYOMING_AUDIO_CONFIG).event())
|
|
41
|
+
seconds_streamed = 0.0
|
|
42
|
+
|
|
43
|
+
async def send_chunk(chunk: bytes) -> None:
|
|
44
|
+
nonlocal seconds_streamed
|
|
45
|
+
"""Send audio chunk to wake word server."""
|
|
46
|
+
await client.write_event(
|
|
47
|
+
AudioChunk(audio=chunk, **constants.WYOMING_AUDIO_CONFIG).event(),
|
|
48
|
+
)
|
|
49
|
+
seconds_streamed += len(chunk) / (constants.AUDIO_RATE * constants.AUDIO_CHANNELS * 2)
|
|
50
|
+
if live and not quiet:
|
|
51
|
+
live.update(f"{progress_message}... ({seconds_streamed:.1f}s)")
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
await read_from_queue(queue=queue, chunk_handler=send_chunk, logger=logger)
|
|
55
|
+
finally:
|
|
56
|
+
if client._writer is not None:
|
|
57
|
+
await client.write_event(AudioStop().event())
|
|
58
|
+
logger.debug("Sent AudioStop for wake detection")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
async def _receive_wake_detection(
|
|
62
|
+
client: AsyncClient,
|
|
63
|
+
logger: logging.Logger,
|
|
64
|
+
*,
|
|
65
|
+
detection_callback: Callable[[str], None] | None = None,
|
|
66
|
+
) -> str | None:
|
|
67
|
+
"""Receive wake word detection events.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
client: Wyoming client connection
|
|
71
|
+
logger: Logger instance
|
|
72
|
+
detection_callback: Optional callback for when wake word is detected
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Name of detected wake word or None if no detection
|
|
76
|
+
|
|
77
|
+
"""
|
|
78
|
+
from wyoming.wake import Detection, NotDetected # noqa: PLC0415
|
|
79
|
+
|
|
80
|
+
while True:
|
|
81
|
+
event = await client.read_event()
|
|
82
|
+
if event is None:
|
|
83
|
+
logger.warning("Connection to wake word server lost.")
|
|
84
|
+
break
|
|
85
|
+
|
|
86
|
+
if Detection.is_type(event.type):
|
|
87
|
+
detection = Detection.from_event(event)
|
|
88
|
+
wake_word_name = detection.name or "unknown"
|
|
89
|
+
logger.info("Wake word detected: %s", wake_word_name)
|
|
90
|
+
if detection_callback:
|
|
91
|
+
detection_callback(wake_word_name)
|
|
92
|
+
return wake_word_name
|
|
93
|
+
if NotDetected.is_type(event.type):
|
|
94
|
+
logger.debug("No wake word detected")
|
|
95
|
+
break
|
|
96
|
+
logger.debug("Ignoring event type: %s", event.type)
|
|
97
|
+
|
|
98
|
+
return None
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
async def _detect_wake_word_from_queue(
|
|
102
|
+
wake_word_cfg: config.WakeWord,
|
|
103
|
+
logger: logging.Logger,
|
|
104
|
+
queue: asyncio.Queue,
|
|
105
|
+
*,
|
|
106
|
+
live: Live | None = None,
|
|
107
|
+
detection_callback: Callable[[str], None] | None = None,
|
|
108
|
+
quiet: bool = False,
|
|
109
|
+
progress_message: str = "Listening for wake word",
|
|
110
|
+
) -> str | None:
|
|
111
|
+
"""Detect wake word from an audio queue."""
|
|
112
|
+
from wyoming.wake import Detect # noqa: PLC0415
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
async with wyoming_client_context(
|
|
116
|
+
wake_word_cfg.wake_server_ip,
|
|
117
|
+
wake_word_cfg.wake_server_port,
|
|
118
|
+
"wake word",
|
|
119
|
+
logger,
|
|
120
|
+
quiet=quiet,
|
|
121
|
+
) as client:
|
|
122
|
+
await client.write_event(Detect(names=[wake_word_cfg.wake_word]).event())
|
|
123
|
+
|
|
124
|
+
_send_task, recv_task = await manage_send_receive_tasks(
|
|
125
|
+
_send_audio_from_queue_for_wake_detection(
|
|
126
|
+
client,
|
|
127
|
+
queue,
|
|
128
|
+
logger,
|
|
129
|
+
live,
|
|
130
|
+
quiet,
|
|
131
|
+
progress_message,
|
|
132
|
+
),
|
|
133
|
+
_receive_wake_detection(client, logger, detection_callback=detection_callback),
|
|
134
|
+
return_when=asyncio.FIRST_COMPLETED,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if recv_task.done() and not recv_task.cancelled():
|
|
138
|
+
return recv_task.result()
|
|
139
|
+
|
|
140
|
+
return None
|
|
141
|
+
except (ConnectionRefusedError, asyncio.CancelledError, Exception):
|
|
142
|
+
return None
|