Editor de expresiones CEL
Usa CEL en mensajes de agentes, condiciones de acciones, salidas de workflows y
comportamiento de formularios. AutoTalk usa CEL-Go en navegador y servidor.
Funciones compartidas usan <family>.<camelCase>; funciones importadas
del tenant usan <slug>.<function>. La referencia
muestra sintaxis y disponibilidad por contexto.
La generación 4 conserva el descriptor {expr, ...options} y usa nombres
más cortos. Las escrituras CEL en la API envían X-Autotalk-Cel-Schema: 4;
las herramientas MCP que reciben código CEL usan celSchemaGeneration: "4".
El código con los prefijos antiguos necesita la migración revisada antes de
ejecutarse con esta generación.
Dónde aparecen las expresiones
La insignia CEL identifica un campo de expresión. Los lugares habituales incluyen mensajes/pre-acciones/post-acciones de agentes, pasos de workflow, templates y etiquetas/visibilidad/previews de Custom Types. Los nombres de campos e identificadores literales de pestañas/referencias no son expresiones automáticamente.
Editor compacto
El editor compacto ofrece resaltado de sintaxis, validación, formato y
Expandir. Usa Ctrl+Shift+F para formatear. Los diagnósticos de sintaxis/tipos
ayudan a localizar problemas; las pruebas comprueban valores representativos.
Los nombres de llamadas se resaltan por sintaxis, incluso llamadas desconocidas.
El color del namespace usa los metadatos actuales de funciones/importaciones;
una selección como values.name sigue siendo dato. El color no confirma la
disponibilidad ni la validez de una función.
La llamada equivalente en la generación 4 es labels.normalizeName desde la versión v1 fijada.
Las capturas siguientes usan datos sintéticos de la generación 3; sus rótulos
autotalk.*/tenant.* preceden a los nombres cortos de los ejemplos de esta página.
CEL nativo y texto literal
Cada campo de expresión almacena una única expresión CEL nativa. Para texto
simple, escribe una cadena CEL entre comillas y escapa comillas o saltos de línea
dentro de ella. El editor expandido muestra esa misma expresión. Para texto
dinámico, escribe "Hello " + contact.name + "!",
o usa una llamada explícita de template:
text.template("Hello {name}!", {
"name": values.coalesce(maps.get(contact, "name"), "Guest")
})
Llaves como {{contact.name}} dentro de una cadena siguen siendo texto literal.
"Hello {{contact.name}}" es texto literal; las llaves no sustituyen un valor.
JSON y MCP usan el mismo descriptor en todos los lugares, incluidos etiquetas de Custom Types, pestañas, previews y condiciones de monitores:
{"expr": "\"Hello \" + contact.name + \"!\"", "onFailure": "throw"}
Opciones avanzadas
| Opción | Finalidad |
|---|---|
| Si falla | Producir un error, devolver null, usar texto literal alternativo o mantener la expresión original |
| Tipo del resultado | Resultado esperado: any, string, number, boolean, date, array u object |
| Valor alternativo | Texto literal usado por la política de fallback |
Un fallback no hace correcta una expresión inválida. Prueba los resultados esperados y los casos de error antes de depender de él.
Entorno de trabajo completo
Expande el campo para abrir el editor completo. La barra abre Explorador y Prueba. Los editores compacto y expandido comparten las importaciones exactas del documento; validación, sugerencias y Prueba usan las mismas versiones. Guarda el agente, workflow, Custom Type o borrador de biblioteca para persistir la expresión y sus versiones fijadas.
Explorador
Explorador lista variables del contexto y funciones con sus firmas. Las
funciones compartidas se agrupan por familia, como maps y text; los recursos
estándar mantienen su sintaxis. Las importaciones exactas añaden funciones en
la raíz del slug, como labels.normalizeName.
Busca y selecciona entradas para insertarlas; funciones no disponibles en el
contexto quedan excluidas.

