diff --git a/app/MindWork AI Studio/Models/Kinds/TranscriptionModelsFamily.cs b/app/MindWork AI Studio/Models/Kinds/TranscriptionModelsFamily.cs
index a2ed9a41..bba1e1e9 100644
--- a/app/MindWork AI Studio/Models/Kinds/TranscriptionModelsFamily.cs
+++ b/app/MindWork AI Studio/Models/Kinds/TranscriptionModelsFamily.cs
@@ -16,7 +16,7 @@ public sealed class TranscriptionModelsFamily : ModelFamily
public override ModelVendor Vendor => ModelVendor.UNKNOWN;
///
- public override ModelSource Source => new("https://huggingface.co/models?pipeline_tag=automatic-speech-recognition", new DateOnly(2026, 9, 19), "Ported from the transcription markers of Provider/ModelKindExtensions.cs, minus the two which their own families now state. Canary came later: the markers never named it, so it reached the answer meant for everything nobody wrote a rule for.");
+ public override ModelSource Source => new("https://huggingface.co/models?pipeline_tag=automatic-speech-recognition", new DateOnly(2026, 9, 19), "Ported from the transcription markers of Provider/ModelKindExtensions.cs, minus the two which their own families now state. Canary and asr came later: the markers named neither, so both reached the answer meant for everything nobody wrote a rule for. Alibaba's speech line is documented at https://www.alibabacloud.com/help/en/model-studio/qwen-asr-api-reference.");
///
protected override void Declare(ModelFamilyBuilder builder)
@@ -33,5 +33,19 @@ public sealed class TranscriptionModelsFamily : ModelFamily
// English word which would otherwise reach into names it has nothing to do with -- the
// same reason the embedding family gives for gte.
builder.Modifier("canary").AsSegment().Inherits();
+
+ //
+ // The abbreviation the whole field goes by, and the one Alibaba names its speech line
+ // after: qwen3-asr-flash, qwen3-asr-1.7b, fun-asr-realtime. Three letters, so a name part
+ // and never a substring -- "laser" and "eraser" carry them without meaning any of this.
+ //
+ builder.Modifier("asr").AsSegment().Inherits();
+
+ //
+ // Alibaba also builds the line into its audio models, and "audio" is the longer word, so
+ // without this the speech synthesis rule would answer for a model which only listens. A
+ // name carrying both words is a transcription model whatever else it is called.
+ //
+ builder.Modifier("audio").AsSegment().AlsoContains("asr").Inherits();
}
}
\ No newline at end of file
diff --git a/app/Tests/Models/Corpus/ModelKindCorpus.cs b/app/Tests/Models/Corpus/ModelKindCorpus.cs
index 54cd29a9..74b32140 100644
--- a/app/Tests/Models/Corpus/ModelKindCorpus.cs
+++ b/app/Tests/Models/Corpus/ModelKindCorpus.cs
@@ -116,6 +116,16 @@ public static class ModelKindCorpus
// sees the name, so what is left has to carry the word on its own.
new(SELF_HOSTED, "canary-1b-flash", TRANSCRIPTION),
new(SELF_HOSTED, "nvidia/canary-180m-flash", TRANSCRIPTION),
+
+ //
+ // Alibaba's speech line. Every one of these begins with the letter the Alibaba Cloud
+ // provider kept its whole chat list by, so all of them stood among the models somebody
+ // talks to. The last one carries two words at once, and the one which decides is not the
+ // longer one.
+ //
+ new(ALIBABA_CLOUD, "qwen3-asr-flash", TRANSCRIPTION),
+ new(ALIBABA_CLOUD, "qwen3-asr-1.7b", TRANSCRIPTION),
+ new(ALIBABA_CLOUD, "qwen-audio-3.0-asr-flash-streaming", TRANSCRIPTION),
];
///
@@ -131,6 +141,8 @@ public static class ModelKindCorpus
// The one name which glues the word to something else, and the reason the three words are
// not loosened into substrings:
new(SELF_HOSTED, "xtts-v2", SPEECH_SYNTHESIS),
+
+ new(ALIBABA_CLOUD, "qwen-tts", SPEECH_SYNTHESIS),
];
///
@@ -145,6 +157,14 @@ public static class ModelKindCorpus
new(OPEN_AI, "gpt-realtime-whisper", REALTIME),
new(OPEN_AI, "gpt-live-1", REALTIME, AnsweredTodayAs: CHAT, Reason: "Found in the chat list while testing. The line which succeeds the realtime models dropped the word, and it is even less of a chat partner: it listens and speaks at once and leaves the thinking to a text model behind it."),
+
+ //
+ // Alibaba builds the word into both of its speech lines, and both are here to hold the
+ // rank the realtime rule carries: a connection AI Studio cannot open stays out of every
+ // list, whether the model would otherwise have spoken or listened.
+ //
+ new(ALIBABA_CLOUD, "qwen-tts-realtime", REALTIME),
+ new(ALIBABA_CLOUD, "qwen3-asr-flash-realtime", REALTIME),
];
///