// Copyright (C) 2026 Danilo M. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. .pragma library // Canned questions for the file state's Ask row. icon is a Nerd Font // codepoint, checked in Inconsolata Nerd Font's cmap; a saved preset // without one gets FALLBACK. kinds lists the staged // kinds a preset applies to (Files.js); ["many"] offers it whenever two or // more files are staged. The list in use is Prefs.presets when one is // saved (a settings page will edit it), these otherwise. const DEFAULTS = [ { label: "Summarize", icon: "\uf036", kinds: ["pdf", "text"], prompt: "Summarize this in a few short paragraphs." }, { label: "Key points", icon: "\uf0ca", kinds: ["pdf"], prompt: "List the key points as bullets." }, { label: "Explain simply", icon: "\uf0eb", kinds: ["pdf", "text"], prompt: "Explain this simply, as to a non-expert." }, { label: "Describe", icon: "\uf06e", kinds: ["image"], prompt: "Describe this image." }, { label: "Extract text", icon: "\uf031", kinds: ["image", "pdf"], prompt: "Transcribe all the text, keeping the layout where it helps." }, { label: "What is this?", icon: "\uf059", kinds: ["image"], prompt: "What is this, and what is it for?" }, { label: "Explain", icon: "\uf121", kinds: ["code"], prompt: "Explain what this code does." }, { label: "Review", icon: "\uf188", kinds: ["code"], prompt: "Review this code: bugs, risks, and simplifications." }, { label: "Compare", icon: "\uf0db", kinds: ["many"], prompt: "Compare these files: what they share and how they differ." }, ]; var FALLBACK = "\uf086"; // The saved list if it is one, else the defaults: a hand edit with a typo // must not leave the row empty. function list(saved) { const ok = Array.isArray(saved) && saved.every(p => p && typeof p.label === "string" && typeof p.prompt === "string" && Array.isArray(p.kinds)); return ok ? saved : DEFAULTS; } function offered(presets, files) { if (!files.length) return []; return presets.filter(p => p.kinds.includes("many") ? files.length > 1 : files.every(f => p.kinds.includes(f.kind))); } // The model answers in the language it is asked in; a preset is asked in // English, so it says which language to use. function prompt(p) { return p.prompt + " Answer in the language of the document."; }