Logotipo Hedhog

Get Hedhog updates in your inbox

New releases, fresh recipes, and breaking changes — no spam.

sac Submodule

ai-suggestions

AI reply drafts for the agent, refinable in plain language and never sent without a human confirming.

Source path: libraries/sac/src/ai

Module file: sac-ai.module.ts

Introduction

A draft is generated on every new ticket and every customer reply. Because all entry points converge on the same two methods, e-mail and WhatsApp get this for free. Generation runs on the queue — nobody is waiting for it — while a draft requested or refined from the screen is synchronous, because there an agent is watching.

The agent has three ways out, all of them explicit acts: confirm and send, refine with an instruction in plain language ("shorter", "mention the 5 business day window"), or drop the text into the editor. Refinements chain through `parent_suggestion_id`, so the sequence of adjustments stays auditable. Confirming goes through the ordinary reply path, with the same per-channel transport, SLA and event trail.

Only public messages enter the context: internal notes are where the team writes what is not meant for the customer. A partial unique index guarantees one AUTOMATIC draft per triggering message — a WhatsApp conversation with ten messages in a row does not become ten model calls — while agent-requested refinements are deliberately excluded from it. The system prompt is registered with required phrases carrying the prompt-injection defence: if a database override drops them, the resolver discards the override and falls back to the code version, so the protection cannot be removed through the admin.

HTTP Endpoints

4 endpoints

Latest draft of the ticket, so the screen shows it without waiting for generation.

Params
id (int)

Generate a draft or refine the current one. Synchronous: an agent is waiting on screen.

Params
id (int)

Body

FieldTypeRequiredNotes
instructionstring (max 1000)noPlain-language adjustment; empty generates a fresh draft
parent_suggestion_idintnoDraft being refined; empty uses the most recent

Confirm and publish the draft as the agent reply, then mark the suggestion used.

Params
id (int)

Body

FieldTypeRequiredNotes
bodystringnoWhat was actually sent — the agent may have edited the draft before confirming

Record feedback or discard the draft.

Params
id (int)

Body

FieldTypeRequiredNotes
feedbackhelpful | not_helpfulno
statusdiscardedno