Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vox",
"version": "3.1.1",
"version": "3.1.2",
"description": "Agent-facing speech to text and text to speech over Alibaba Model Studio.",
"repository": "https://github.com/celados/vox",
"bin": {
Expand Down
2 changes: 1 addition & 1 deletion src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Local, Apple Silicon, needs `uv` and `ffmpeg`. Voiceprints are personal voice da

A vocabulary is a YAML file you write at `~/.vox/vocabulary/<name>.yaml`; there is no create or edit command. `hear --vocab <name>` syncs on demand, and editing the file changes the run id. It only biases domain terms; it cannot rescue bad audio. File format and quota: `vox @skill references/vocab.md`.

## Speaking — `.{say,voice,cache}`
## Speaking — `.{say,voice}`

- Multi-line text goes as the whole input in YAML (`vox say - <<'EOF'` with `text: |`), not inside a JSON object. A script already on disk is `text: { ref: 'file:<path>' }`; don't paste it back.
- System voices: Cherry, Ethan, Chelsie, Serena (zh/en), Dylan (Beijing), Jada (Shanghai), Sunny (Sichuan). `--output` writes a WAV and does not play.
Expand Down
4 changes: 3 additions & 1 deletion src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ test("@schema exposes the dotted command surface", async () => {
"### say\n",
"### voice.*\n",
"### voice.record\n",
"### cache.*\n",
]) {
expect(stdout).toContain(fragment);
}
// Legacy cache ops are hidden from the overview but still addressable by path.
expect(stdout).not.toContain("### cache");
expect((await run(["@schema", ".cache"])).stdout).toContain("### cache.clear\n");
expect(stdout).not.toContain("### dashscope");
expect(stdout).not.toContain("### auth");
expect(stdout).not.toContain("values:");
Expand Down
21 changes: 13 additions & 8 deletions src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const hear = c
.meta({
description:
"Transcribe audio into a cached run and Markdown file, optionally identify enrolled speakers",
examples: ["vox hear \"{ file: 'lecture.mp3', lang: ['zh'], speakers: true }\""],
})
.input(
s(
Expand Down Expand Up @@ -125,7 +124,6 @@ const exportCmd = c
.meta({
description:
"Render a stored run as srt, vtt, md, txt, or json. stdout is the document unless output is set",
examples: ["vox export --sid a3f1c2 --format srt --output meeting.srt"],
})
.input(
s(
Expand All @@ -148,7 +146,6 @@ const vocab = group(
.meta({
description:
"Push local YAML to the server for a target model. hear --vocab syncs on demand",
examples: ["vox vocab.sync --all --model qwen"],
})
.input(
s(
Expand All @@ -172,8 +169,7 @@ const vocab = group(

const say = c
.meta({
description:
"Speak text with TTS. Multi-line text: whole input as YAML with text: |, or a file with text: { ref: 'file:…' }",
description: "Speak text with TTS",
examples: [
"vox say - <<'EOF'\nvoice: Cherry\ntext: |\n First line.\n Slow and clear.\nEOF",
"vox say \"{ text: { ref: 'file:script.txt' }, voice: 'Cherry' }\"",
Expand All @@ -186,9 +182,18 @@ const say = c
text: ref(v.pipe(v.string(), v.minLength(1)), [file()], {
description: "Text to speak, or a text file read verbatim",
}),
voice: v.optional(v.string()),
voice: v.optional(
v.pipe(
v.string(),
v.description(
"System or cloned voice name; see voice.list. Omitted: the last used voice, else Cherry",
),
),
),
lang: v.optional(v.string(), "auto"),
instruct: v.optional(v.string()),
instruct: v.optional(
v.pipe(v.string(), v.description("Free-text delivery style, honored by system voices")),
),
speed: v.optional(v.number(), 1),
output: v.optional(v.string()),
noCache: v.optional(v.boolean(), false),
Expand Down Expand Up @@ -226,7 +231,7 @@ const voice = group(
);

const cache = group(
{ description: "TTS audio cache (legacy; not content-addressed runs)" },
{ description: "TTS audio cache (legacy; not content-addressed runs)", hidden: true },
{
status: c
.meta({ description: "Show cache path, file count, and bytes" })
Expand Down
Loading