Skip to content

feat(automations): add floating AI copilot chat#429

Draft
davibritovilela52-design wants to merge 33 commits into
ArnasDon:mainfrom
davibritovilela52-design:codex/ai-automation-floating-chat
Draft

feat(automations): add floating AI copilot chat#429
davibritovilela52-design wants to merge 33 commits into
ArnasDon:mainfrom
davibritovilela52-design:codex/ai-automation-floating-chat

Conversation

@davibritovilela52-design

Copy link
Copy Markdown

Summary

  • Adds a permission-gated floating AI copilot chat on /automations.
  • Persists chat history locally in the page, renders draft automation cards, and sends serialized {role,text} history to the existing generation API.
  • Adds English and Korean copy plus the shared popover primitive needed by the floating widget.

Test Plan

  • npm test
  • npm run typecheck
  • npm run build
  • changed-file ESLint and git diff --check

Notes

  • Browser visual QA was not completed because the in-app browser runtime failed to initialize locally.

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