@p8n.ai/pi-listens 0.1.0
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.
- package/CHANGELOG.md +27 -0
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/package.json +70 -0
- package/skills/pi-listens/SKILL.md +33 -0
- package/src/audio.ts +361 -0
- package/src/commands.ts +286 -0
- package/src/config.ts +182 -0
- package/src/index.ts +84 -0
- package/src/sarvam.ts +311 -0
- package/src/text.ts +33 -0
- package/src/tools.ts +252 -0
- package/src/voice-ui.ts +350 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@p8n.ai/pi-listens` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
This project follows [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-05-09
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Initial release of `@p8n.ai/pi-listens` for Pi.
|
|
14
|
+
- Sarvam AI speech-to-text tools for microphone input and audio file transcription.
|
|
15
|
+
- Sarvam AI text-to-speech tools for spoken output and spoken clarification loops.
|
|
16
|
+
- `/listen`, `/speak`, `/voice-on`, and `/voice-status` slash commands.
|
|
17
|
+
- Interactive voice panel with listen, auto-listen, read-aloud, and close controls.
|
|
18
|
+
- Config support through environment variables, user config, and project config.
|
|
19
|
+
- Global config at `~/.pi/pi-listens.json`, with project-level overrides from `<project>/.pi/pi-listens.json`.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Stop active audio capture/playback subprocesses when voice mode is closed or the Pi session shuts down.
|
|
24
|
+
- Clean up generated audio files when spoken playback is interrupted.
|
|
25
|
+
|
|
26
|
+
[Unreleased]: https://github.com/p8n-ai/pi-listens/compare/v0.1.0...HEAD
|
|
27
|
+
[0.1.0]: https://github.com/p8n-ai/pi-listens/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ravindra Barthwal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# @p8n.ai/pi-listens
|
|
2
|
+
|
|
3
|
+
Speech-first Pi package powered by [Sarvam AI](https://www.sarvam.ai/). It gives Pi tools and commands for:
|
|
4
|
+
|
|
5
|
+
- streaming speech-to-text (STT) with Sarvam Saaras (`saaras:v3`) over WebSockets
|
|
6
|
+
- text-to-speech (TTS) with Sarvam Bulbul (`bulbul:v3`)
|
|
7
|
+
- voice-first clarification loops where the agent speaks a question, listens, transcribes, and continues
|
|
8
|
+
- interactive TUI and headless/RPC usage through Pi extension tools and UI fallback
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pi install npm:@p8n.ai/pi-listens
|
|
14
|
+
export SARVAM_API_KEY="your-sarvam-api-key"
|
|
15
|
+
pi
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
For local development from this checkout:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install
|
|
22
|
+
npm run typecheck
|
|
23
|
+
pi -e /Users/ravindrabarthwal/Projects/pi-listens
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## System requirements
|
|
27
|
+
|
|
28
|
+
### Sarvam API key
|
|
29
|
+
|
|
30
|
+
Set one of:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
export SARVAM_API_KEY="..."
|
|
34
|
+
# or
|
|
35
|
+
export SARVAM_API_SUBSCRIPTION_KEY="..."
|
|
36
|
+
# or
|
|
37
|
+
export PI_LISTENS_SARVAM_API_KEY="..."
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Sarvam's SDK uses the `api-subscription-key` auth model internally; this package uses the official `sarvamai` npm package.
|
|
41
|
+
|
|
42
|
+
### Local microphone recorder and audio player
|
|
43
|
+
|
|
44
|
+
`pi-listens` records from the local microphone and plays audio locally.
|
|
45
|
+
|
|
46
|
+
Auto-detected recorders:
|
|
47
|
+
|
|
48
|
+
1. `rec` from SoX (recommended)
|
|
49
|
+
2. `ffmpeg` (`avfoundation` on macOS, `alsa` on Linux)
|
|
50
|
+
|
|
51
|
+
Auto-detected players:
|
|
52
|
+
|
|
53
|
+
1. `afplay` on macOS
|
|
54
|
+
2. `play` from SoX
|
|
55
|
+
3. `ffplay`
|
|
56
|
+
4. `aplay`
|
|
57
|
+
|
|
58
|
+
You can override capture/playback with command templates:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
export PI_LISTENS_RECORD_COMMAND='rec -q -r {sampleRate} -c 1 -b 16 {path} trim 0 {seconds}'
|
|
62
|
+
export PI_LISTENS_STREAM_COMMAND='rec -q -r {sampleRate} -c 1 -b 16 -e signed-integer -t raw -'
|
|
63
|
+
export PI_LISTENS_PLAY_COMMAND='afplay {path}'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Template variables are shell-quoted automatically. Recording templates support `{path}`, `{seconds}`, `{sampleRate}`. Streaming templates write 16-bit mono PCM to stdout and support `{sampleRate}`.
|
|
67
|
+
|
|
68
|
+
## Agent tools
|
|
69
|
+
|
|
70
|
+
The package registers these tools for Pi's agent:
|
|
71
|
+
|
|
72
|
+
| Tool | Purpose |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| `voice_output` | Speak short user-facing text via Sarvam TTS and local playback. |
|
|
75
|
+
| `voice_input` | Stream microphone audio over Sarvam WebSocket STT. |
|
|
76
|
+
| `voice_ask` | Speak a concise question, then listen and transcribe the user's answer. |
|
|
77
|
+
| `voice_transcribe_file` | Transcribe an existing audio file. |
|
|
78
|
+
| `voice_setup_check` | Check API key, recorder, player, and model configuration. |
|
|
79
|
+
|
|
80
|
+
The extension also injects voice guidance into the system prompt:
|
|
81
|
+
|
|
82
|
+
- use `voice_ask` whenever user input is needed in voice-first sessions
|
|
83
|
+
- use `voice_output` for short spoken status or response snippets
|
|
84
|
+
- do not speak code blocks, logs, diffs, stack traces, or long explanations
|
|
85
|
+
- keep spoken questions concise and answerable in a short response
|
|
86
|
+
|
|
87
|
+
## Commands
|
|
88
|
+
|
|
89
|
+
| Command | Purpose |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| `/listen [seconds]` | Stream one utterance over Sarvam WebSocket STT, wait for a sustained silence boundary, transcribe, and send it to Pi as a user message. |
|
|
92
|
+
| `/speak <text>` | Speak text with Sarvam TTS. |
|
|
93
|
+
| `/voice-on [--speak] [--manual] [--no-listen] [seconds]` | Open the hands-free TUI panel. By default it listens now and auto-listens again after each agent response. `--speak` reads short assistant replies aloud. `--manual` leaves the panel active but only listens when you press R. |
|
|
94
|
+
| `/voice-on --no-speak` | Open the panel without auto-reading assistant replies. |
|
|
95
|
+
| `/voice-status` | Show setup and voice-mode status. |
|
|
96
|
+
|
|
97
|
+
Voice panel controls in interactive mode:
|
|
98
|
+
- R: listen now; press again while listening to stop listening
|
|
99
|
+
- A: auto-listen on/off (listen again after each assistant reply)
|
|
100
|
+
- S: read aloud on/off (speak assistant replies)
|
|
101
|
+
- Q: close the panel (and stop listening first if needed)
|
|
102
|
+
- Click the orb: visual ripple feedback (terminals with mouse reporting)
|
|
103
|
+
|
|
104
|
+
## Headless/RPC behavior
|
|
105
|
+
|
|
106
|
+
Pi extension tools work in interactive TUI and headless/RPC modes.
|
|
107
|
+
|
|
108
|
+
- The audio capture/playback still happens on the machine running Pi.
|
|
109
|
+
- When speech is not recognized, `voice_input` and `voice_ask` use Pi's extension UI text fallback if UI is available.
|
|
110
|
+
- In RPC mode that fallback becomes an `extension_ui_request` (`input`) event, so a client can provide textual input.
|
|
111
|
+
- In print/JSON modes, UI fallback is unavailable; the tool returns the empty transcription so the agent can recover.
|
|
112
|
+
|
|
113
|
+
## Configuration
|
|
114
|
+
|
|
115
|
+
Configuration is resolved in this order, with later entries overriding earlier ones:
|
|
116
|
+
|
|
117
|
+
1. defaults
|
|
118
|
+
2. `~/.pi/agent/pi-listens.json` (legacy global path, still supported)
|
|
119
|
+
3. `~/.pi/pi-listens.json` (global user config)
|
|
120
|
+
4. `<project>/.pi/pi-listens.json` (project config)
|
|
121
|
+
5. environment variables
|
|
122
|
+
|
|
123
|
+
Project config overrides global config, and environment variables override both.
|
|
124
|
+
|
|
125
|
+
Example config file:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"sttModel": "saaras:v3",
|
|
130
|
+
"sttMode": "transcribe",
|
|
131
|
+
"sttLanguageCode": "unknown",
|
|
132
|
+
"translateInputToEnglish": true,
|
|
133
|
+
"ttsModel": "bulbul:v3",
|
|
134
|
+
"ttsLanguageCode": "en-IN",
|
|
135
|
+
"ttsSpeaker": "shubh",
|
|
136
|
+
"recordSeconds": 300,
|
|
137
|
+
"recordSampleRate": 16000,
|
|
138
|
+
"streamChunkMs": 250,
|
|
139
|
+
"streamMaxSeconds": 300,
|
|
140
|
+
"silenceStartSeconds": 0.2,
|
|
141
|
+
"silenceStopSeconds": 3.5,
|
|
142
|
+
"silenceThreshold": "1%",
|
|
143
|
+
"ttsSampleRate": 24000,
|
|
144
|
+
"ttsOutputCodec": "wav",
|
|
145
|
+
"textFallback": true,
|
|
146
|
+
"autoSpeakAssistant": false,
|
|
147
|
+
"maxAutoSpeakChars": 900
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Supported environment variables:
|
|
152
|
+
|
|
153
|
+
- `SARVAM_API_KEY` / `SARVAM_API_SUBSCRIPTION_KEY` / `PI_LISTENS_SARVAM_API_KEY`
|
|
154
|
+
- `PI_LISTENS_STT_MODEL`
|
|
155
|
+
- `PI_LISTENS_STT_MODE` (`transcribe`, `translate`, `verbatim`, `translit`, `codemix`)
|
|
156
|
+
- `PI_LISTENS_STT_LANGUAGE` (default `unknown`)
|
|
157
|
+
- `PI_LISTENS_TRANSLATE_INPUT_TO_ENGLISH` (default `true`; speak any supported language, send English to the agent)
|
|
158
|
+
- `PI_LISTENS_TTS_MODEL`
|
|
159
|
+
- `PI_LISTENS_TTS_LANGUAGE` (default `en-IN`)
|
|
160
|
+
- `PI_LISTENS_TTS_SPEAKER` (default `shubh`)
|
|
161
|
+
- `PI_LISTENS_TTS_PACE`
|
|
162
|
+
- `PI_LISTENS_TTS_TEMPERATURE`
|
|
163
|
+
- `PI_LISTENS_TTS_SAMPLE_RATE`
|
|
164
|
+
- `PI_LISTENS_TTS_OUTPUT_CODEC` (`wav`, `mp3`, `linear16`, `mulaw`, `alaw`, `opus`, `flac`, `aac`)
|
|
165
|
+
- `PI_LISTENS_RECORD_SECONDS` (default `300`; maximum listen duration for one streaming utterance)
|
|
166
|
+
- `PI_LISTENS_RECORD_SAMPLE_RATE` (default `16000`; Sarvam streaming works best with 16kHz mono PCM)
|
|
167
|
+
- `PI_LISTENS_STREAM_CHUNK_MS` (default `250`; outgoing WebSocket audio chunk size)
|
|
168
|
+
- `PI_LISTENS_STREAM_MAX_SECONDS` (default `300`; default maximum for streaming microphone capture)
|
|
169
|
+
- `PI_LISTENS_SILENCE_START_SECONDS`
|
|
170
|
+
- `PI_LISTENS_SILENCE_STOP_SECONDS`
|
|
171
|
+
- `PI_LISTENS_SILENCE_THRESHOLD`
|
|
172
|
+
|
|
173
|
+
`recordSeconds` is the maximum time Pi will keep streaming one utterance. `silenceStopSeconds` is the quiet pause after which it considers the utterance complete, flushes the WebSocket, and submits the transcript. For example, `recordSeconds: 300` and `silenceStopSeconds: 3.5` means “let me speak for up to 5 minutes, but submit after 3.5 seconds of silence.”
|
|
174
|
+
- `PI_LISTENS_RECORD_COMMAND`
|
|
175
|
+
- `PI_LISTENS_PLAY_COMMAND`
|
|
176
|
+
- `PI_LISTENS_AUDIO_DIR`
|
|
177
|
+
- `PI_LISTENS_DELETE_AUDIO`
|
|
178
|
+
- `PI_LISTENS_TEXT_FALLBACK`
|
|
179
|
+
- `PI_LISTENS_AUTO_SPEAK`
|
|
180
|
+
- `PI_LISTENS_MAX_AUTO_SPEAK_CHARS`
|
|
181
|
+
|
|
182
|
+
## Notes
|
|
183
|
+
|
|
184
|
+
- Sarvam STT uses the WebSocket streaming API for microphone input, not the 30-second synchronous REST endpoint.
|
|
185
|
+
- Streaming input is sent as 16kHz, 16-bit, mono PCM (`pcm_s16le`) with `saaras:v3` by default.
|
|
186
|
+
- macOS may ask for microphone permissions the first time `rec` or `ffmpeg` records audio.
|
|
187
|
+
- Spoken output is intentionally optimized for concise interaction, not for reading code or full agent responses.
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@p8n.ai/pi-listens",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Pi package for speech-first interaction using Sarvam AI speech-to-text and text-to-speech.",
|
|
5
|
+
"author": "Ravindra Barthwal",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/p8n-ai/pi-listens.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/p8n-ai/pi-listens#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/p8n-ai/pi-listens/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"pi-package",
|
|
18
|
+
"pi",
|
|
19
|
+
"pi-coding-agent",
|
|
20
|
+
"speech-to-text",
|
|
21
|
+
"text-to-speech",
|
|
22
|
+
"voice",
|
|
23
|
+
"sarvam",
|
|
24
|
+
"sarvam-ai",
|
|
25
|
+
"agents"
|
|
26
|
+
],
|
|
27
|
+
"files": [
|
|
28
|
+
"src/",
|
|
29
|
+
"skills/",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"CHANGELOG.md"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"test": "npm run typecheck"
|
|
37
|
+
},
|
|
38
|
+
"pi": {
|
|
39
|
+
"extensions": [
|
|
40
|
+
"./src/index.ts"
|
|
41
|
+
],
|
|
42
|
+
"skills": [
|
|
43
|
+
"./skills"
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"sarvamai": "^1.1.7"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@earendil-works/pi-ai": "*",
|
|
51
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
52
|
+
"@earendil-works/pi-tui": "*",
|
|
53
|
+
"typebox": "*"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@earendil-works/pi-ai": "^0.74.0",
|
|
57
|
+
"@earendil-works/pi-coding-agent": "^0.74.0",
|
|
58
|
+
"@earendil-works/pi-tui": "^0.74.0",
|
|
59
|
+
"@types/node": "^24.0.0",
|
|
60
|
+
"tsx": "^4.21.0",
|
|
61
|
+
"typebox": "^1.1.38",
|
|
62
|
+
"typescript": "^5.8.0"
|
|
63
|
+
},
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=20"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-listens
|
|
3
|
+
description: Use when interacting with the user by voice through @p8n.ai/pi-listens, Sarvam AI speech-to-text, or Sarvam AI text-to-speech. Applies when the user says they are speaking, wants voice input/output, asks Pi to listen, or when clarification should be gathered by voice.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pi Listens Voice Interaction
|
|
7
|
+
|
|
8
|
+
This Pi package provides voice tools backed by Sarvam AI.
|
|
9
|
+
|
|
10
|
+
## Tools
|
|
11
|
+
|
|
12
|
+
- `voice_output`: speak a short message to the user with Sarvam TTS.
|
|
13
|
+
- `voice_input`: listen to the microphone and transcribe the user's speech.
|
|
14
|
+
- `voice_ask`: speak a concise question, then listen and transcribe the answer.
|
|
15
|
+
- `voice_transcribe_file`: transcribe an existing audio file.
|
|
16
|
+
- `voice_setup_check`: diagnose API key, recorder, player, and voice settings.
|
|
17
|
+
|
|
18
|
+
## Usage rules
|
|
19
|
+
|
|
20
|
+
1. When you need user input, clarification, or confirmation, use `voice_ask` instead of asking only in text.
|
|
21
|
+
2. Before using `voice_input`, make sure the user already knows you are listening. If not, use `voice_ask`.
|
|
22
|
+
3. Use `voice_output` for concise spoken status updates or spoken summaries that matter to the user.
|
|
23
|
+
4. Do not speak code blocks, diffs, stack traces, logs, long tables, or lengthy explanations. Summarize briefly and leave details in text.
|
|
24
|
+
5. Treat transcripts returned by `voice_input` or `voice_ask` as user input, while allowing for speech-recognition mistakes. If the transcript is ambiguous, ask a short follow-up with `voice_ask`.
|
|
25
|
+
6. If speech is not recognized, rely on the tool's text fallback when available, or ask again with a shorter prompt.
|
|
26
|
+
|
|
27
|
+
## Good voice question style
|
|
28
|
+
|
|
29
|
+
- Ask one thing at a time.
|
|
30
|
+
- Keep questions under one sentence where possible.
|
|
31
|
+
- Offer clear options if the answer space is constrained.
|
|
32
|
+
- Prefer: "Which option should I use: A, B, or C?"
|
|
33
|
+
- Avoid: long multi-part questions or reading implementation details aloud.
|