Explorador filtra las funciones disponibles en el campo actual y muestra sus firmas.
| Contexto | Entradas habituales |
|---|---|
| Agente | contact, contactMessage, conversation, company, parámetros de herramienta declarados |
| Workflow | _workflow, occurrenceDate, entradas manuales y doc, prev, op, model del trigger |
| Formulario | values, item, args, company, employee cuando el formulario los proporciona |
| Función de biblioteca | Solo parámetros nombrados declarados y variables locales |
El contacto es contact. Entradas manuales/de herramientas son nombres de
primer nivel, no un mapa parameters implícito. Si un agente necesita datos de
empleados, obténlos con una acción de datos y lee su salida declarada.
Prueba
- Proporciona valores JSON representativos de las variables.
- Ejecuta con el botón o
Ctrl+Enter. - Compara valor/tipo o examina el diagnóstico.

Prueba evalúa la función pura fijada y devuelve example label.
Incluye datos ausentes/null/vacíos y casos límite. Prueba no ejecuta acciones de workflow automáticamente para producir salidas de pasos; las funciones de contexto y bibliotecas necesitan el contexto del campo y sus importaciones exactas.
Valores opcionales y lógica tipada
Raíces ausentes y acceso directo a campos ausentes producen errores. Usa rutas seguras o selección opcional:
values.coalesce(maps.get(contact, "name"), "Guest")
contact.?nickname.orValue("Guest")
cel.bind(name, maps.get(contact, "name"),
values.present(name) ? name : "Guest")
Presencia y null son distintos: un null presente no usa fallback opcional.
has(contact.name) comprueba presencia; maps.has(contact,"name")
comprueba una ruta no null. Las conversiones nativas usan tipos CEL y pueden
fallar. Conserva unidades externas con datetime.fromMillis / toMillis;
timestamp(int) nativo usa segundos Unix.
Ejemplos de salidas de pasos
workflow.stepOk(0)
workflow.stepData(0, "title", "Unknown")
workflow.stepData(1, "choices.0.message.content", "")
workflow.stepError(2)
La ruta es relativa a data cuando existe ese envelope; no repitas data.
Acciones con salida en raíz usan sus campos declarados. Consulta datos del paso
y salidas en raíz.
Ejecutar código publica result, por lo que workflow.stepData(N,"count")
lee workflow.step(N).result.count. Campos raíz files, logs y
executionTimeMs necesitan maps.get(workflow.step(N),"files",[]).
Rutas ausentes usan el valor alternativo, pero índices inexistentes producen error.
Bibliotecas del tenant
Las bibliotecas permiten reutilizar reglas sin repetir expresiones grandes. Abre Automatizaciones → Bibliotecas y elige Nueva biblioteca → CEL. Introduce el nombre y un namespace (slug) estable y elige Crear biblioteca para abrir el editor de funciones. Añade funciones tipadas y fixtures y usa Verificar para comprobar compilación y pruebas. Guarda el borrador con el botón Guardar de la página. Publicar vN publica la revisión guardada y vuelve a comprobar compilación y fixtures configuradas.
Cada función tiene parámetros nombrados, retorno y cuerpo CEL. Solo lee parámetros, variables locales, funciones puras compartidas y funciones puras importadas. Pasa contactos, relojes y otros datos explícitamente; las bibliotecas no leen estado ambiente de agente/formulario/paso ni realizan I/O.
Borrador de ejemplo
{
"imports": [],
"functions": [{
"name": "normalizeName",
"parameters": [{"name": "value", "type": "string"}],
"returnType": "string",
"body": {"expr": "text.nameKey(value)"},
"tests": [
{"name": "accents-and-spaces", "args": {"value": " Álice Silva "}, "expected": "alice silva"},
{"name": "empty", "args": {"value": ""}, "expected": ""}
]
}]
}
Usa este borrador en una biblioteca de slug labels. Las fixtures proporcionan
exactamente los argumentos nombrados y un único expected o expectedError.
Los errores esperados corresponden a códigos del evaluador. Los tipos admiten
primitivas CEL, list<T>, map<K,V> y optional<T>. Valores JSON especiales usan
el codec $cel, por ejemplo:
{"$cel": "timestamp", "seconds": "1705276800", "nanos": 0}
Publicar y seleccionar una versión exacta
Las versiones publicadas son inmutables. Para la primera importación, selecciona una función legible del tenant aún no importada en las sugerencias o aplica la corrección de importación ausente; esto añade la versión exacta al documento. Con importaciones existentes, abre el número de bibliotecas junto al título del documento/página para gestionarlas y elegir otra versión publicada. Una expresión que llama a una función importada también ofrece Gestionar en el chip de biblioteca del pie. El gestor comparte las importaciones actuales con los editores compacto y expandido. Guarda el documento para persistir cambios. Por MCP/API o en modo JSON, usa los IDs exactos devueltos:
{"celLibraries": [{"libraryId": "000000000000000000000001", "releaseId": "000000000000000000000002"}]}
Cuando el documento omite celLibraries, utiliza las importaciones predeterminadas
de la empresa. Una lista propia sustituye esos valores; [] los desactiva
explícitamente. Los documentos existentes con una lista vacía conservan esa
exclusión. Los mensajes de agentes/Workflows utilizan las importaciones resueltas
de quien los ejecutó y las plantillas usan sus propias importaciones. Los mensajes
enviados mediante la API, contacts.sendMessage o la interfaz de conversaciones
del empleado guardan las versiones exactas al enviarse. Los cambios posteriores
en la empresa no modifican las acciones de opciones de mensajes ya enviados. El
agente asignado a la conversación no proporciona las importaciones del mensaje
de un empleado.
La autoría directa de acciones ejecutables en opciones exige acceso de lectura a
las bibliotecas importadas. La herramienta MCP send_message no acepta actions
en opciones y las rechaza antes del envío; utiliza contacts.sendMessage con
automation:admin para esos mensajes.
Sustituye estos ejemplos por tus IDs. Después puedes llamar:
labels.normalizeName(
values.coalesce(maps.get(contact, "name"), ""))
Editar o publicar no actualiza llamadores automáticamente. Selecciona otra versión exacta deliberadamente; las dependencias también fijan versiones exactas. Recarga un borrador desactualizado antes de volver a guardar/publicar.
labels.normalizeName(value) es una función definida por el tenant en este ejemplo. Cada tenant debe definir e importar su biblioteca labels; el namespace no proporciona una función global de AutoTalk ni la implementación de otro tenant.
Creación por MCP y API
Los clientes MCP usan create_document / update_document con type:"cel_libraries".
Las actualizaciones incluyen el draftRevision leído. Descubre acciones con
list_functions y usa execute_function para validateDraft, testDraft y publish:
En escrituras de bibliotecas con código CEL, pasa celSchemaGeneration: "4"
junto a type y document/data, nunca dentro del borrador guardado. Ejemplo:
create_document({type: "cel_libraries", document, celSchemaGeneration: "4"}).
Un borrador candidate en execute_function también necesita este argumento;
la lectura get_cel_reference no lo necesita.
{"type":"cel_libraries","id":"LIBRARY_ID","functionName":"publish","args":{"expectedDraftRevision":1},"celSchemaGeneration":"4"}
Usa el ID y la revisión actuales. Validación/pruebas admiten candidate no guardado.
get_cel_reference con context:"library" e importaciones celLibraries exactas
devuelve firmas compartidas e importadas permitidas.
La API pública autenticada ofrece las mismas acciones:
POST /v1/dynadata/type/cel_libraries/item/{id}/executeFunction/{functionName}.
El JSON del cuerpo contiene argumentos, como expectedDraftRevision al publicar.
Las escrituras HTTP con código CEL incluyen X-Autotalk-Cel-Schema: 4, también
en clientes fuera del navegador. CRUD usa endpoints y permisos Dynadata normales.
Diagnosticar una expresión en ejecución
Los errores visibles para el equipo identifican expresión y origen. Expande, copia la expresión y revisa sección/índice y diagnóstico. Con logs de depuración, los valores disponibles ayudan a crear una fixture representativa.
Un diagnóstico contraído de demostración identifica el error y muestra una vista previa corta.

Expande el diagnóstico para ver expresión, origen, sección e índice.

La pestaña Variables CEL muestra los valores capturados para el diagnóstico. Estas
tarjetas de demostración ilustran contact.nickname ausente; no contienen registros de clientes.
Corrige la expresión en el agente/workflow/formulario o borrador correspondiente. Prueba y guarda; para bibliotecas, publica y actualiza deliberadamente la importación exacta del llamador. Los borradores no cambian el comportamiento activo hasta que el llamador importa una versión.