aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/assistant/Presets.js
blob: 057f993ba3d447225cdd43579929a50d0c8b31fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
//
// 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."; }