Reemplaza el dispatcher en turnEngineV3.js por un statechart formal en
XState v5. La machine es pura: produce un effect log (pending_actions) +
un descriptor de reply (pending_reply) que el runner traduce afuera.
API externa intacta: runTurnV3 sigue retornando { plan, decision } con
shape compatible con pipeline.js. Snapshot persiste en
context.xstate_snapshot dentro del JSONB existente.
- machine/index.js: statechart top-level (idle/cart/shipping/payment/
waiting/awaiting_human) + cart sub-statechart con todo el flujo
multi-turno (searching/resolving/askingClarification/askingQuantity/
computingFromPersonas/added/showing/pricing/researching).
- guards.js: portados de fsm.js (hasCart, wantsToAddProduct, etc).
- actions.js: assigns para mutations + reply descriptors (pending_reply
con templateKey/vars/rawText). Las async no entran en la machine.
- actors.js: fromPromise wrappers de retrieveCandidates y getProductQtyRules.
- runner.js: boot con prev_context.xstate_snapshot o migrateOldContext.
NLU → nluToEvent → send → settle (espera invokes) → realizeReply
(renderReply real con rewriter) → getPersistedSnapshot → format.
- nluToEvent.js: adapter NLU intent → evento XState (1:1).
Feature flags: USE_XSTATE=1 reemplaza el path; XSTATE_SHADOW=1 corre
ambos en paralelo, devuelve legacy y loguea diffs estructurales para
validar antes de flippar prod.
16 unit tests para la machine cubren: arranque, regla universal cart-on-add,
flow de cart con strong/multi match, checkout completo (shipping/pickup/
payment/cash) y rehidratación de snapshot. 224 tests totales pasando.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
76 lines
1.9 KiB
Plaintext
76 lines
1.9 KiB
Plaintext
# Botino - Example Environment Variables
|
|
# Copy this file to .env and fill in the values
|
|
|
|
# ===================
|
|
# Core
|
|
# ===================
|
|
PORT=3000
|
|
TENANT_KEY=piaf
|
|
DATABASE_URL=postgresql://user:password@localhost:5432/botino
|
|
PG_POOL_MAX=10
|
|
PG_IDLE_TIMEOUT_MS=30000
|
|
PG_CONN_TIMEOUT_MS=5000
|
|
APP_ENCRYPTION_KEY=your-32-char-encryption-key-here
|
|
|
|
# ===================
|
|
# OpenAI
|
|
# ===================
|
|
OPENAI_API_KEY=sk-xxx
|
|
OPENAI_MODEL=gpt-4o-mini
|
|
|
|
# ===================
|
|
# Turn Engine
|
|
# ===================
|
|
# v1 = pipeline actual (heurísticas + guardrails + LLM plan final)
|
|
# v2 = LLM-first NLU, deterministic core (nuevo motor)
|
|
TURN_ENGINE=v1
|
|
|
|
# ===================
|
|
# WooCommerce (usado por seed y fallback)
|
|
# Estas variables son leídas por scripts/seed-tenant.mjs para crear
|
|
# la configuración inicial del tenant en la base de datos.
|
|
# ===================
|
|
WOO_BASE_URL=https://tu-tienda.com
|
|
WOO_CONSUMER_KEY=ck_xxx
|
|
WOO_CONSUMER_SECRET=cs_xxx
|
|
|
|
# ===================
|
|
# Evolution API - WhatsApp
|
|
# ===================
|
|
EVOLUTION_API_URL=https://api.evolution.com
|
|
EVOLUTION_API_KEY=your-api-key
|
|
EVOLUTION_INSTANCE_NAME=piaf
|
|
EVOLUTION_SEND_ENABLED=0 # 0=solo BD (pruebas), 1=envía a WhatsApp (producción)
|
|
|
|
# ===================
|
|
# Limits
|
|
# ===================
|
|
LIMIT_CONVERSATIONS=100
|
|
MAX_CHARS_PER_MESSAGE=4000
|
|
|
|
# ===================
|
|
# Reply Rewriter (LLM adapta templates al contexto)
|
|
# ===================
|
|
REPLY_REWRITER=0
|
|
REPLY_REWRITER_TIMEOUT_MS=1500
|
|
|
|
# ===================
|
|
# XState (Turn engine v2)
|
|
# ===================
|
|
# USE_XSTATE=1 → reemplaza dispatcher legacy con statechart formal
|
|
# XSTATE_SHADOW=1 → corre ambos paths, devuelve legacy, loguea diffs en logs
|
|
USE_XSTATE=0
|
|
XSTATE_SHADOW=0
|
|
XSTATE_SETTLE_MS=10000
|
|
|
|
# ===================
|
|
# Debug Flags (1/true/yes/on para activar)
|
|
# ===================
|
|
DEBUG_PERF=0
|
|
DEBUG_WOO_HTTP=0
|
|
DEBUG_WOO_PRODUCTS=0
|
|
DEBUG_LLM=0
|
|
DEBUG_EVOLUTION=0
|
|
DEBUG_DB=0
|
|
DEBUG_RESOLVE=0
|