Skip to content

Add RAG-backed AI agents#428

Draft
davibritovilela52-design wants to merge 64 commits into
ArnasDon:mainfrom
davibritovilela52-design:codex/ai-rag-agents
Draft

Add RAG-backed AI agents#428
davibritovilela52-design wants to merge 64 commits into
ArnasDon:mainfrom
davibritovilela52-design:codex/ai-rag-agents

Conversation

@davibritovilela52-design

Copy link
Copy Markdown

Summary

  • Add account-scoped RAG schema, ingestion, hybrid retrieval, semantic embeddings, and knowledge management APIs/UI.
  • Wire WhatsApp AI dispatch through specialist routing, account agent definitions, allowed-action enforcement, citations, retrieval/tool/run logs, and tenant guards.
  • Add encrypted BYOK settings for knowledge embeddings without returning plaintext keys.

Test Plan

  • npx vitest run src/lib/ai src/app/api/ai
  • npm test
  • npm run typecheck
  • git diff --check

Notes

  • npm run build compiles and passes TypeScript, then fails prerendering unchanged /automations/new with a Next invariant (Expected workStore to be initialized). Final branch review judged that failure outside this branch's diff.
  • Requires migrations 038_ai_agent.sql and 041_ai_knowledge_rag.sql, plus a valid ENCRYPTION_KEY in target environments.

dvilela-prime and others added 30 commits July 20, 2026 16:25
Drops the BYOK AI reply-assistant feature entirely (auto-reply,
knowledge base, playground, usage dashboard, /agents section,
/api/ai/* routes) ahead of a from-scratch WhatsApp AI agent design.
Bundled with the pending Decizyon brand identity changes that were
staged alongside it.

Migration required: apply supabase/migrations/037_drop_ai.sql
(destructive — drops AI config, knowledge base, usage, and
conversation auto-reply data).
Supersedes the two discarded plans (pipeline-stage AI classifier,
NL automation builder) that were written against the now-removed
BYOK AI infra. Single structured-decision-per-event architecture
instead of a full agent loop, per chatwoot/OpenHands pattern review.
13 tasks: schema, provider-agnostic generateJson foundation, AiConfig
settings UI, move_deal_stage/deal_stage_changed engine + builder
support, moveDealStage helper, WhatsApp agent decision+dispatch,
automation copilot generation+UI, full regression pass.
Implements Task 2: AI provider foundation with provider-agnostic structured-output
call. Creates types, provider adapters for OpenAI and Anthropic, and the main
generateJson<T>() function that handles JSON parsing with fallback for
prose-wrapped responses.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a new Settings > AI agent panel that reads/writes GET and PUT
/api/ai/config (Task 3), letting an account configure its AI
provider/model/API key and auto-reply/pipeline-move behavior.
Loads a conversation's recent text history and linked deal stage
(buildAgentContext), then asks the LLM for a structured decision
(reply/tags/stage move/handoff) via generateJson and sanitizes the
result against the account's real tags/pipelines/stages so a
hallucinated id can never reach the executor.
…ilently degrading

Both messages and deals queries now destructure and check the error field, throwing
descriptive errors naming the table and underlying error message when non-null,
following the established pattern in src/lib/automations/resources.ts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wires the Task 9 decision engine into the real inbound webhook path:
after the automation-trigger dispatch, fire dispatchInboundToAgent
fire-and-forget so the AI decision (reply/tag/move-stage/handoff)
runs without ever blocking or breaking the webhook's response to
Meta. Adds the aiAgentDecision rate-limit bucket (30/min per account,
checked before the AI call).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds generateAutomationFromPrompt, the second and last consumer of the
"never trust a model-returned id" sanitizer pattern in this plan: a
single generateJson call per chat turn that returns either a
clarifying question or a draft automation built only from real
tag/pipeline/stage ids.

Fixes a parent_index indexing bug present in the task brief's
reference implementation: the model's parent_index values are
positions in its own raw steps array, but ALLOWED_STEPS filtering can
drop steps, shortening the output array and desynchronizing raw vs.
output indices. Resolving parent_index against the raw loop index (as
the brief's code did) could produce self- or forward-referencing
parent links once an earlier raw step was dropped. Fixed with a
two-pass approach: filter first, then remap parent_index through a
raw-index -> output-index map, keeping only backward references.
Covered by two added regression tests beyond the brief's five.
Adds POST /api/automations/generate (agent+, rate-limited) wrapping
generateAutomationFromPrompt with pre-flight activation validation,
plus an AiCopilotPanel chat dialog wired into the automations list
page ("Ask AI" button next to "New automation"). Approved drafts are
created inactive via the existing POST /api/automations and open in
the normal builder for review.
…cap reply_text length

Addresses findings from the final whole-branch review:
- loadAutomationResources() no longer fetches all tenants' pipeline_stages
  unfiltered when called via the service-role client (agent-dispatch's hot
  path on every inbound WhatsApp message) — now scoped via the account's
  own pipeline ids.
- agent-dispatch.ts's handoff conversation update now logs on failure
  instead of silently swallowing it, matching every other write in the
  same function.
- agent-decide.ts's sanitize() now caps reply_text at 4096 chars (WhatsApp's
  own text message limit), matching the existing handoff_reason cap pattern.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants