SPB Git

spb/zyquo-local Public MIT

Native macOS AI chat that runs LLMs 100% locally on Apple Silicon with MLX — no cloud, no API keys.

Swift 97.2% Shell 1.8% Makefile 1%
12.4 KB · 157 lines swift
Raw Blame History
1//2//  PromptLibrary.swift3//  Zyquo Local4//5//  Author: Simon-Pierre Boucher6//  Mail: contact@spboucher.ai7//89import Foundation10import Observation1112/// A reusable prompt template with `{{input}}` variables.13struct PromptTemplate: Identifiable, Codable, Hashable, Sendable {14    var id: UUID15    var name: String16    var category: String17    var template: String18    var isBuiltIn: Bool1920    init(id: UUID = UUID(), name: String, category: String, template: String, isBuiltIn: Bool = false) {21        self.id = id22        self.name = name23        self.category = category24        self.template = template25        self.isBuiltIn = isBuiltIn26    }2728    /// Variable names in order of appearance ({{input}}, {{language}}, …).29    var variables: [String] {30        var seen = Set<String>()31        var result: [String] = []32        var search = template[template.startIndex...]33        while let open = search.range(of: "{{"), let close = search[open.upperBound...].range(of: "}}") {34            let name = String(search[open.upperBound..<close.lowerBound]).trimmingCharacters(in: .whitespaces)35            if !name.isEmpty, seen.insert(name).inserted { result.append(name) }36            search = search[close.upperBound...]37        }38        return result39    }4041    func render(values: [String: String]) -> String {42        var output = template43        for (key, value) in values {44            output = output.replacingOccurrences(of: "{{\(key)}}", with: value)45            output = output.replacingOccurrences(of: "{{ \(key) }}", with: value)46        }47        return output48    }49}5051/// Ships ≥50 quality templates; user templates persist alongside.52@MainActor53@Observable54final class PromptLibrary {55    var userTemplates: [PromptTemplate] {56        didSet { PersistenceService.saveDocument(userTemplates, named: "prompt-templates") }57    }5859    var all: [PromptTemplate] { Self.builtIns + userTemplates }6061    var categories: [String] {62        var seen = Set<String>()63        return all.compactMap { seen.insert($0.category).inserted ? $0.category : nil }64    }6566    init() {67        userTemplates = PersistenceService.loadDocument([PromptTemplate].self, named: "prompt-templates") ?? []68    }6970    func add(_ template: PromptTemplate) {71        userTemplates.append(template)72    }7374    func remove(id: UUID) {75        userTemplates.removeAll { $0.id == id }76    }7778    private static func t(_ name: String, _ category: String, _ template: String) -> PromptTemplate {79        PromptTemplate(name: name, category: category, template: template, isBuiltIn: true)80    }8182    /// 56 built-in templates across 8 categories.83    static let builtIns: [PromptTemplate] = [84        // ── Writing ─────────────────────────────────────────────────────────85        t("Improve writing", "Writing", "Improve the clarity, flow and concision of this text while keeping its meaning and tone:\n\n{{input}}"),86        t("Fix grammar", "Writing", "Fix all grammar, spelling and punctuation mistakes in this text. Return only the corrected text:\n\n{{input}}"),87        t("Make it shorter", "Writing", "Rewrite this text at half its length without losing the key information:\n\n{{input}}"),88        t("Make it longer", "Writing", "Expand this text with more detail, examples and nuance, keeping its voice:\n\n{{input}}"),89        t("Change tone", "Writing", "Rewrite this text in a {{tone}} tone:\n\n{{input}}"),90        t("Draft an email", "Writing", "Write a professional email about the following, with a clear subject line. Keep it under 150 words:\n\n{{input}}"),91        t("Blog post outline", "Writing", "Create a detailed outline for a blog post about: {{input}}. Include a hook, 4–6 sections with bullet points, and a conclusion."),92        t("Title ideas", "Writing", "Suggest 10 compelling titles for: {{input}}. Mix styles: direct, curiosity-driven, how-to, and listicle."),9394        // ── Coding ──────────────────────────────────────────────────────────95        t("Explain code", "Coding", "Explain what this code does, step by step, then summarize its purpose in one sentence:\n\n```\n{{input}}\n```"),96        t("Review code", "Coding", "Review this code for bugs, edge cases, performance and readability. Give concrete fixes:\n\n```\n{{input}}\n```"),97        t("Refactor code", "Coding", "Refactor this code for clarity and maintainability, preserving exact behavior. Explain each change briefly:\n\n```\n{{input}}\n```"),98        t("Write tests", "Coding", "Write thorough unit tests for this code, covering happy paths and edge cases:\n\n```\n{{input}}\n```"),99        t("Add documentation", "Coding", "Add clear documentation comments to this code. Return the documented code:\n\n```\n{{input}}\n```"),100        t("Translate to language", "Coding", "Translate this code to {{language}}, keeping behavior identical and using idiomatic style:\n\n```\n{{input}}\n```"),101        t("Debug an error", "Coding", "Here is code and the error it produces. Diagnose the root cause and give a fix.\n\nCode:\n```\n{{input}}\n```\n\nError:\n{{error}}"),102        t("Regex builder", "Coding", "Write a regular expression that {{input}}. Explain each part and give 3 matching and 3 non-matching examples."),103        t("SQL query", "Coding", "Write a SQL query that {{input}}. Assume sensible table/column names, state your assumptions, and explain the query."),104        t("Shell one-liner", "Coding", "Write a macOS shell one-liner that {{input}}. Explain what each part does and note any pitfalls."),105106        // ── Analysis ────────────────────────────────────────────────────────107        t("Summarize", "Analysis", "Summarize this text in 5 bullet points, then one sentence:\n\n{{input}}"),108        t("Key takeaways", "Analysis", "Extract the key takeaways from this text as a prioritized list, most important first:\n\n{{input}}"),109        t("Pros and cons", "Analysis", "List the pros and cons of: {{input}}. End with a balanced recommendation."),110        t("Compare options", "Analysis", "Compare these options across the criteria that matter most; use a table, then recommend one:\n\n{{input}}"),111        t("Find weaknesses", "Analysis", "Steelman the strongest objections to this argument, then assess which objections actually hold:\n\n{{input}}"),112        t("Fact-check reasoning", "Analysis", "Check this reasoning for logical fallacies and unsupported claims, quoting each problem:\n\n{{input}}"),113        t("SWOT analysis", "Analysis", "Produce a SWOT analysis (strengths, weaknesses, opportunities, threats) for: {{input}}"),114        t("Data interpretation", "Analysis", "Interpret this data: what patterns, anomalies and conclusions stand out? What further data would help?\n\n{{input}}"),115116        // ── Learning ────────────────────────────────────────────────────────117        t("Explain like I'm five", "Learning", "Explain {{input}} so a curious 5-year-old would get it, using one everyday analogy."),118        t("Explain in depth", "Learning", "Give an expert-level explanation of {{input}}: precise definitions, how it works, trade-offs, and common misconceptions."),119        t("Study plan", "Learning", "Design a 4-week study plan to learn {{input}} from scratch: weekly goals, resources, exercises and checkpoints."),120        t("Quiz me", "Learning", "Create a 10-question quiz on {{input}} with increasing difficulty. Show answers with explanations at the end."),121        t("Analogy maker", "Learning", "Explain {{input}} through 3 different analogies from unrelated domains, and note where each analogy breaks down."),122        t("Flashcards", "Learning", "Turn this material into 15 question→answer flashcards, hardest concepts first:\n\n{{input}}"),123        t("Historical context", "Learning", "Explain the historical context of {{input}}: what led to it, why it mattered, and its lasting consequences."),124125        // ── Productivity ────────────────────────────────────────────────────126        t("Meeting agenda", "Productivity", "Create a focused agenda for a {{duration}} meeting about {{input}}: timed sections, owners, and desired outcomes."),127        t("Meeting minutes", "Productivity", "Turn these raw notes into clean meeting minutes with decisions, action items (owner + due date), and open questions:\n\n{{input}}"),128        t("Prioritize tasks", "Productivity", "Prioritize these tasks with an effort/impact matrix and propose what to do today, this week, and to drop:\n\n{{input}}"),129        t("Project plan", "Productivity", "Break this project into phases with milestones, dependencies and risks:\n\n{{input}}"),130        t("Decision matrix", "Productivity", "Build a weighted decision matrix for this decision; propose criteria and weights, score the options, and conclude:\n\n{{input}}"),131        t("Brainstorm ideas", "Productivity", "Brainstorm 20 ideas for {{input}} — first 10 sensible, next 10 wild. Then mark the 3 most promising."),132        t("Weekly review", "Productivity", "Structure a weekly review from these notes: wins, misses, lessons, and next week's top 3 priorities:\n\n{{input}}"),133134        // ── Communication ───────────────────────────────────────────────────135        t("Difficult message", "Communication", "Help me write a kind but clear message about this difficult situation. Offer two versions — softer and more direct:\n\n{{input}}"),136        t("Negotiation prep", "Communication", "Prepare me for this negotiation: my leverage, their likely position, anchors, concessions and walk-away point:\n\n{{input}}"),137        t("Feedback for a colleague", "Communication", "Turn these observations into constructive, specific, actionable feedback using the SBI (situation-behavior-impact) format:\n\n{{input}}"),138        t("Announcement", "Communication", "Write a clear announcement about {{input}} for {{audience}}: what changes, why, when, and what they need to do."),139        t("Apology note", "Communication", "Write a sincere apology for this situation — own the mistake, no excuses, concrete repair step:\n\n{{input}}"),140        t("Elevator pitch", "Communication", "Craft a 30-second elevator pitch for {{input}}, plus a one-line hook and a follow-up question to keep the conversation going."),141142        // ── Translation & language ──────────────────────────────────────────143        t("Translate", "Language", "Translate this text to {{language}}, preserving tone and idioms naturally:\n\n{{input}}"),144        t("Translate + explain", "Language", "Translate this to {{language}}, then explain any idioms or cultural references that required adaptation:\n\n{{input}}"),145        t("Proofread (non-native)", "Language", "I'm not a native speaker. Correct this text and briefly explain the 3 most instructive mistakes:\n\n{{input}}"),146        t("Vocabulary builder", "Language", "Give me 10 advanced ways to express “{{input}}”, from formal to casual, with an example sentence each."),147148        // ── Creative ────────────────────────────────────────────────────────149        t("Short story", "Creative", "Write a 500-word short story about {{input}} with a strong opening line and an unexpected ending."),150        t("Character builder", "Creative", "Create a rich character based on: {{input}}. Include appearance, voice, motivation, flaw, secret, and a sample line of dialogue."),151        t("World-building", "Creative", "Develop a setting from this seed: {{input}}. Cover geography, society, conflict, and 3 story hooks."),152        t("Poem", "Creative", "Write a poem about {{input}} in the style of {{style}}."),153        t("Naming ideas", "Creative", "Suggest 15 names for {{input}}: 5 descriptive, 5 evocative, 5 invented words. Note availability concerns for the top 3."),154        t("Dialogue scene", "Creative", "Write a dialogue-only scene (no narration) where {{input}}. Make each voice distinct."),155    ]156}157