feat: abilita di default la pipeline multimodale diretta Gemini per l'audio indipendentemente dal modello attivo in sessione

This commit is contained in:
Matteo Benedetto
2026-08-21 21:51:57 +02:00
parent 49e6269626
commit ace461ff59
2 changed files with 19 additions and 4 deletions
+2
View File
@@ -127,6 +127,8 @@ della richiesta utente, seguendo le best practice di context engineering:
| `contextTokens` | `1500` | Token cap per il contesto iniettato |
| `webSearch` | `auto` | Ricerca web Strada A: `auto` \| `on` \| `off` |
| `vocalPlanningMode` | `true` | Piano + conferma in overlay dopo il vocale |
| `sttDirectGemini` | `true` | Interpretazione multimodale diretta Gemini (anche con DeepSeek/Claude) |
| `voiceModel` | `gemini-3.7-flash-medium` | Modello Gemini per l'audio |
Le variabili d'ambiente (`GEMINI_API_KEY`, `AGY_STT_BACKEND`, ecc.) hanno
priorità sul file di config quando impostate.
+17 -4
View File
@@ -66,6 +66,8 @@ interface AgyConfig {
contextTokens?: number; // token cap per il contesto iniettato
webSearch?: string; // auto|on|off — Strada A: pi cerca + inietta
vocalPlanningMode?: boolean; // Opzione 4: piano + conferma prima di eseguire
sttDirectGemini?: boolean; // Forza l'uso di Gemini multimodale per l'audio anche con modelli non-Gemini (es. DeepSeek)
voiceModel?: string; // Modello per l'elaborazione vocale diretta (default: gemini-3.7-flash-medium)
}
const CONFIG_DEFAULTS: AgyConfig = {
@@ -81,6 +83,8 @@ const CONFIG_DEFAULTS: AgyConfig = {
contextTokens: 1500,
webSearch: "auto",
vocalPlanningMode: true,
sttDirectGemini: true,
voiceModel: "gemini-3.7-flash-medium",
};
function loadConfig(): AgyConfig {
@@ -111,7 +115,7 @@ function getConfig(key: keyof AgyConfig): string | undefined {
function setConfig(key: keyof AgyConfig, value: string) {
const cfg = loadConfig();
const numKeys: (keyof AgyConfig)[] = ["sttMaxDuration", "agyTimeoutMs", "contextTokens"];
const boolKeys: (keyof AgyConfig)[] = ["ttsNotify", "contextInject", "vocalPlanningMode"];
const boolKeys: (keyof AgyConfig)[] = ["ttsNotify", "contextInject", "vocalPlanningMode", "sttDirectGemini"];
if (numKeys.includes(key)) {
(cfg as any)[key] = Number(value);
} else if (boolKeys.includes(key)) {
@@ -3125,20 +3129,27 @@ export default function agyExtension(pi: ExtensionAPI) {
let searchHints: string[] = [];
const activeModel = ctx.model;
const useDirectMultimodal = isGeminiModel(activeModel);
const directGeminiConfig = getConfig("sttDirectGemini");
// Usa la pipeline multimodale diretta con Gemini se abilitata (default: true) o se il modello di chat è Gemini
const useDirectMultimodal =
directGeminiConfig !== "false" ? true : isGeminiModel(activeModel);
if (useDirectMultimodal) {
// =========================================================================
// Pipeline Multimodale Diretta (Gemini): l'audio viene inviato direttamente
// al modello senza passare per un riconoscitore vocale STT separato.
// a Gemini (gateway Antigravity / Gemini API) senza passare per un STT separato,
// anche se il modello attivo in sessione è DeepSeek, Claude o un modello locale.
// =========================================================================
ctx.ui.notify("Interpretazione vocale diretta con Gemini...", "info");
try {
const voiceModelName =
getConfig("voiceModel") ||
(isGeminiModel(activeModel) ? activeModel?.id : "gemini-3.7-flash-medium");
const directRes = await interpretAudioDirectGemini(
optimized,
editorText,
context,
activeModel?.id,
voiceModelName,
);
transcript = directRes.transcript || directRes.cleanPrompt;
finalText = directRes.cleanPrompt;
@@ -3360,6 +3371,8 @@ export default function agyExtension(pi: ExtensionAPI) {
{ key: "contextTokens", desc: "Token cap per il contesto iniettato (default 1500)" },
{ key: "webSearch", desc: "Ricerca web Strada A: auto | on | off" },
{ key: "vocalPlanningMode", desc: "Opzione 4: piano+conferma dopo il vocale (true|false)" },
{ key: "sttDirectGemini", desc: "Interpretazione vocale diretta Gemini (true|false, default true)" },
{ key: "voiceModel", desc: "Modello Gemini per l'audio (default gemini-3.7-flash-medium)" },
];
pi.registerCommand("agy:config", {