Add strict linked-product upsell controls, improve retrieval consistency, persist full storefront escalation transcripts, and upgrade ticket APIs/UI for complete thread visibility and safer human handoff workflows. Co-authored-by: Cursor <cursoragent@cursor.com>
5.9 KiB
5.9 KiB
AI features — configuration and flows (high level)
This document describes how customer-facing AI is wired today: entry points, major pipeline steps, configuration stored on Store, and known gaps. Use it when changing ticket creation, Gmail behavior, or module gating.
Surfaces
| Surface | Primary code | Notes |
|---|---|---|
| Gmail inbound | src/lib/gmail/emailProcessor.ts, webhook src/app/api/webhooks/gmail/route.ts |
Processes one unread message; builds a reply via generateAutoReplyPreview and sends it. |
| Storefront widget | src/app/api/storefront-chat/messages/route.ts, src/lib/ai/storefrontGroq.ts |
Public API; resolves store by shop domain; runs the same L1 orchestrator as email with channel: "widget". |
Gmail reply composition (generateAutoReplyPreview)
Rough order:
- Safety —
screenInboundEmailForAbuse; flagged messages get a minimal HTML response and no order data. - Classification —
classifyCustomerEmail(Groq) yields Gmail intent/mood for logging and guardrails; order-context lines are built with heuristics in the same file (when to load cached orders, when to ask for order number first, off-topic detection, etc.). - L1 orchestrator — If not skipped (off-topic, too sparse, needs order id first, hint unmatched),
runL1Orchestratorruns withchannel: "email"andemailFromset to the sender. - HTML fallbacks — If L1 returns empty text, built-in HTML snippets apply (off-topic boundary, need order id, hint unmatched, minimal acknowledgment). Vendor-editable HTML templates were removed; there is no DB template fallback.
Relevant store fields on this path: businessName, email, aiModules, modulePolicies (see below).
L1 orchestrator (runL1Orchestrator)
Single implementation for widget and email:
- Retrieval —
getBlendedStorefrontContextalways retrieves KB/FAQ and only includes products when the active module allows it. In strict mode, product retrieval is constrained to linked upsell candidates. - Intent → module —
routeCustomerIntent(Groq JSON) maps the customer message to anL1Module. - Module gating —
parseAiModulesJson+isModuleEnabled. Disabled modules fall back to FAQ.FAQis always treated as enabled (cannot be turned off via JSON).UNKNOWNstays enabled for routing stability. - Pillar — Each module has a pillar in
MODULE_MANIFESTS:K(knowledge),T(transactional / DB),X(ticket handoff copy),CAT(catalog metafields). - Verification — Widget: OTP-verified session on
StorefrontChatConversation(asserted email + expiry). Email: trustFromas customer email for order lookup (seerunL1and order tools). - Tools — Orders:
orderTools. Products:productTools. Linked upsell allowlist:upsellLinksbacked byUpsellProductLink+ optionaljuno.upsell_linksmetafields. - Reply — Mostly
composeReply(Groq) over assembled facts. Strict guardrails prevent recommending products outside linked allowlist and strip generic upsell language when no linked candidates exist.
Vendor UI for aiModules and modulePolicies: dashboard JUNO Engine → Modules; persistence via GET/PATCH /api/stores/[storeId].
Knowledge base (separate from module toggles)
- Mode and content —
Store.knowledgeBaseMode,knowledgeTemplateJSON, documents, FAQs, structured chunks. APIs undersrc/app/api/stores/[storeId]/knowledge-templateand KB subroutes. - Public query — e.g.
src/app/api/stores/[storeId]/kb/query/route.tsfor RAG-style use.
Module toggles do not turn off the knowledge base; they only restrict which L1 modules can run after routing.
Known gaps (intentional follow-ups)
- Ticket-led (
X) flows — Vendor Tickets are derived fromEmailLog, not a separate ticket table. Storefront escalations now persist the full storefront transcript and conversation linkage metadata on theEmailLogrow. - Spec vs router — Vendor policy text is stored per
L1ModuleinStore.modulePolicies(AI modules UI). TheintentRouteronly emits declared modules. Extending automation requires adding a module in types,MODULE_MANIFESTS,DEFAULT_ENABLEDinaiModules.ts, and orchestrator branches inrunL1.ts. - Gmail vs widget parity — Same L1 core; Gmail adds a pre-L1 classification layer and different skip rules for when L1 runs.
Environment / models
- Groq and related env vars are used by
groqClient,gmailGroq,intentRouter, andcomposeReply. - Rate limits and leases for Gmail inbound:
gmailAutoReplyGuards. - Upsell safety flags:
STRICT_UPSELL_LINKS(defaulttrue) blocks out-of-policy upsells.L1_INCLUDE_PRODUCT_RETRIEVAL(defaulttrue) controls whether product snippets can enter retrieval context (still module-gated).