npcsh 0.3.31__py3-none-any.whl → 1.0.0__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.
- npcsh/_state.py +942 -0
- npcsh/alicanto.py +1074 -0
- npcsh/guac.py +785 -0
- npcsh/mcp_helpers.py +357 -0
- npcsh/mcp_npcsh.py +822 -0
- npcsh/mcp_server.py +184 -0
- npcsh/npc.py +218 -0
- npcsh/npcsh.py +1161 -0
- npcsh/plonk.py +387 -269
- npcsh/pti.py +234 -0
- npcsh/routes.py +958 -0
- npcsh/spool.py +315 -0
- npcsh/wander.py +550 -0
- npcsh/yap.py +573 -0
- npcsh-1.0.0.dist-info/METADATA +596 -0
- npcsh-1.0.0.dist-info/RECORD +21 -0
- {npcsh-0.3.31.dist-info → npcsh-1.0.0.dist-info}/WHEEL +1 -1
- npcsh-1.0.0.dist-info/entry_points.txt +9 -0
- {npcsh-0.3.31.dist-info → npcsh-1.0.0.dist-info}/licenses/LICENSE +1 -1
- npcsh/audio.py +0 -210
- npcsh/cli.py +0 -545
- npcsh/command_history.py +0 -566
- npcsh/conversation.py +0 -291
- npcsh/data_models.py +0 -46
- npcsh/dataframes.py +0 -163
- npcsh/embeddings.py +0 -168
- npcsh/helpers.py +0 -641
- npcsh/image.py +0 -298
- npcsh/image_gen.py +0 -79
- npcsh/knowledge_graph.py +0 -1006
- npcsh/llm_funcs.py +0 -2027
- npcsh/load_data.py +0 -83
- npcsh/main.py +0 -5
- npcsh/model_runner.py +0 -189
- npcsh/npc_compiler.py +0 -2870
- npcsh/npc_sysenv.py +0 -383
- npcsh/npc_team/assembly_lines/test_pipeline.py +0 -181
- npcsh/npc_team/corca.npc +0 -13
- npcsh/npc_team/foreman.npc +0 -7
- npcsh/npc_team/npcsh.ctx +0 -11
- npcsh/npc_team/sibiji.npc +0 -4
- npcsh/npc_team/templates/analytics/celona.npc +0 -0
- npcsh/npc_team/templates/hr_support/raone.npc +0 -0
- npcsh/npc_team/templates/humanities/eriane.npc +0 -4
- npcsh/npc_team/templates/it_support/lineru.npc +0 -0
- npcsh/npc_team/templates/marketing/slean.npc +0 -4
- npcsh/npc_team/templates/philosophy/maurawa.npc +0 -0
- npcsh/npc_team/templates/sales/turnic.npc +0 -4
- npcsh/npc_team/templates/software/welxor.npc +0 -0
- npcsh/npc_team/tools/bash_executer.tool +0 -32
- npcsh/npc_team/tools/calculator.tool +0 -8
- npcsh/npc_team/tools/code_executor.tool +0 -16
- npcsh/npc_team/tools/generic_search.tool +0 -27
- npcsh/npc_team/tools/image_generation.tool +0 -25
- npcsh/npc_team/tools/local_search.tool +0 -149
- npcsh/npc_team/tools/npcsh_executor.tool +0 -9
- npcsh/npc_team/tools/screen_cap.tool +0 -27
- npcsh/npc_team/tools/sql_executor.tool +0 -26
- npcsh/response.py +0 -623
- npcsh/search.py +0 -248
- npcsh/serve.py +0 -1460
- npcsh/shell.py +0 -538
- npcsh/shell_helpers.py +0 -3529
- npcsh/stream.py +0 -700
- npcsh/video.py +0 -49
- npcsh-0.3.31.data/data/npcsh/npc_team/bash_executer.tool +0 -32
- npcsh-0.3.31.data/data/npcsh/npc_team/calculator.tool +0 -8
- npcsh-0.3.31.data/data/npcsh/npc_team/celona.npc +0 -0
- npcsh-0.3.31.data/data/npcsh/npc_team/code_executor.tool +0 -16
- npcsh-0.3.31.data/data/npcsh/npc_team/corca.npc +0 -13
- npcsh-0.3.31.data/data/npcsh/npc_team/eriane.npc +0 -4
- npcsh-0.3.31.data/data/npcsh/npc_team/foreman.npc +0 -7
- npcsh-0.3.31.data/data/npcsh/npc_team/generic_search.tool +0 -27
- npcsh-0.3.31.data/data/npcsh/npc_team/image_generation.tool +0 -25
- npcsh-0.3.31.data/data/npcsh/npc_team/lineru.npc +0 -0
- npcsh-0.3.31.data/data/npcsh/npc_team/local_search.tool +0 -149
- npcsh-0.3.31.data/data/npcsh/npc_team/maurawa.npc +0 -0
- npcsh-0.3.31.data/data/npcsh/npc_team/npcsh.ctx +0 -11
- npcsh-0.3.31.data/data/npcsh/npc_team/npcsh_executor.tool +0 -9
- npcsh-0.3.31.data/data/npcsh/npc_team/raone.npc +0 -0
- npcsh-0.3.31.data/data/npcsh/npc_team/screen_cap.tool +0 -27
- npcsh-0.3.31.data/data/npcsh/npc_team/sibiji.npc +0 -4
- npcsh-0.3.31.data/data/npcsh/npc_team/slean.npc +0 -4
- npcsh-0.3.31.data/data/npcsh/npc_team/sql_executor.tool +0 -26
- npcsh-0.3.31.data/data/npcsh/npc_team/test_pipeline.py +0 -181
- npcsh-0.3.31.data/data/npcsh/npc_team/turnic.npc +0 -4
- npcsh-0.3.31.data/data/npcsh/npc_team/welxor.npc +0 -0
- npcsh-0.3.31.dist-info/METADATA +0 -1853
- npcsh-0.3.31.dist-info/RECORD +0 -76
- npcsh-0.3.31.dist-info/entry_points.txt +0 -3
- {npcsh-0.3.31.dist-info → npcsh-1.0.0.dist-info}/top_level.txt +0 -0
npcsh/audio.py
DELETED
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
# Move optional imports into try/except
|
|
2
|
-
try:
|
|
3
|
-
import whisper
|
|
4
|
-
from playsound import playsound
|
|
5
|
-
from gtts import gTTS
|
|
6
|
-
import pyaudio
|
|
7
|
-
except Exception as e:
|
|
8
|
-
print(f"Error importing audio dependencies: {e}")
|
|
9
|
-
|
|
10
|
-
import numpy as np
|
|
11
|
-
import tempfile
|
|
12
|
-
import os
|
|
13
|
-
import time
|
|
14
|
-
from typing import Optional, List
|
|
15
|
-
from .llm_funcs import get_llm_response
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def get_audio_level(audio_data):
|
|
19
|
-
return np.max(np.abs(np.frombuffer(audio_data, dtype=np.int16)))
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def calibrate_silence(sample_rate=16000, duration=2):
|
|
23
|
-
"""
|
|
24
|
-
Function Description:
|
|
25
|
-
This function calibrates the silence level for audio recording.
|
|
26
|
-
Args:
|
|
27
|
-
None
|
|
28
|
-
Keyword Args:
|
|
29
|
-
sample_rate: The sample rate for audio recording.
|
|
30
|
-
duration: The duration in seconds for calibration.
|
|
31
|
-
Returns:
|
|
32
|
-
The silence threshold level.
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
p = pyaudio.PyAudio()
|
|
36
|
-
stream = p.open(
|
|
37
|
-
format=pyaudio.paInt16,
|
|
38
|
-
channels=1,
|
|
39
|
-
rate=sample_rate,
|
|
40
|
-
input=True,
|
|
41
|
-
frames_per_buffer=1024,
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
print("Calibrating silence level. Please remain quiet...")
|
|
45
|
-
levels = []
|
|
46
|
-
for _ in range(int(sample_rate * duration / 1024)):
|
|
47
|
-
data = stream.read(1024)
|
|
48
|
-
levels.append(get_audio_level(data))
|
|
49
|
-
|
|
50
|
-
stream.stop_stream()
|
|
51
|
-
stream.close()
|
|
52
|
-
p.terminate()
|
|
53
|
-
|
|
54
|
-
avg_level = np.mean(levels)
|
|
55
|
-
silence_threshold = avg_level * 1.5 # Set threshold slightly above average
|
|
56
|
-
print(f"Silence threshold set to: {silence_threshold}")
|
|
57
|
-
return silence_threshold
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def is_silent(audio_data: bytes, threshold: float) -> bool:
|
|
61
|
-
"""
|
|
62
|
-
Function Description:
|
|
63
|
-
This function checks if audio data is silent based on a threshold.
|
|
64
|
-
Args:
|
|
65
|
-
audio_data: The audio data to check.
|
|
66
|
-
threshold: The silence threshold level.
|
|
67
|
-
Keyword Args:
|
|
68
|
-
None
|
|
69
|
-
Returns:
|
|
70
|
-
A boolean indicating whether the audio is silent.
|
|
71
|
-
"""
|
|
72
|
-
|
|
73
|
-
return get_audio_level(audio_data) < threshold
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def record_audio(
|
|
77
|
-
sample_rate: int = 16000,
|
|
78
|
-
max_duration: int = 10,
|
|
79
|
-
silence_threshold: Optional[float] = None,
|
|
80
|
-
) -> bytes:
|
|
81
|
-
"""
|
|
82
|
-
Function Description:
|
|
83
|
-
This function records audio from the microphone.
|
|
84
|
-
Args:
|
|
85
|
-
None
|
|
86
|
-
Keyword Args:
|
|
87
|
-
sample_rate: The sample rate for audio recording.
|
|
88
|
-
max_duration: The maximum duration in seconds.
|
|
89
|
-
silence_threshold: The silence threshold level.
|
|
90
|
-
Returns:
|
|
91
|
-
The recorded audio data.
|
|
92
|
-
"""
|
|
93
|
-
|
|
94
|
-
if silence_threshold is None:
|
|
95
|
-
silence_threshold = calibrate_silence()
|
|
96
|
-
|
|
97
|
-
p = pyaudio.PyAudio()
|
|
98
|
-
stream = p.open(
|
|
99
|
-
format=pyaudio.paInt16,
|
|
100
|
-
channels=1,
|
|
101
|
-
rate=sample_rate,
|
|
102
|
-
input=True,
|
|
103
|
-
frames_per_buffer=1024,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
print("Listening... (speak now)")
|
|
107
|
-
frames = []
|
|
108
|
-
silent_chunks = 0
|
|
109
|
-
has_speech = False
|
|
110
|
-
max_silent_chunks = int(sample_rate * 3.0 / 1024) # 3.0 seconds of silence
|
|
111
|
-
max_chunks = int(sample_rate * max_duration / 1024) # Maximum duration in chunks
|
|
112
|
-
|
|
113
|
-
start_time = time.time()
|
|
114
|
-
for _ in range(max_chunks):
|
|
115
|
-
data = stream.read(1024)
|
|
116
|
-
frames.append(data)
|
|
117
|
-
|
|
118
|
-
if is_silent(data, silence_threshold):
|
|
119
|
-
silent_chunks += 1
|
|
120
|
-
if has_speech and silent_chunks > max_silent_chunks:
|
|
121
|
-
break
|
|
122
|
-
else:
|
|
123
|
-
silent_chunks = 0
|
|
124
|
-
has_speech = True
|
|
125
|
-
|
|
126
|
-
if len(frames) % 10 == 0: # Print a dot every ~0.5 seconds
|
|
127
|
-
print(".", end="", flush=True)
|
|
128
|
-
|
|
129
|
-
if time.time() - start_time > max_duration:
|
|
130
|
-
print("\nMax duration reached.")
|
|
131
|
-
break
|
|
132
|
-
|
|
133
|
-
print("\nProcessing...")
|
|
134
|
-
|
|
135
|
-
stream.stop_stream()
|
|
136
|
-
stream.close()
|
|
137
|
-
p.terminate()
|
|
138
|
-
|
|
139
|
-
return b"".join(frames)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def speak_text(text: str) -> None:
|
|
143
|
-
"""
|
|
144
|
-
Function Description:
|
|
145
|
-
This function converts text to speech and plays the audio.
|
|
146
|
-
Args:
|
|
147
|
-
text: The text to convert to speech.
|
|
148
|
-
Keyword Args:
|
|
149
|
-
None
|
|
150
|
-
Returns:
|
|
151
|
-
None
|
|
152
|
-
"""
|
|
153
|
-
|
|
154
|
-
try:
|
|
155
|
-
tts = gTTS(text=text, lang="en")
|
|
156
|
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as fp:
|
|
157
|
-
tts.save(fp.name)
|
|
158
|
-
playsound(fp.name)
|
|
159
|
-
os.unlink(fp.name)
|
|
160
|
-
except Exception as e:
|
|
161
|
-
print(f"Text-to-speech error: {e}")
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def process_audio(file_path: str, table_name: str) -> List:
|
|
165
|
-
"""
|
|
166
|
-
Function Description:
|
|
167
|
-
This function is used to process an audio file.
|
|
168
|
-
Args:
|
|
169
|
-
file_path : str : The file path.
|
|
170
|
-
table_name : str : The table name.
|
|
171
|
-
Keyword Args:
|
|
172
|
-
None
|
|
173
|
-
Returns:
|
|
174
|
-
List : The embeddings and texts.
|
|
175
|
-
"""
|
|
176
|
-
|
|
177
|
-
embeddings = []
|
|
178
|
-
texts = []
|
|
179
|
-
try:
|
|
180
|
-
audio, sr = librosa.load(file_path)
|
|
181
|
-
# Transcribe audio using Whisper
|
|
182
|
-
model = whisper.load_model("base") # Or a larger model if available
|
|
183
|
-
result = model.transcribe(file_path)
|
|
184
|
-
transcribed_text = result["text"].strip()
|
|
185
|
-
|
|
186
|
-
# Split transcribed text into chunks (adjust chunk_size as needed)
|
|
187
|
-
chunk_size = 1000
|
|
188
|
-
for i in range(0, len(transcribed_text), chunk_size):
|
|
189
|
-
chunk = transcribed_text[i : i + chunk_size]
|
|
190
|
-
text_embedding_response = get_llm_response(
|
|
191
|
-
f"Generate an embedding for: {chunk}",
|
|
192
|
-
model="text-embedding-ada-002",
|
|
193
|
-
provider="openai",
|
|
194
|
-
) # Use a text embedding model
|
|
195
|
-
if (
|
|
196
|
-
isinstance(text_embedding_response, dict)
|
|
197
|
-
and "error" in text_embedding_response
|
|
198
|
-
):
|
|
199
|
-
print(
|
|
200
|
-
f"Error generating text embedding: {text_embedding_response['error']}"
|
|
201
|
-
)
|
|
202
|
-
else:
|
|
203
|
-
embeddings.append(text_embedding_response) # Store the embedding
|
|
204
|
-
texts.append(chunk) # Store the corresponding text chunk
|
|
205
|
-
|
|
206
|
-
return embeddings, texts
|
|
207
|
-
|
|
208
|
-
except Exception as e:
|
|
209
|
-
print(f"Error processing audio: {e}")
|
|
210
|
-
return [], [] # Return empty lists in case of error
|