ThunderAI/claude-spec/02-prompts.md
2026-04-02 21:45:46 +02:00

8.7 KiB
Raw Blame History

Prompts System

Overview

Prompts are the core user-facing feature of ThunderAI. Each prompt defines an AI instruction and how it behaves. There are two kinds:

  • Built-in prompts — defined in js/mzta-prompts.js
  • Custom prompts — created by the user and stored in browser.storage.local

Prompt Properties

Base Properties (built-in only)

Property Type Description
id string Unique identifier
name string __MSG_key__ i18n reference or plain text
prompt string The prompt template text (may contain {%placeholder%} tokens)
type number 0 = always visible, 1 = reading email only, 2 = composing only
action number 0 = close, 1 = reply (open compose), 2 = substitute text in-place
need_selected number 0 = use full message body, 1 = requires text selection
need_signature number 0 = no signature, 1 = include signature
need_custom_text number 0 = no custom input, 1 = show custom text input field
define_response_lang number 0 = no language hint, 1 = append response language instruction
use_diff_viewer number 0 = normal output, 1 = show diff viewer (ChatGPT Web only)

User Properties (stored per-prompt in storage)

Property Type Description
enabled number 0 = hidden, 1 = shown in menus
position_display number Sort order in reading view (used when alphabetical ordering is off)
position_compose number Sort order in compose view (used when alphabetical ordering is off)
show_in string "popup" = popup only, "context" = context menu only, "both" = both. Default: "popup" for default/custom prompts, "both" for special prompts

Per-Prompt API Override Properties

Each prompt can override the global API connection. These mirror the keys in integration_options_config and prefs_default:

Property Description
connection_type Override API type for this prompt
chatgpt_web_model Override ChatGPT Web model
chatgpt_web_project Override ChatGPT Web project
chatgpt_web_custom_gpt Override custom GPT
All chatgpt_*, ollama_*, openai_comp_*, google_gemini_*, anthropic_* keys Override specific API settings

Special Prompts

Some prompts trigger additional Thunderbird actions beyond just sending text to the AI. They are identified by their id:

ID Feature
add_tags Auto-tag the email after AI response
spamfilter Classify as spam and optionally move email
summarize Summarize email content
get_calendar_event Extract and create a calendar event
get_task Extract and create a task
translate Translate email content into a target language

These special prompts can have their own dedicated API integration settings (configured in the Options page). The list of these special prompts is in options/mzta-options-default.js as special_prompts_with_integration.

Menu System

Popup Menu

  • Displays prompts filtered by show_in ("popup" or "both") and by tab context (type property)
  • Ordering: user can choose between alphabetical or position-based (using position_display/position_compose) via the dynamic_menu_order_alphabet preference
  • Special prompts retain their colored background (CSS class special_prompt) in the popup based on is_special == "1"

Context Menu

  • Dynamically built from all prompts with show_in set to "context" or "both", filtered to reading types only (type 0 or 1)
  • Appears as a "ThunderAI" submenu in the message_list context
  • Special prompts (add_tags, spamfilter, summarize, translate) route through processEmails() for batch processing; regular prompts execute via menus.executeMenuAction()
  • Icons: special prompts use dedicated icons (defined in contextMenuIconsPath); all other prompts use the addon icon (images/icon-32.png)
  • Add Tags in context menu assigns tags automatically (addTagsAuto: true), while in the popup it shows the interactive tag selection form

Summarize: Dual-Mode Prompt System

The summarize feature uses two distinct prompt pathways:

Context Menu Summarize (right-click on messages in message list):

  • Activated via the summarize context menu item, controlled by the summarize feature flag
  • Uses 3 special prompts stored in specialPrompts:
    • prompt_summarize — the main instruction prompt for the LLM
    • prompt_summarize_email_template — template for formatting each email's content
    • prompt_summarize_email_separator — separator text between multiple emails
  • Supports multi-email summarization: each selected message is formatted with the email template, joined by the separator, then prepended with the instruction prompt
  • All 3 prompts support placeholder autocomplete ({%placeholder%} syntax)
  • Result is displayed via openChatGPT() in the standard chat output window (not inline)
  • Default prompt texts are stored as i18n keys: prompt_summarize_full_text, prompt_summarize_email_template_full_text, prompt_summarize_email_separator_full_text

Inline Summary on Message Display (automatic or manual per summarize_auto pref):

  • Uses the same 3 special prompts as webchat mode, via taPromptUtils.buildSummaryPrompt() in js/mzta-utils-prompt.js
  • Does not support chatgpt_web connection type (shows error if configured)
  • Result is rendered as a styled banner at the top of the message body via mzta-compose-script.js
  • Banner includes a refresh button (↻) to regenerate the summary
  • Cached per-message via taSummaryStore / taStorage (max 100 entries)

Unified Prompt BuildingtaPromptUtils.buildSummaryPrompt(messageDataArray):

  • All summary paths (inline, webchat single, webchat multi) use this single method
  • Accepts an array of { message, fullMessage } entries
  • Returns { promptText, promptInfo } where promptInfo is the prompt_summarize prompt object

Translate: Inline-Only Prompt System

The translate feature uses a single special prompt (prompt_translate_this) for translating emails. Translation always renders inline (no webchat mode).

Inline Translation on Message Display (controlled by translate_auto pref):

  • Uses a single special prompt: prompt_translate_this
  • The prompt uses placeholders ({%mail_subject%}, {%mail_html_body%}, {%thunderai_translate_lang%}, {%thunderai_translate_exclude_lang%}) resolved via the standard placeholder system
  • The AI response is a JSON object: { "subject": "...", "body": "...", "status": "1"|"-1" }
    • status = "1": translation completed, subject and body are displayed
    • status = "-1": translation skipped (excluded/target language), a "skipped" message is shown
  • Target language is determined by translate_lang pref, falling back to default_chatgpt_lang
  • Does not support chatgpt_web connection type (shows error if configured)
  • Result is rendered as a styled banner (green/teal theme) in the message body via mzta-compose-script.js
  • Banner includes refresh (↻) and delete (×) buttons
  • Cached per-message via taTranslationStore / taStorage (max 100 entries)
  • The prompt was originally a regular prompt (defaultPrompts) and was moved to specialPrompts with is_special: "1" and type: "1" (reading email only)

Prompt BuildingtaPromptUtils.buildTranslationPrompt(fullMessage):

  • Retrieves the prompt_translate_this special prompt text
  • Resolves placeholders via placeholdersUtils.getPlaceholdersValues() + replacePlaceholders()
  • Returns { promptText, promptInfo }

Prompt Types Reference

type 0  → shown when reading AND composing
type 1  → shown only when reading an email (message display)
type 2  → shown only when composing an email

Action Types Reference

action 0  → no output, just close (e.g. for tag/spam actions handled in background)
action 1  → open a reply compose window with AI response
action 2  → replace selected text (or insert) in compose window

Adding a New Built-in Prompt

  1. Add the prompt object to the defaultPrompts array in js/mzta-prompts.js
  2. Add the name string key to _locales/en/messages.json
  3. If the prompt text needs a localized string, add it to _locales/en/messages.json as well
  4. Reference any needed placeholders using {%placeholder_id%} syntax in the prompt field

Custom Prompts

Custom prompts are stored in browser.storage.local and managed via pages/customprompts/. They follow the same property structure as built-in prompts but are created/edited/deleted by the user through the UI. Custom placeholders can also be referenced in custom prompt text.