agent-cli 0.63.0__py3-none-any.whl → 0.64.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/scripts/check_plugin_skill_sync.py +50 -0
- agent_cli/server/whisper/wyoming_handler.py +22 -27
- {agent_cli-0.63.0.dist-info → agent_cli-0.64.1.dist-info}/METADATA +2 -2
- {agent_cli-0.63.0.dist-info → agent_cli-0.64.1.dist-info}/RECORD +7 -6
- {agent_cli-0.63.0.dist-info → agent_cli-0.64.1.dist-info}/WHEEL +0 -0
- {agent_cli-0.63.0.dist-info → agent_cli-0.64.1.dist-info}/entry_points.txt +0 -0
- {agent_cli-0.63.0.dist-info → agent_cli-0.64.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Check that plugin skill files are in sync with source files."""
|
|
3
|
+
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
SYNC_PAIRS = [
|
|
8
|
+
# Plugin marketplace distribution
|
|
9
|
+
("agent_cli/dev/skill/SKILL.md", ".claude-plugin/skills/agent-cli-dev/SKILL.md"),
|
|
10
|
+
("agent_cli/dev/skill/examples.md", ".claude-plugin/skills/agent-cli-dev/examples.md"),
|
|
11
|
+
# Project-local skill (for Claude Code working on this repo)
|
|
12
|
+
("agent_cli/dev/skill/SKILL.md", ".claude/skills/agent-cli-dev/SKILL.md"),
|
|
13
|
+
("agent_cli/dev/skill/examples.md", ".claude/skills/agent-cli-dev/examples.md"),
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def main() -> int:
|
|
18
|
+
"""Check that plugin skill files match source files."""
|
|
19
|
+
root = Path(__file__).parent.parent
|
|
20
|
+
out_of_sync = []
|
|
21
|
+
|
|
22
|
+
for source, target in SYNC_PAIRS:
|
|
23
|
+
source_path = root / source
|
|
24
|
+
target_path = root / target
|
|
25
|
+
|
|
26
|
+
if not source_path.exists():
|
|
27
|
+
print(f"Source not found: {source}")
|
|
28
|
+
continue
|
|
29
|
+
|
|
30
|
+
if not target_path.exists():
|
|
31
|
+
out_of_sync.append((source, target, "target missing"))
|
|
32
|
+
continue
|
|
33
|
+
|
|
34
|
+
if source_path.read_text() != target_path.read_text():
|
|
35
|
+
out_of_sync.append((source, target, "content differs"))
|
|
36
|
+
|
|
37
|
+
if out_of_sync:
|
|
38
|
+
print("Plugin skill files are out of sync:")
|
|
39
|
+
for source, target, reason in out_of_sync:
|
|
40
|
+
print(f" {source} -> {target} ({reason})")
|
|
41
|
+
print("\nRun:")
|
|
42
|
+
print(" cp agent_cli/dev/skill/*.md .claude-plugin/skills/agent-cli-dev/")
|
|
43
|
+
print(" cp agent_cli/dev/skill/*.md .claude/skills/agent-cli-dev/")
|
|
44
|
+
return 1
|
|
45
|
+
|
|
46
|
+
return 0
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
sys.exit(main())
|
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import io
|
|
6
5
|
import logging
|
|
7
|
-
import wave
|
|
8
6
|
from functools import partial
|
|
9
7
|
from typing import TYPE_CHECKING
|
|
10
8
|
|
|
11
9
|
from wyoming.asr import Transcribe, Transcript
|
|
12
|
-
from wyoming.audio import AudioChunk, AudioStop
|
|
10
|
+
from wyoming.audio import AudioChunk, AudioChunkConverter, AudioStop
|
|
13
11
|
from wyoming.info import AsrModel, AsrProgram, Attribution, Describe, Info
|
|
14
12
|
from wyoming.server import AsyncEventHandler, AsyncServer
|
|
15
13
|
|
|
16
|
-
from agent_cli
|
|
14
|
+
from agent_cli import constants
|
|
17
15
|
from agent_cli.server.whisper.languages import WHISPER_LANGUAGE_CODES
|
|
16
|
+
from agent_cli.services import pcm_to_wav
|
|
18
17
|
|
|
19
18
|
if TYPE_CHECKING:
|
|
20
19
|
from wyoming.event import Event
|
|
@@ -49,8 +48,12 @@ class WyomingWhisperHandler(AsyncEventHandler):
|
|
|
49
48
|
"""
|
|
50
49
|
super().__init__(*args, **kwargs)
|
|
51
50
|
self._registry = registry
|
|
52
|
-
self.
|
|
53
|
-
self.
|
|
51
|
+
self._audio_bytes: bytes = b""
|
|
52
|
+
self._audio_converter = AudioChunkConverter(
|
|
53
|
+
rate=constants.AUDIO_RATE,
|
|
54
|
+
width=constants.AUDIO_FORMAT_WIDTH,
|
|
55
|
+
channels=constants.AUDIO_CHANNELS,
|
|
56
|
+
)
|
|
54
57
|
self._language: str | None = None
|
|
55
58
|
self._initial_prompt: str | None = None
|
|
56
59
|
|
|
@@ -80,39 +83,31 @@ class WyomingWhisperHandler(AsyncEventHandler):
|
|
|
80
83
|
|
|
81
84
|
async def _handle_audio_chunk(self, event: Event) -> bool:
|
|
82
85
|
"""Handle an audio chunk event."""
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if self._wav_file is None:
|
|
86
|
+
if not self._audio_bytes:
|
|
86
87
|
logger.debug("AudioChunk begin")
|
|
87
|
-
self._audio_buffer = io.BytesIO()
|
|
88
|
-
self._wav_file = wave.open(self._audio_buffer, "wb") # noqa: SIM115
|
|
89
|
-
setup_wav_file(
|
|
90
|
-
self._wav_file,
|
|
91
|
-
rate=chunk.rate,
|
|
92
|
-
channels=chunk.channels,
|
|
93
|
-
sample_width=chunk.width,
|
|
94
|
-
)
|
|
95
88
|
|
|
96
|
-
|
|
89
|
+
chunk = AudioChunk.from_event(event)
|
|
90
|
+
chunk = self._audio_converter.convert(chunk)
|
|
91
|
+
self._audio_bytes += chunk.audio
|
|
97
92
|
return True
|
|
98
93
|
|
|
99
94
|
async def _handle_audio_stop(self) -> bool:
|
|
100
95
|
"""Handle audio stop event - transcribe the collected audio."""
|
|
101
96
|
logger.debug("AudioStop")
|
|
102
97
|
|
|
103
|
-
if
|
|
98
|
+
if not self._audio_bytes:
|
|
104
99
|
logger.warning("AudioStop received but no audio data")
|
|
105
100
|
await self.write_event(Transcript(text="").event())
|
|
106
101
|
return False
|
|
107
102
|
|
|
108
|
-
#
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
self.
|
|
103
|
+
# Wrap PCM in WAV format for the backend
|
|
104
|
+
audio_data = pcm_to_wav(
|
|
105
|
+
self._audio_bytes,
|
|
106
|
+
sample_rate=constants.AUDIO_RATE,
|
|
107
|
+
sample_width=constants.AUDIO_FORMAT_WIDTH,
|
|
108
|
+
channels=constants.AUDIO_CHANNELS,
|
|
109
|
+
)
|
|
110
|
+
self._audio_bytes = b""
|
|
116
111
|
|
|
117
112
|
# Transcribe
|
|
118
113
|
try:
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.64.1
|
|
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>
|
|
7
7
|
License-File: LICENSE
|
|
8
|
-
Requires-Python:
|
|
8
|
+
Requires-Python: <3.14,>=3.11
|
|
9
9
|
Requires-Dist: dotenv
|
|
10
10
|
Requires-Dist: google-genai>=1.25.0
|
|
11
11
|
Requires-Dist: httpx
|
|
@@ -109,6 +109,7 @@ agent_cli/rag/client.py,sha256=mFiZ4yjI75Vsehie6alsV1My50uIsp-G07Qz6SaNrZw,8913
|
|
|
109
109
|
agent_cli/rag/engine.py,sha256=XySDer0fNTsEUjbUby5yf7JqB7uCE7tw2A6tYJixHnI,9800
|
|
110
110
|
agent_cli/rag/models.py,sha256=uECWoeBChlkAK7uTM-pUnPGaaMO4EYJ3pJcAf8uh1vI,1043
|
|
111
111
|
agent_cli/scripts/__init__.py,sha256=QvI1gnTagN85mmKDy2IRw96MEU9DKRWKkhSKSBshGVY,78
|
|
112
|
+
agent_cli/scripts/check_plugin_skill_sync.py,sha256=abuiSjvj34mazYeKOG-Mw6y14uN_1Ie8dkcCs_M_RF0,1656
|
|
112
113
|
agent_cli/scripts/run-openwakeword.sh,sha256=jXZ3hegiL5TINFttvOPnnfDWuIR6x8Mv_pAEWij7Z08,446
|
|
113
114
|
agent_cli/scripts/run-piper-windows.ps1,sha256=jpy4-3NxCoBpT3mnNbmCCSGbahjbv34KozlQ3lCDpV4,1134
|
|
114
115
|
agent_cli/scripts/run-piper.sh,sha256=MAI1yTnmcn3z-t7UWwK5oSvpr9KNgh6Z2h7ns_dbYNc,877
|
|
@@ -161,7 +162,7 @@ agent_cli/server/whisper/api.py,sha256=_2z04tUfuQ6QnKMaZnikb5Ji7LbtCfKYs42MG6v-Q
|
|
|
161
162
|
agent_cli/server/whisper/languages.py,sha256=Tv3qsIOSQQLxw-v5Wy41jSS6uHG_YBiG-T2uJVVt3u0,2686
|
|
162
163
|
agent_cli/server/whisper/model_manager.py,sha256=LI92mkueu8o8m6AhzlUaaIWygnZucJa295-j7ymx7Ss,4925
|
|
163
164
|
agent_cli/server/whisper/model_registry.py,sha256=qoRkB0ex6aRtUlsUN5BGik-oIZlwJbVHGQKaCbf_yVg,789
|
|
164
|
-
agent_cli/server/whisper/wyoming_handler.py,sha256=
|
|
165
|
+
agent_cli/server/whisper/wyoming_handler.py,sha256=HjN565YfDHeVfaGjQfoy9xjCZPx_TvYvjRYgbKn3aOI,6634
|
|
165
166
|
agent_cli/server/whisper/backends/__init__.py,sha256=DfgyigwMLKiSfaRzZ1TTeV7fa9HWSmT1UJnJa-6el7k,2338
|
|
166
167
|
agent_cli/server/whisper/backends/base.py,sha256=gQi5EyMCFS464mKXGIKbh1vgtBm99eNkf93SCIYRYg0,2597
|
|
167
168
|
agent_cli/server/whisper/backends/faster_whisper.py,sha256=-BogM_-_rhlXKUZuW1qUN8zw2gD0ut1bJozPDP19knA,6717
|
|
@@ -172,8 +173,8 @@ agent_cli/services/asr.py,sha256=V6SV-USnMhK-0aE-pneiktU4HpmLqenmMb-jZ-_74zU,169
|
|
|
172
173
|
agent_cli/services/llm.py,sha256=Kwdo6pbMYI9oykF-RBe1iaL3KsYrNWTLdRSioewmsGQ,7199
|
|
173
174
|
agent_cli/services/tts.py,sha256=exKo-55_670mx8dQOzVSZkv6aWYLv04SVmBcjOlD458,14772
|
|
174
175
|
agent_cli/services/wake_word.py,sha256=j6Z8rsGq_vAdRevy9fkXIgLZd9UWfrIsefmTreNmM0c,4575
|
|
175
|
-
agent_cli-0.
|
|
176
|
-
agent_cli-0.
|
|
177
|
-
agent_cli-0.
|
|
178
|
-
agent_cli-0.
|
|
179
|
-
agent_cli-0.
|
|
176
|
+
agent_cli-0.64.1.dist-info/METADATA,sha256=NtwnF8rl-kVN0Tw2P6ECUdSY5RuxhDoOHRTGrcpvOqs,151915
|
|
177
|
+
agent_cli-0.64.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
178
|
+
agent_cli-0.64.1.dist-info/entry_points.txt,sha256=FUv-fB2atLsPUk_RT4zqnZl1coz4_XHFwRALOKOF38s,97
|
|
179
|
+
agent_cli-0.64.1.dist-info/licenses/LICENSE,sha256=majJU6S9kC8R8bW39NVBHyv32Dq50FL6TDxECG2WVts,1068
|
|
180
|
+
agent_cli-0.64.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|