JUNOHUB-test/docs/ai-features-configuration.md
Saad Mohsin 6cc4472feb Harden upsell reliability and ticket context completeness.
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>
2026-05-13 23:45:47 +05:00

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:

  1. Safety — screenInboundEmailForAbuse; flagged messages get a minimal HTML response and no order data.
  2. 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.).
  3. L1 orchestrator — If not skipped (off-topic, too sparse, needs order id first, hint unmatched), runL1Orchestrator runs with channel: "email" and emailFrom set to the sender.
  4. 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:

  1. Retrieval — getBlendedStorefrontContext always retrieves KB/FAQ and only includes products when the active module allows it. In strict mode, product retrieval is constrained to linked upsell candidates.
  2. Intent → module — routeCustomerIntent (Groq JSON) maps the customer message to an L1Module.
  3. Module gating — parseAiModulesJson + isModuleEnabled. Disabled modules fall back to FAQ. FAQ is always treated as enabled (cannot be turned off via JSON). UNKNOWN stays enabled for routing stability.
  4. Pillar — Each module has a pillar in MODULE_MANIFESTS: K (knowledge), T (transactional / DB), X (ticket handoff copy), CAT (catalog metafields).
  5. Verification — Widget: OTP-verified session on StorefrontChatConversation (asserted email + expiry). Email: trust From as customer email for order lookup (see runL1 and order tools).
  6. Tools — Orders: orderTools. Products: productTools. Linked upsell allowlist: upsellLinks backed by UpsellProductLink + optional juno.upsell_links metafields.
  7. 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)

Module toggles do not turn off the knowledge base; they only restrict which L1 modules can run after routing.

Known gaps (intentional follow-ups)

  1. Ticket-led (X) flows — Vendor Tickets are derived from EmailLog, not a separate ticket table. Storefront escalations now persist the full storefront transcript and conversation linkage metadata on the EmailLog row.
  2. Spec vs router — Vendor policy text is stored per L1Module in Store.modulePolicies (AI modules UI). The intentRouter only emits declared modules. Extending automation requires adding a module in types, MODULE_MANIFESTS, DEFAULT_ENABLED in aiModules.ts, and orchestrator branches in runL1.ts.
  3. 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, and composeReply.
  • Rate limits and leases for Gmail inbound: gmailAutoReplyGuards.
  • Upsell safety flags:
    • STRICT_UPSELL_LINKS (default true) blocks out-of-policy upsells.
    • L1_INCLUDE_PRODUCT_RETRIEVAL (default true) controls whether product snippets can enter retrieval context (still module-gated).