Skip to content

Add typed custom fields - #426

Open
davibritovilela52-design wants to merge 33 commits into
ArnasDon:mainfrom
davibritovilela52-design:codex/custom-field-types
Open

Add typed custom fields#426
davibritovilela52-design wants to merge 33 commits into
ArnasDon:mainfrom
davibritovilela52-design:codex/custom-field-types

Conversation

@davibritovilela52-design

Copy link
Copy Markdown

Summary

  • Add reusable typed custom-field utilities for text, number, date, select, checkbox, URL, and phone fields.
  • Update custom-field settings UI to create typed fields, including select options and locked type display.
  • Render, validate, serialize, and format typed custom values in contact details while keeping values stored as TEXT for automation compatibility.

Test Plan

  • npm.cmd run typecheck
  • npm.cmd run lint
  • npm.cmd test
  • npm.cmd run build
  • UI E2E on local wacrm:3002: created all seven field types, validated invalid URL, saved values, closed and reopened contact, confirmed persisted formatted values.
  • Supabase cleanup verified temporary fields/values remaining_fields=0 and remaining_values=0.
  • Migration validated in temporary table with rollback for normalization and CHECK rejection.

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