diff --git a/app/MindWork AI Studio/Models/Google/AqaFamily.cs b/app/MindWork AI Studio/Models/Google/AqaFamily.cs
new file mode 100644
index 00000000..f9f6c0d5
--- /dev/null
+++ b/app/MindWork AI Studio/Models/Google/AqaFamily.cs
@@ -0,0 +1,32 @@
+using AIStudio.Provider;
+
+using static AIStudio.Provider.Capability;
+
+namespace AIStudio.Models.Google;
+
+///
+/// AQA, which answers a question out of the passages it was handed.
+///
+///
+/// Attributed Question Answering, and the one entry in Google's catalog whose whole name is three
+/// letters. It answers on generateAnswer rather than on generateContent, together with the semantic
+/// retriever, and what comes back is the answer, the passages it rests on, and an estimate of
+/// whether the question could be answered from them at all.
+///
+/// Bound to Google, and it has to be: three letters are three letters, and a rule that short has no
+/// business meeting a name from somewhere else. The catalog holds exactly one model it can match.
+///
+public sealed class AqaFamily : ModelFamily
+{
+ ///
+ public override ModelVendor Vendor => ModelVendor.GOOGLE;
+
+ ///
+ public override ModelSource Source => new("https://ai.google.dev/gemini-api/docs/semantic_retrieval", new DateOnly(2026, 9, 19), "Reads 7,168 tokens and writes 1,024, which is a size for an answer rather than for a conversation. The route it answers on is generateAnswer, so nothing the app sends over the chat completion API reaches it.");
+
+ ///
+ protected override void Declare(ModelFamilyBuilder builder) =>
+ builder.Rule("aqa").AsExact().OnlyOn(LLMProviders.GOOGLE)
+ .Capabilities(TEXT_INPUT | TEXT_OUTPUT)
+ .Kind(ModelKind.GROUNDED_ANSWERING);
+}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Models/Google/GoogleAgentFamily.cs b/app/MindWork AI Studio/Models/Google/GoogleAgentFamily.cs
new file mode 100644
index 00000000..bc305a45
--- /dev/null
+++ b/app/MindWork AI Studio/Models/Google/GoogleAgentFamily.cs
@@ -0,0 +1,42 @@
+using AIStudio.Provider;
+
+using static AIStudio.Provider.Capability;
+
+namespace AIStudio.Models.Google;
+
+///
+/// The Google models which are handed a job rather than a message.
+///
+///
+/// Both of these answer on the Interactions API alone, never on generateContent: one request starts
+/// an autonomous loop which plans, runs code, manages files and searches the web, and a research
+/// run takes minutes rather than seconds. A chat request does not time out against them -- it never
+/// arrives.
+///
+/// Deep Research is the reason these rules are bound to Google instead of standing among the kinds.
+/// Perplexity sells something under that name too, and sonar-deep-research is an ordinary chat
+/// model with web search bolted on, stated in its own family. The same two words, two different
+/// things, and only the provider tells them apart. Antigravity needs no such guard -- nobody else
+/// names a model that -- but it is a statement about Google's catalog all the same, so it stands
+/// where the other one stands.
+///
+public sealed class GoogleAgentFamily : ModelFamily
+{
+ ///
+ public override ModelVendor Vendor => ModelVendor.GOOGLE;
+
+ ///
+ public override ModelSource Source => new("https://ai.google.dev/gemini-api/docs/deep-research", new DateOnly(2026, 9, 19), "Deep Research runs only through the Interactions API and only in the background, because a single run takes five to twenty minutes. The Antigravity agent is documented at https://ai.google.dev/gemini-api/docs/antigravity-agent and works the same way, on a sandbox Google hosts.");
+
+ ///
+ protected override void Declare(ModelFamilyBuilder builder)
+ {
+ builder.Rule("deep-research").AsPrefix().OnlyOn(LLMProviders.GOOGLE)
+ .Capabilities(TEXT_INPUT)
+ .Kind(ModelKind.AGENT);
+
+ builder.Rule("antigravity").AsSegment().OnlyOn(LLMProviders.GOOGLE)
+ .Capabilities(TEXT_INPUT)
+ .Kind(ModelKind.AGENT);
+ }
+}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Models/Google/LyriaFamily.cs b/app/MindWork AI Studio/Models/Google/LyriaFamily.cs
new file mode 100644
index 00000000..f53697d4
--- /dev/null
+++ b/app/MindWork AI Studio/Models/Google/LyriaFamily.cs
@@ -0,0 +1,35 @@
+using AIStudio.Provider;
+
+using static AIStudio.Provider.Capability;
+
+namespace AIStudio.Models.Google;
+
+///
+/// Lyria, which writes music from a description.
+///
+///
+/// Nothing knew the name, so the catalog answered for it the way it answers for everything nobody
+/// wrote a rule for: a chat model which reads text, writes text and calls tools. What comes back is
+/// a stereo recording with instruments and, from 3.5 on, sung lyrics.
+///
+/// Nobody ran into it because the Google provider showed only names beginning with "gemini", which
+/// kept four Lyria models out of sight along with the two Gemma models somebody actually wants. The
+/// prefix is gone now, so the rule has to carry what the prefix carried by accident.
+///
+/// Whole name parts rather than a substring, for the reason Imagen gives next door. The rule is not
+/// bound to Google, unlike the agent ones: wherever a model called Lyria turns up, it is this.
+///
+public sealed class LyriaFamily : ModelFamily
+{
+ ///
+ public override ModelVendor Vendor => ModelVendor.GOOGLE;
+
+ ///
+ public override ModelSource Source => new("https://ai.google.dev/gemini-api/docs/music-generation", new DateOnly(2026, 9, 19), "A description goes in and 44.1 kHz stereo music comes out, with vocals and timed lyrics from Lyria 3.5 on. The realtime variant holds a connection open instead, which the realtime rule states and outranks this with.");
+
+ ///
+ protected override void Declare(ModelFamilyBuilder builder) =>
+ builder.Rule("lyria").AsSegment()
+ .Capabilities(TEXT_INPUT)
+ .Kind(ModelKind.MUSIC_GENERATION);
+}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Plugins/models/plugin.lua b/app/MindWork AI Studio/Plugins/models/plugin.lua
index 82f691ae..d68f2b3a 100644
--- a/app/MindWork AI Studio/Plugins/models/plugin.lua
+++ b/app/MindWork AI Studio/Plugins/models/plugin.lua
@@ -146,10 +146,13 @@ MODELS = {}
--
-- -- What the model is made for. Optional, defaults to CHAT.
-- -- Allowed values are: CHAT, TEXT_COMPLETION, EMBEDDING, RERANKING,
--- -- IMAGE_GENERATION, VIDEO_GENERATION, TRANSCRIPTION, SPEECH_SYNTHESIS,
--- -- REALTIME, COMPUTER_USE, OCR, MODERATION, OTHER
+-- -- IMAGE_GENERATION, VIDEO_GENERATION, MUSIC_GENERATION, TRANSCRIPTION,
+-- -- SPEECH_SYNTHESIS, REALTIME, COMPUTER_USE, AGENT, GROUNDED_ANSWERING,
+-- -- OCR, MODERATION, OTHER
-- -- This decides which lists the model appears in. Use OTHER for entries
--- -- which are no models at all.
+-- -- which are no models at all. Use AGENT for a model which is handed a
+-- -- job and works on it by itself, and GROUNDED_ANSWERING for one which
+-- -- answers out of passages it is given and cites them.
-- ["KIND"] = "CHAT",
--
-- -- Optional: how many tokens the model reads and writes in one
diff --git a/app/MindWork AI Studio/Provider/ModelKind.cs b/app/MindWork AI Studio/Provider/ModelKind.cs
index 75a7e49f..f6baa0b3 100644
--- a/app/MindWork AI Studio/Provider/ModelKind.cs
+++ b/app/MindWork AI Studio/Provider/ModelKind.cs
@@ -52,6 +52,16 @@ public enum ModelKind
///
VIDEO_GENERATION,
+ ///
+ /// The model composes music.
+ ///
+ ///
+ /// Audio comes out of it, but not speech: instruments, arrangement, and in Lyria's case singing
+ /// with lyrics. Neither the speech synthesis list nor any other one fits, and a chat request to
+ /// such a model gets nothing back that reads like an answer.
+ ///
+ MUSIC_GENERATION,
+
///
/// The model transcribes audio into text.
///
@@ -86,6 +96,27 @@ public enum ModelKind
///
COMPUTER_USE,
+ ///
+ /// The model runs an errand of its own instead of answering.
+ ///
+ ///
+ /// One request starts a loop which plans, calls tools, runs code and reads the web, and it can
+ /// take minutes. Google serves its research and coding agents this way, through an API of their
+ /// own which a chat request never reaches. Note that the name alone decides nothing here: what
+ /// Perplexity calls deep research is an ordinary chat model with web search.
+ ///
+ AGENT,
+
+ ///
+ /// The model answers a question out of sources handed to it, and says where the answer came from.
+ ///
+ ///
+ /// Built for retrieval rather than for conversation: it is given passages along with the
+ /// question, and returns the answer, the citations, and an estimate of whether the question
+ /// could be answered from them at all. Reached through a route of its own.
+ ///
+ GROUNDED_ANSWERING,
+
///
/// The model extracts text from images or scanned documents.
///
diff --git a/app/Tests/Models/Corpus/ModelKindCorpus.cs b/app/Tests/Models/Corpus/ModelKindCorpus.cs
index 7c78ba6d..ac73ea69 100644
--- a/app/Tests/Models/Corpus/ModelKindCorpus.cs
+++ b/app/Tests/Models/Corpus/ModelKindCorpus.cs
@@ -193,6 +193,46 @@ public static class ModelKindCorpus
new(GOOGLE, "lyria-realtime-exp", REALTIME),
];
+ ///
+ /// The models which write music.
+ ///
+ ///
+ /// All four off Google's own catalog. They were never seen because the provider showed only
+ /// names beginning with "gemini" -- the same prefix which kept Gemma out, which is why it had
+ /// to go and why these needed a rule of their own before it could.
+ ///
+ private static readonly ModelKindExample[] MUSIC_ENTRIES =
+ [
+ new(GOOGLE, "lyria-3.5", MUSIC_GENERATION),
+ new(GOOGLE, "lyria-3-pro-preview", MUSIC_GENERATION),
+ new(GOOGLE, "lyria-3-clip-preview", MUSIC_GENERATION),
+ ];
+
+ ///
+ /// The models which are handed a job instead of a message.
+ ///
+ ///
+ /// The last two are the point of binding these rules to Google. Perplexity sells deep research
+ /// as well, and what it sells is a chat model -- so the same two words have to mean different
+ /// things at different providers, which is exactly what a binding is for.
+ ///
+ private static readonly ModelKindExample[] AGENT_ENTRIES =
+ [
+ new(GOOGLE, "deep-research-preview-04-2026", AGENT),
+ new(GOOGLE, "deep-research-max-preview-04-2026", AGENT),
+ new(GOOGLE, "deep-research-pro-preview-12-2025", AGENT),
+ new(GOOGLE, "antigravity-preview-05-2026", AGENT),
+ new(GOOGLE, "antigravity-preview-09-2026", AGENT),
+ ];
+
+ ///
+ /// The model which answers out of what it was handed, and says where the answer came from.
+ ///
+ private static readonly ModelKindExample[] GROUNDED_ANSWERING_ENTRIES =
+ [
+ new(GOOGLE, "aqa", GROUNDED_ANSWERING),
+ ];
+
///
/// The models which work a screen.
///
@@ -303,6 +343,15 @@ public static class ModelKindCorpus
new(PERPLEXITY, "sonar-reasoning-pro", CHAT),
new(PERPLEXITY, "sonar-deep-research", CHAT),
+ //
+ // The other two deep research models of the world, and the reason Google's rule is bound
+ // to Google and written as a prefix. Perplexity and OpenAI both sell something under that
+ // name which answers over the API the app already speaks, so both stay chat models. Only
+ // Google's own line, whose names start with the words, is handed a job instead.
+ //
+ new(OPEN_AI, "o3-deep-research", CHAT),
+ new(OPEN_AI, "o4-mini-deep-research", CHAT),
+
//
// The counter-sample to the three rules above, taken off the same three catalogs. Every
// one of these carries a word which now means something -- code, live, image -- without
@@ -342,6 +391,9 @@ public static class ModelKindCorpus
..TRANSCRIPTION_ENTRIES,
..SPEECH_ENTRIES,
..REALTIME_ENTRIES,
+ ..MUSIC_ENTRIES,
+ ..AGENT_ENTRIES,
+ ..GROUNDED_ANSWERING_ENTRIES,
..COMPUTER_USE_ENTRIES,
..TEXT_COMPLETION_ENTRIES,
..OCR_ENTRIES,