pi-voicekit 0.2.1 → 0.2.3
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/README.md
CHANGED
|
@@ -399,6 +399,10 @@ Every dictation also writes one `voice-polish` entry into the session file: the
|
|
|
399
399
|
transcript, what reached the editor and why the pass decided that. The model never sees
|
|
400
400
|
these entries — they are not part of the conversation context — so they are there for
|
|
401
401
|
analysis, and they do keep the raw text on disk for as long as the session file exists.
|
|
402
|
+
Each entry also records how the pass was configured: the transcript length on its own
|
|
403
|
+
(separate from any text already in the editor), whether thinking was turned off for it,
|
|
404
|
+
and the output-token cap it carried, plus the audio seconds it covered and which recogniser
|
|
405
|
+
produced it — which is what makes polish time readable as a speedup.
|
|
402
406
|
|
|
403
407
|
| Setting | Scope | Default | Notes |
|
|
404
408
|
| ------------------------- | ------------------ | ----------- | ------------------------------------------------------- |
|
|
@@ -69,7 +69,10 @@ If nothing in <TRANSCRIPT> can be cleaned, return it unchanged.
|
|
|
69
69
|
*/
|
|
70
70
|
export function polishMaxTokens(rawChars: number): number {
|
|
71
71
|
const bounded = Number.isFinite(rawChars) ? Math.max(1, Math.floor(rawChars)) : 1;
|
|
72
|
-
|
|
72
|
+
// The floor is 2048 because thinking is not bounded by the input length: a 76-character
|
|
73
|
+
// dictation spent about 1,200 reasoning tokens, so the earlier 1024 floor truncated it and
|
|
74
|
+
// dropped the pass back to the raw transcript after a 7.6 s wait.
|
|
75
|
+
return Math.min(4096, Math.max(2048, Math.ceil(bounded * 2) + 512));
|
|
73
76
|
}
|
|
74
77
|
|
|
75
78
|
function renderContext(context: AssembledContext): string {
|
|
@@ -240,6 +240,18 @@ export interface PolishAudit {
|
|
|
240
240
|
latencyMs?: number;
|
|
241
241
|
contextChars?: number;
|
|
242
242
|
truncated?: boolean;
|
|
243
|
+
/** Characters of the dictation itself, excluding text already in the editor. */
|
|
244
|
+
transcriptChars?: number;
|
|
245
|
+
/** Characters of the editor prefix, which is not part of the transcript. */
|
|
246
|
+
editorPrefixChars?: number;
|
|
247
|
+
/** Seconds of audio the dictation covered, so polish time can be read as a speedup. */
|
|
248
|
+
durationSec?: number;
|
|
249
|
+
/** Which recogniser produced it, so results are never pooled across backends. */
|
|
250
|
+
backend?: string;
|
|
251
|
+
/** True when the pass asked the model not to think. */
|
|
252
|
+
thinkingOff?: boolean;
|
|
253
|
+
/** The output-token cap the request carried, a cap and not a spend. */
|
|
254
|
+
maxTokens?: number;
|
|
243
255
|
}
|
|
244
256
|
|
|
245
257
|
export function buildPolishAudit(input: {
|
|
@@ -248,6 +260,12 @@ export function buildPolishAudit(input: {
|
|
|
248
260
|
status?: string;
|
|
249
261
|
disposition?: string;
|
|
250
262
|
reason?: string;
|
|
263
|
+
transcriptChars?: number;
|
|
264
|
+
editorPrefixChars?: number;
|
|
265
|
+
thinkingOff?: boolean;
|
|
266
|
+
durationSec?: number;
|
|
267
|
+
backend?: string;
|
|
268
|
+
maxTokens?: number;
|
|
251
269
|
telemetry?: {
|
|
252
270
|
model?: string;
|
|
253
271
|
configured?: string;
|
|
@@ -266,6 +284,12 @@ export function buildPolishAudit(input: {
|
|
|
266
284
|
if (input.status !== undefined) audit.status = input.status;
|
|
267
285
|
if (input.disposition !== undefined) audit.disposition = input.disposition;
|
|
268
286
|
if (input.reason !== undefined) audit.reason = input.reason;
|
|
287
|
+
if (input.transcriptChars !== undefined) audit.transcriptChars = input.transcriptChars;
|
|
288
|
+
if (input.editorPrefixChars !== undefined) audit.editorPrefixChars = input.editorPrefixChars;
|
|
289
|
+
if (input.thinkingOff !== undefined) audit.thinkingOff = input.thinkingOff;
|
|
290
|
+
if (input.maxTokens !== undefined) audit.maxTokens = input.maxTokens;
|
|
291
|
+
if (input.durationSec !== undefined) audit.durationSec = input.durationSec;
|
|
292
|
+
if (input.backend !== undefined) audit.backend = input.backend;
|
|
269
293
|
const telemetry = input.telemetry;
|
|
270
294
|
if (telemetry) {
|
|
271
295
|
if (telemetry.model !== undefined) audit.model = telemetry.model;
|
package/extensions/voice.ts
CHANGED
|
@@ -114,6 +114,7 @@ import {
|
|
|
114
114
|
resolveModelChoice,
|
|
115
115
|
} from "./voice/post-process";
|
|
116
116
|
import { DEFAULT_CONTEXT_LIMITS } from "./voice/post-process-context";
|
|
117
|
+
import { polishMaxTokens } from "./voice/post-process-prompt";
|
|
117
118
|
|
|
118
119
|
/** Adapter for the real event loop — lets GapTimer run under the real setTimeout. */
|
|
119
120
|
const realTimerPort: TimerPort = {
|
|
@@ -883,6 +884,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
883
884
|
ms: number;
|
|
884
885
|
contextChars?: number;
|
|
885
886
|
truncated?: boolean;
|
|
887
|
+
/** Recorded so a slow or truncated pass can be diagnosed without reading code. */
|
|
888
|
+
thinkingOff?: boolean;
|
|
889
|
+
maxTokens?: number;
|
|
886
890
|
reason?: string;
|
|
887
891
|
error?: string;
|
|
888
892
|
};
|
|
@@ -987,6 +991,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
987
991
|
const telemetry = {
|
|
988
992
|
model: polishModelLabel(choice),
|
|
989
993
|
configured: choice.ref,
|
|
994
|
+
// Pure and cheap, so computing it twice (here and in the call options) is fine, and it
|
|
995
|
+
// keeps the audit entry honest about what the pass decided.
|
|
996
|
+
thinkingOff: Boolean(polishSamplingOptions(model as { reasoning?: boolean }, raw.length).samplingParams),
|
|
997
|
+
maxTokens: polishMaxTokens(raw.length),
|
|
990
998
|
status: result.status,
|
|
991
999
|
ms: Date.now() - started,
|
|
992
1000
|
contextChars: result.contextChars,
|
|
@@ -1818,6 +1826,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
1818
1826
|
"voice-polish",
|
|
1819
1827
|
buildPolishAudit({
|
|
1820
1828
|
raw: prefix + fullText,
|
|
1829
|
+
transcriptChars: fullText.length,
|
|
1830
|
+
editorPrefixChars: prefix.length,
|
|
1831
|
+
thinkingOff: polishTelemetry?.thinkingOff,
|
|
1832
|
+
maxTokens: polishTelemetry?.maxTokens,
|
|
1833
|
+
durationSec: Number(elapsed),
|
|
1834
|
+
backend: config.backend,
|
|
1821
1835
|
written: wroteEditor ? finalText : undefined,
|
|
1822
1836
|
status: final.status,
|
|
1823
1837
|
disposition: final.disposition,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-voicekit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Voice in + voice out for Pi CLI — hold-to-talk STT (Deepgram streaming or 21 offline models) plus TTS (Kitten Nano, Piper, Kokoro, or Deepgram Aura)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|