// Reply templates for Phase 5 (FR-8). // // A template is a short instruction that shapes the LLM draft. It is not the // final text: the model fills it in from the message, the classification, and // any extra note Sam types. Templates are built in for v1; a template editor is // not in the Phase 5 requirements. package reply import "strings" // Template is one reply shape. type Template struct { ID string Name string Description string // Instruction is the template-specific part of the prompt. Instruction string } // Templates is the built-in template list, in menu order. var Templates = []Template{ { ID: "quick-ack", Name: "Quick acknowledgement", Description: "Confirm receipt in one or two short sentences.", Instruction: "Acknowledge that the message was received. If the sender asked for something, say when Sam will look at it. Do not promise anything Sam has not agreed to.", }, { ID: "answer", Name: "Answer the question", Description: "Answer the sender's question directly.", Instruction: "Answer the sender's question directly and briefly. If the message does not contain a clear question, summarise what Sam understood and ask one clarifying question.", }, { ID: "confirm", Name: "Confirm an arrangement", Description: "Confirm a booking, time, or arrangement.", Instruction: "Confirm the arrangement in the message: restate the key detail (date, time, or reference) and say it works for Sam.", }, { ID: "decline", Name: "Politely decline", Description: "Decline or say no thanks, politely.", Instruction: "Politely decline the request or offer. Thank the sender and keep it warm but brief. Do not over-explain.", }, } // TemplateByID returns the template with the given id. ok is false when it is // unknown. The id match is case-insensitive. func TemplateByID(id string) (Template, bool) { id = strings.ToLower(strings.TrimSpace(id)) for _, t := range Templates { if t.ID == id { return t, true } } return Template{}, false } // TemplateForAction picks a sensible default template from the classifier's // recommended action. An unknown action falls back to a quick acknowledgement. func TemplateForAction(action string) Template { switch strings.ToLower(strings.TrimSpace(action)) { case "reply": t, _ := TemplateByID("answer") return t default: t, _ := TemplateByID("quick-ack") return t } }