From bc18c5818e9f2673c1aa316c6757032f06b68625 Mon Sep 17 00:00:00 2001 From: Eason WaveKat Date: Sun, 19 Jul 2026 22:08:10 +1200 Subject: [PATCH] fix: name Prompt variants via schema titles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Prompt oneOf branches had no titles, so typify fell back to positional Variant0/Variant1 names in the Rust model — every match site needed a comment decoding which was which, and reordering the branches would silently swap the meanings while still compiling. Titling the branches Text / Audio gives Prompt::Text(String) and Prompt::Audio { audio } in Rust, and named Text / Audio aliases in the TS union. Annotation-only: the wire format, validation, and conformance corpus are untouched. Rust consumers matching on the old positional names must rename on upgrade (0.0.x). The TS Prompt union is structurally unchanged. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Hj93UCb3RKjF6mBwzhsp9f --- crates/wavekat-flow/schema/flow.v1.schema.json | 3 ++- crates/wavekat-flow/src/model_ext.rs | 7 +++---- .../src/generated/flow.v1.schema.json | 3 ++- packages/flow-schema/src/generated/model.ts | 18 +++++++++--------- packages/flow-schema/src/generated/schema.ts | 2 ++ schema/flow.v1.schema.json | 3 ++- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/crates/wavekat-flow/schema/flow.v1.schema.json b/crates/wavekat-flow/schema/flow.v1.schema.json index 595efde..0f8e812 100644 --- a/crates/wavekat-flow/schema/flow.v1.schema.json +++ b/crates/wavekat-flow/schema/flow.v1.schema.json @@ -42,8 +42,9 @@ "Prompt": { "description": "What a component speaks: TTS text (a bare string) or a reference to a pre-rendered audio asset shipped alongside the flow.", "oneOf": [ - { "type": "string" }, + { "title": "Text", "type": "string" }, { + "title": "Audio", "type": "object", "required": ["audio"], "properties": { diff --git a/crates/wavekat-flow/src/model_ext.rs b/crates/wavekat-flow/src/model_ext.rs index bb932e5..34e9cc0 100644 --- a/crates/wavekat-flow/src/model_ext.rs +++ b/crates/wavekat-flow/src/model_ext.rs @@ -81,12 +81,11 @@ impl Node { impl Prompt { /// The spoken text, or `None` for an audio-asset prompt. Handy for - /// traces and length validation. typify names the untagged variants - /// `Variant0` (text) and `Variant1` (`{ audio }`). + /// traces and length validation. pub fn as_text(&self) -> Option<&str> { match self { - Prompt::Variant0(t) => Some(t.as_str()), - Prompt::Variant1 { .. } => None, + Prompt::Text(t) => Some(t.as_str()), + Prompt::Audio { .. } => None, } } } diff --git a/packages/flow-schema/src/generated/flow.v1.schema.json b/packages/flow-schema/src/generated/flow.v1.schema.json index 595efde..0f8e812 100644 --- a/packages/flow-schema/src/generated/flow.v1.schema.json +++ b/packages/flow-schema/src/generated/flow.v1.schema.json @@ -42,8 +42,9 @@ "Prompt": { "description": "What a component speaks: TTS text (a bare string) or a reference to a pre-rendered audio asset shipped alongside the flow.", "oneOf": [ - { "type": "string" }, + { "title": "Text", "type": "string" }, { + "title": "Audio", "type": "object", "required": ["audio"], "properties": { diff --git a/packages/flow-schema/src/generated/model.ts b/packages/flow-schema/src/generated/model.ts index c02638c..fc4b350 100644 --- a/packages/flow-schema/src/generated/model.ts +++ b/packages/flow-schema/src/generated/model.ts @@ -8,15 +8,8 @@ export type Node = GreetingNode | HoursNode | MenuNode | RingNode | MessageNode /** * What a component speaks: TTS text (a bare string) or a reference to a pre-rendered audio asset shipped alongside the flow. */ -export type Prompt = - | string - | { - /** - * Audio asset ref. A generated-clip ref is a voice_prompts id matching ^vprompt_[a-z0-9]+$. - */ - audio: string; - [k: string]: unknown; - }; +export type Prompt = Text | Audio; +export type Text = string; /** * The cue a message node plays between its prompt and the start of recording. */ @@ -69,6 +62,13 @@ export interface GreetingNode { exits?: Exits; [k: string]: unknown; } +export interface Audio { + /** + * Audio asset ref. A generated-clip ref is a voice_prompts id matching ^vprompt_[a-z0-9]+$. + */ + audio: string; + [k: string]: unknown; +} /** * Wired exits: exit name → target node id. Which names are valid is a property of the node's kind and is checked by the validator, not by this schema. */ diff --git a/packages/flow-schema/src/generated/schema.ts b/packages/flow-schema/src/generated/schema.ts index 244eb9b..bedf61a 100644 --- a/packages/flow-schema/src/generated/schema.ts +++ b/packages/flow-schema/src/generated/schema.ts @@ -54,9 +54,11 @@ const schema = { "description": "What a component speaks: TTS text (a bare string) or a reference to a pre-rendered audio asset shipped alongside the flow.", "oneOf": [ { + "title": "Text", "type": "string" }, { + "title": "Audio", "type": "object", "required": [ "audio" diff --git a/schema/flow.v1.schema.json b/schema/flow.v1.schema.json index 595efde..0f8e812 100644 --- a/schema/flow.v1.schema.json +++ b/schema/flow.v1.schema.json @@ -42,8 +42,9 @@ "Prompt": { "description": "What a component speaks: TTS text (a bare string) or a reference to a pre-rendered audio asset shipped alongside the flow.", "oneOf": [ - { "type": "string" }, + { "title": "Text", "type": "string" }, { + "title": "Audio", "type": "object", "required": ["audio"], "properties": {