Changelog
Qué hay de nuevo.
Cada mejora de la plataforma, a medida que se envía.
· SecurityService
Relevo condicional-LLPA autoring
Relays POST ********** a través de la org-stamping escribir ayudante, así que un mayordodo de autores condicionales sólo para su propio inquilino.
· kamo-internal
Bulk-reassign seleccionó a un miembro del equipo
La cuadrícula ya tenía buzones multiseleccionados pero nada que ver con una selección. Comprobar filas revela ahora una acción de Reassign junto a las otras acciones de plomo, cerradas en REASSIGN-LEADS-MANUALMENTE (el servidor lo vuelve a comprobar; esto es sólo de conveniencia). Usa checkRight en lugar de comprobarRole para que el modo dios coinja con los has de backend bypass, checkRole no pasa por alto y diverge para los usuarios de dios. El diálogo elige un miembro de destino por búsqueda, toma una nota opcional, y dice por adelantado que el miembro será enviado por correo electrónico, ya que ese es el punto de la función. Indigo/blue en lugar de Hot Reassign's naranja/rosa: esto es un acción deliberada de administración a granel, no una transferencia urgente de llamadas. La casilla de verificación de la cabecera selecciona cada fila en la cuadrícula del lado del cliente. grande org - por lo que la tapa de 250 se aplica aquí también. De lo contrario el titular "seleccionar todo y reasignar" flujo fallaría del lado del servidor sólo después de que el usuario había rellenado en todo el diálogo, con un error sin traducir. La selección se borró a través de seleccionadosIdsRef antes de recargar: loadLeads reselecciona lo que sea que ese árbitro tenga, así que dejarlo poblado volvería a comprobar el filas acaban de moverse. El mensaje de resultado está compuesto en lugar de una cadena de otro, porque un lote puede ser parcial y no notificado y la cadena reportada solamente el primero.
· SecurityService
Bulk-reassign endpoint endpoint, cerrado en REASSIGN-LEADS-MANUALMENTE
POST **************** mueve un lote de pistas en un equipo miembro y correos electrónicos que un miembro una vez para todo el lote. Autorización usa REASSIGN-LEADUALLY (149) - la derecha nombrada exactamente - Esto. Eso es más estricto que el camino de un solo líder en PUT /leads/Eid, que comprueba ASSIGN-LEADS; reasignar cien pistas es un radio de explosión diferente de reasignar uno, y los dos derechos existen para que puedan distinguirse. El nivel de visibilidad no asignado se aplica aquí también. Asignación ES una visibilidad subvención: una vez que se asigna una pista a la persona que llama lee como "asignada para mí", que levanta el 403 sin asignar y se salta la máscara de contacto-info. Sin esto. comprobar que una persona que tiene una llamada que sostiene 149, pero no VIEW-UNASSIGNED-LEADS podría auto-asignar leads la rejilla se esconde de ellos y las bálea en las totalmente legibles. Se saltó pistas informe NOT.FOUND - emparejamiento de lo que su propia cuadrícula muestra - por lo que la respuesta no puede enumerar pistas ocultas o extranjeras. El lote deliberadamente no es todo o nada: cada asignaciónLead corre en su propio transacción y un mal id se convierte en un salto, porque desechar nueve bien Las reasignaciones sobre el décimo son peores que las reportadas que no se han llevado. Capturado a 250 por llamada para atar tanto las cerraba las cerrajas de la fila como el fan-out en tiempo real. El notificante resuelve sus datos en una transacción corta a través de un frijol separado y envía después, así que una llamada de ida con un tiempo de 30s de 30 nunca pincha un Conexión CRDB. Cruzar el límite del frijol es también lo que hace que el transporte sea. aplicar en absoluto. autoinvocación correría silenciosamente sin transacción y la La asociación de usuarios LAZY lanzaría.
· EmailService
Variables de muestra para la plantilla LEADS-ASSIGNED
Sin un caso aquí, la vista previa del editor de plantillas de administración renderice la nueva plantilla con cada marcador de posición en blanco, que se lee como una plantilla rota en lugar de una sin llenar uno. notasBlock está pre-renderizado HTML porque el renderizador no tiene condicionales - el remitente se derrumba a "" cuando no hay nota.
· kamo-shared-library
Modelo de correo electrónico LEADS-ASSIGNED; endurece assignLead for bulk use
asignó a Leead tenía cero llamadas y nunca había corrido en producción. Antes de cablear el camino de reasignación a granel hacia ella, dárselo las garantías que el camino necesita: - tomar orgId y verificar BOTH el plomo y el nuevo cesionario le pertenecen, así que a La reasignación no puede llegar a los inquilinos (incununciado como "no encontrado" en lugar de "probado" por lo que el error no se puede usar para sondear ids de plomo extraños) - bloquear la fila con findByUidForUpdate: una reasignación manual y una simulacional acepto de la piscina-acepto apunta a la misma pista y de lo contrario se entrelazaría en una pérdida actualización - despejar las banderas de la piscina, espejo CreditLeadAssignmentService. Una ventaja marcada para auto-asignación de lo contrario permanece en la piscina después de ser reclamada a mano y sacan de su nuevo dueño - publicar enrutamiento de chat, como ya lo hace la actualizaciónLead, así que el prestatario está abierto en vivo chat sigue la pista en lugar de quedarse con el oficial anterior También agregue la plantilla canónica LEADS-ASSIGNED. La clave debe estar en CANONICAL-KEYS o nunca se puede semilla y nunca puede auto-curar, y cada enviado devuelve un 404.
· kamo-shared-library
Añadir MANAGE-ORG-BRANDING (174)
Puntos finales de marca de Org (logos, colores, fondos, aprovisionamiento temático) fueron propietario-o-dios sólo, sin dejar forma de delegar marca sin entregar la propiedad del org. Añade la derecha deleble; el propietario comprueba la estancia como un subvención implícita para que los propietarios existentes sigan trabajando sin que se les asigne.
· kamo-internal
Autor matrices de elegibilidad del panel de catálogo
Sin una matriz que cubra la ocupación y el propósito de un escenario, los precios devuelve NO-COVERAGE . Así que antes de esto, sólo se podía tener un precio de la compra de una residencia principal. Los autores de la forma a matriz y sus celdas para un tipo de límite elegido, ocupación y propósito, con celda de adición/remove filas, junto con la forma de política de bloqueo en el mismo panel. Dejando el producto desconectado desconectado una matriz por producto ACTIVE del inversor, porque El alcance del producto de la matriz NO es NULL y no puede expresar "todos los productos" como una sola fila.
· SecurityService
Relevo elegibilidad-matriz de autoría; reconstrucción recoge el currículum SUSPENDED
Relays POST ********** a través de la escritura existente de la estampación de org ayudante, así que un mayordomo los autores matrices sólo para su propio inquilino. Este empuje también se reconstruye contra el cambio compartido que permite un curriculum vitae de préstamo SUSPENDED. La biblioteca compartida de kamo no tiene CI propio. Cada clones de servicio y lo construye de origen. para que la solución llegue a este servicio sólo cuando este servicio se reconstruye.
· kamo-internal
Reconstruir el estudio de agentes como un espacio de trabajo de ancho completo
Eliminar la tapa de anchura no era la solución; el diseño en sí necesitaba ser diseñado por el espacio más que tolerado en él. El estudio es ahora tres zonas lado a lado: - **carril exterior** - las secciones, con el actual resaltado mientras desplazamiento (IntersectionObservador, de peso superior por lo que una sección se vuelve actual cuando su cabecera llega a donde realmente se encuentra la atención). Las secciones escritas a mano están marcadas, por lo que a La parte manuscrita es más tarde sin abrir todas. - **Editor** Las secciones mismas, azulado en tantas columnas como el el puerto de visión se mantiene en lugar de una estrecha cinta. - **Conversación en vivo** - una columna real en una amplia pantalla, no una tira que colapsa el contenido cuando se abre. Este es el bucle de edición y reloj del estudio. existe para: cambiar una instrucción, ver la respuesta cambiar, sin navegar. Una instancia de TestDrivePanel, reposicionamiento en lugar de duplicarla. dos veces empezaría dos sesiones de desechables. Abajo xl cae debajo del editor como una fila de ancho completo en lugar de exprimir una tercera columna en una exhibición sin espacio por uno, y el carril se esconde por completo en pantallas pequeñas.
· kamo-internal
Políticas de bloqueo de los autores sin uno, ninguna tarifa se puede bloquear en absoluto
Commitment RateCommitmentService rechaza un candado cada vez que el resultado precio no lleva lockPolicyVersionId ("se requiere versión de política de bloqueo"), y un resultado solo lleva uno si el inversor tiene una versión publicada en materia de política de bloqueo. Ninguna IU podría publicar una, así que la fijación de tarifas era inalcanzable para cada inquilino, mientras que el punto final en sí ya estaba construido, org-gated y sustituyendo correctamente. Sólo faltaba el método del cliente y este formulario. La forma toma los períodos de bloqueo ofrecidos como una lista ordenada porque el PRIMERO se convierte en el incumplimiento, por lo que deliberadamente no las clasifica; entradas que no son un todo positivo El número de días se abandonan en lugar de ser enviados como un mal término de bloqueo.
· kamo-internal
Muestra cómo lo está haciendo cada agente
Añade una sección de actuación a la parte superior del estudio de agentes: conversaciones, cómo A menudo una persona se hizo cargo y lo que lo desencadenó, los resultados de alcance y el costo. Escrito para que ninguna cifra pueda inducir mal: - Cero rinde como la palabra 'Ninguno', nunca 0. - Una parte sólo se hace cuando hay un denominador; de lo contrario 'No hay conversaciones Todavía para compararme con'. No hay porcentajes de denominador cero. - Cuando nada en el período que lleva un precio, la cifra de NO se muestra en absoluto - Sólo una explicación de que los precios se establecieron después de que ocurrió el tráfico. Parcial la cobertura muestra la cantidad más cuántas respuestas faltan de ella. - La divulgación suprimida se presenta como la característica que es: "Se mantienen en: "Se mantienen en propósito - son tu historial de por qué alguien no fue contactado. - Códigos desconocidos de enum se degradan a texto legible en lugar de una ruta de clave cruda. Se eliminaron los mensajes de porversión y las columnas de entrega: la API no agrega ellos por versión, por lo que esas celdas habrían hecho un 0 fabricado como si fuera se había medido. Sólo las conversaciones responden para qué sirve la tabla, que salvó copia manejada qué tráfico. Doblado en el documento de estudio de desplazamiento existente en lugar de una nueva pestaña, y mantenido fuera de la lista de agentes, donde un 0 desnudo contra cada agente sería el exacto mal lectura se evitó.
· AIService
Marcar de puntuación por agente
Lo que hizo en realidad cada agente: conversaciones, con qué frecuencia una persona tenía que tomar el releva y por qué, los resultados de la divulgación, incluidos los que se pusieron de control, y lo que costó. Cada número es uno que los datos pueden soportar. Tres cosas son deliberadamente NO aquí: - **No totales situlados.** Son reales en la ruta de sincronización y fabricados en el streaming uno (contenido.length()/4), por lo que cualquier total es parte inventada. Respuestas de costos la misma pregunta honestamente, porque es nula en lugar de adivinar dónde se desconoce el precio. - **No hay resolución o tasa de desviación.** Nada observa si una conversación terminó bien, y "no hubo entrega" no es una prueba de éxito. - **No hay mensajes porversión o cuentas de entrega.** Esos no se agregan por versión, y emitir 0 para ellos sería una invención renderizada como un medición - el fallo preciso que existe esta pantalla para evitar. El costo lleva una bandera rastreada explícita y una cantidad nula en lugar de 0 cuando Nada en la ventana tenía un precio, por lo que un org a cuyo tráfico es anterior a los precios ve 'no registrado' en lugar de un confiado $0.00. precioCalls es la autoridad más bien que la suma, por lo que un cero genuino de las llamadas de nivel libre a precio todavía se lee como rastreado. La prosa transcripción está cerrada en VIEW-SALES-AGENT-TRANSCRIPTS por separado de la cuenta - el resumen del modelo de un visitante específico es el contenido de conversación, no un métrica. Agentes sin tráfico devuelve un marcador vacío estructuralmente completo: un agente que falta en la lista se lee como un error, un agente presente con ceros lee como la verdad. parseHandoffArguments se comparte ahora con la ruta del chat en lugar de reimplementado, por lo que la coacción de razones inventadas para no ir a la deriva entre los dos. Suite es 150 pruebas, verde.
· kamo-shared-library
Agrupadas consultas agregadas para el marcador agente
Doce agregados de preguntas a través de sesiones, mensajes, registros de uso y salida toca, por lo que un marcador es un púcito de consultas agrupadas en lugar de cargar filas en la memoria. Dos propiedades se aplican en los predicados en lugar de dejarlas a los que llaman: - **isLas sesiones de prueba se excluyen en la propia consulta.** En un agente joven el Las propias unidades de prueba del autor serían de otra manera la mayoría de los datos, y un llamante que Olvida el filtro produce números que se ven reales y no lo son. - **count(costsEstimato) cuenta sólo con los costos NON-NULL.** Eso es lo que permite el El marcador distingue 'nada tenía precio' de 'costó cero' - colate esos pondrían un seguro $0.00 delante de un org cuyo tráfico simplemente Precios anteriores. Los toques salientes se agrupan por decisión en lugar de filtrados a los envíos. El las negativas son la mitad más interesante: un agente cuyos toques son casi todos SUPPRESSED-QUIET-HOURS está mal configurado, y eso es invisible si los decodificadores son Descartado.
· kamo-internal
Editar lo que cuesta cada modelo
Añade la edición de precios por modelo a la pantalla de configuración del proveedor. Los precios se siembran de precio de lista publicado por cada vendedor donde lo sabemos, y en blanco donde no - un costo en blanco simplemente no se rastrea para ese modelo, que es mejor que un número que está confiadomente equivocado. Copy le dice a la gente que revise las cifras de semilla contra su propio proyecto de ley en lugar de Presentándolos como autorizados. Arregla un error de visualización atropida en revisión: el adornos de rastro-cero habría hecho un precio de 10 como 1. Ahora desnuda ceros sólo después del punto decimal.
· AIService
Catálogo de precios de modelos, ruta de escritura y relleno
Contabilidad de costos nunca podría funcionar: AiModel tiene columnas de precios, AiModelController los lee y ChatOrquestrationService les lee para calcular el costo de la estimación - pero NADA las escribió en ninguna parte. Los modelos sólo son creados por el desmontaje del proveedor, y no hay precios de rendimiento de API de proveedor. 140 modelos, 0 de precio, sin ruta por la que podría cambiar. Las columnas eran estructuralmente inalcanzables. Tres partes: - ModeloPricingCatalog Semillas vendedores LIST precios en el descubrimiento, emparejado en un identificado identificador normalizado con una regla de prefijo límite de guión para gpt-4 nunca puede reclame gpt-4o. Los modelos no chat (TTS, incrustaciones, en tiempo real) son rechazados por reutilizando la marca de la modalidad existente - desplazan una hoja diferente. - PATCH endpoint . UI para que un org pueda corregir o liquidar un precio. Org-scoped exactamente como el DELETE existente. - Volver relleno sólo las columnas NULL, por columna de forma independiente, y nunca sobrescribe lo que un org ha establecido - de lo contrario haría que los precios fueran editables sería un mentira. Idempotente, y envuelto así que la contabilidad de costos nunca puede bloquear la bota. **Un modelo en el que no confiamos en obtener precio NO en lugar de uno adivinado.** GPT-5, o3, la mayoría de Mistral, DeepSeek, xAI, Cohere y Meta están deliberadamente en blanco; OpenRouter y AbrazarFace nunca coinciden con el diseño, ya que facturan sus propias tarifas y heredar precios previos sería una suposición. Un precio equivocado produce un cifra en forma de facturas que se equivoca con confianza - la misma razón por la que el costo sigue siendo no se computó en el camino de la transmisión, donde se fabrican recuentos simberos. Conversión a la columna per-1k utiliza RoundingMode.UNNECESSARY a propósito: un precio necesitando más de 6 decimales lanzan a clase-init en lugar de almacenar silenciosamente un razón y queda en blanco. Suite es 145 pruebas, verde.
· kamo-internal
Mostrar el contexto de entrega de IA al agente apoderándose de
Rendera un evento del sistema de AI-HANDOFF como una tarjeta con la razón, el resumen de la IA, y una transcripción plegable de la conversación hasta ahora - por lo que el prestatario lo hace no hay que volver a explicarse a la persona que contesta. Los tres estados degradados son explícitos y visibles en lugar de silenciosos: transcripción no disponible, transcripción truncada y carga útil despojadas en tránsito. Un agente debe nunca dejarse creyendo que tienen el contexto completo cuando no lo hacen. Visitante y agente comparten un tema STOMP, por lo que el marco en vivo llega redactado (el El resumen de AI es su evaluación privada del visitante y no puede ir a su navegador). En lugar de decirle al agente que vuelva a cargar, la tarjeta vuelve a leer la fila completa una vez desde su propio endpoint autenticado. La re-leer se valida antes de que adoptado - una respuesta que se produjo todavía desgarrada se rechaza en lugar de utilizarse, Así que la advertencia sólo puede quedar clara cuando el contexto se ganó genuinamente. Cualquier fracaso cae de nuevo en el mensaje de recarga.
· APIService
Proxy la ruta pública de entrega de IA-Ahuman
Añade POST ************* axilado a MediaService junto a su creaciónSupportSession hermano. Sin esto la función de entrega estaba muerta a su llegada: el punto final de MediaService dura-requiere X-Internal-Auth, X-Public-Chat-Org-Id y X-Public-Chat-Key-Hash, que sólo esta puerta de entrada se inyecta, por lo que el widget's POST 404'd aquí y nunca Lo alcanzó. Lleva el mismo guardia condicional de *** que createSupportSession. Corridas de mano el camino de la creación de sesión completa, por lo que proxying desnudo habría dejado un Ruta creadora de billetes que eluda la prueba de trabajo que hace cumplir su hermano.
· MediaService
Llebra la conversación de IA en el hilo humano en el a mano
Crea o reutiliza la sesión de soporte, copia la transcripción de AI en un sistema evento, lo desvía y le dice al visitante honestamente lo que sucede después. La confidencialidad está dividida por el público, que el primer pase se dio al revés. El Resumen y razón de AIDetail son su evaluación privada del visitante, y la Carga completa estaba llegando al propio navegador del visitante a través de dos puertas REST y el marco STOMP mientras el agente no veía nada. La acción roja se aplica ahora en cada Ruta orientada al visitante; la fila persistente mantiene la carga útil completa para el agente. chat.session.-guid es un solo tema a un solo tema a los que ambas audiencias se suscriben, por lo que el en vivo marco se corta a lo que el visitante puede ver y el agente de IU relee la fila completa desde su propio endpoint autenticado. La impermedupotencia está en la borda aiSessionGuid, org-scoped, y se comprueba ANTES de crear lo que sea. Cultivarlo en la sesión y comprobar después de la creación - lo obvio forma - es inútil precisamente cuando importa: un reiniciar que perdió su sesión Token siempre pasa el cheque y produce un billete duplicado y un segundo agente página. Tra transcriptAunque ahora informa lo que realmente sucedió. Anteriormente volvió. cierto incluso cuando la escritura había fracasado en silencio, que es la peor posible combinación: al visitante se le dice que su contexto se encontró, el hilo del agente es vacía, y ninguna de las partes lo sabe. Copiado-a-a-al-go-off, no migración: AI se turna de estancia donde los lee análisis.
· AIService
Entrenamiento de agente a un humano, con contexto
La IA no podía pedir previamente una persona: las reglas de la escalada llegaron al modelo a través de la señal compilada, pero no había ninguna señal legible por máquina hacia atrás, por lo que el El modelo sólo podía decir que traería a alguien y no pasó nada. - Herramienta Synthetic kamo-quest-quest-human, descrita de la propia empresa. Títulos de la regla de escalada para que el modelo vea condiciones desencadenantes idénticas en el rápido y la herramienta. Interceptado antes del despacho MCP - es una señal, no una llamada de la herramienta real - y la fila TOOL que persiste es lo que hace que la razón sea duradera y listos para análisis con cero nuevas columnas. - Apegado SOLAMENTE cuando el canal realmente tiene soporte en vivo habilitado. Entregando a IA solo es una herramienta que promete a un humano que nunca puede llegar es peor que no tener ninguna herramienta: el widget no tiene pestaña de Soporte, por lo que la señal se deja caer y la El visitante se queda esperando a alguien que nunca venía. - Nueva variable interna devuelve la razón de entrega, el resumen de la IA para quien sea toma el relevo, y la transcripción de USUARIOS/ASSISTANT. Las filas de TOOL y SISTEMA son excluido - el ser humano necesita la conversación, no la maquinaria. - razón Detalle y resumen se ocultan deliberadamente al navegador del visitante: son la evaluación privada del modelo del visitante. Sólo se le pidió, razón. cruces al cliente; MediaService consigue el lado del servidor de descanso. - Los giros de IA nunca se mueven o eliminan. AiChatMessage se mantiene el sistema de análisis de registro; el lado humano obtiene una copia. También corrige un fallo latente encontrado en el camino: el bloque de herramientas ignoró el modelo per supportToolUse flag, por lo que un modelo explícitamente marcado como no herramientas de apoyo era Todavía los envió. 31 de 140 modelos están marcados en falso; ai-mcp.server-configs es en racimo vacía, por lo que el radio de explosión de hoy es cero. Suite es 124 pruebas, verde.
· MediaService
Acepta agente-autor de divulgación en un hilo de prestatario abierto
El despachador de alcance de la contraparte AIService llama. Sin él el todo senda de salida terminada en un 404 registrado - la puerta autorizó un toque, el El mensaje estaba compuesto, y no había dónde ponerlo. La propiedad se mantiene dividida deliberadamente: AIService decide que un toque puede salir y escribe el texto, este servicio lo coloca. Escribiendo estas filas de AIService desdibujaría la propiedad de la transcripción al servicio que no posee ni la charla Mesas ni el enchufe. Dos cosas que no hará. Nunca crea una conversación - la divulgación puede reanudarse un hilo el visitante ya abierto, nunca conjurense una ventana de chat a alguien que No lo hizo. Y nunca cruza orgs: una ventaja que se resuelve en el billete de otra org pondría al agente de una org dentro de la conversación de otro org, así que el org está Coete contra el billete en lugar de confiar en el que llama. El mensaje se atribuye al miembro de la sesión, exactamente como mensaje de visitante NO al oficial humano asignado. Render un mensaje compuesto por IA como aunque una persona nombrada y con licencia escribió que es lo que existe una regla de revelación de IA a prevenir. asegurarseSuscripción precede a la publicación NATS porque el consumidor utiliza DeliverPolicy.Nuevo: publicar primero persistiría el mensaje pero lo soltaría de a cada cliente conectado. Devuelve tanto id como mensajeId para el registro de auditoría de alcance hace referencia el mensaje más que el hilo. 404 cuando no existe ningún hilo abierto, Así que el llamante registra un fallo limpio en lugar de asumir la entrega.
· AIService
Desencadenantes de salida, programador y despacho de chat web
Hace que la espina dorsal de alcance se incendia. La puerta, estado de contacto, consentimiento y ya existía auditoría; nada hizo que se evaluara un toque. - NATS habilitado para AIService a través de su propio k8s/configmap.yaml (cada servicio Java lleva su propio dir k8s; KlusterServices posee sólo clúster infra). JetStream se deja deliberadamente OFF: NatsConfig afirma su propio factor de replicación contra Corrientes de suministro central en la startup, y AIService solo se suscribe al núcleo NATS y no publica nada, así que permitirlo no ganaría nada y arriesgarse a un segundo servicio que afirma conteos de réplicas. - AgentOutboundConsumer suscribe seguridad.leads.rt. y consume SOLAMENTE LEAD.CREATED/LEAD-UPDATED. La editorial también emite eventos de cerradura y estadísticas - la mano a una persona porque un colega tomó un candado de edición en su historial no es defendible. Los muchachos llegan como cuerdas de la editorial, así que están analizados. como texto en lugar de comoLong(). - AgenteOutboundScheduler evalúa los desencadenantes de horarios bajo cuatro límites: conjunto de org derivado de agentes que realmente tienen divulgación en (capoteada), un delgado deslizamiento la porción de tiempo para que el costo rastree la nueva tasa de plomo en lugar de las corrientes totales, una fila per-tick tapa, y un amortiguador de reevaluación para que se vuelva a cruzar una pista durante las horas tranquilas una vez en lugar de cada garrafa por un día. - Composición de las semillas de semillas Completado con el símbolo compilado de la versión PUBLISHED, Nunca el borrador, más la intención desencadenante. Registros de fallos de composición FAILED; no hay ningún mensaje enlatado. - El despacho de WEB-CHAT continúa solo con un hilo existente. La divulgación puede reanudar un conversación que el visitante abrió; puede no conjurar una ventana de chat a alguien que nunca abrió uno. - SMS/EMAIL/SOCIAL-DM ruta a una FAILED registrada nombrando el cumplimiento faltante fontanera, así que un org apuntando con un gatillo a SMS ve por qué en el registro de divulgación inmediatamente en vez de nada. 23 nuevas pruebas; suite es de 68 y verde.
· kamo-internal
Editor de texto requerido; dedupe Configuraciones generales de IA; arreglar el modelo de conmutación
Añade un editor para el texto de apertura/cierre necesario de toda la or en todo el mundo - el compilador y existían columnas pero nada podía ponerlas, así que la capacidad estaba muerta. Copia afirma claramente que los agentes no pueden eliminarlo y que ese ahorro lo aplica a todos los agente inmediatamente, y el brindis informa cuántos agentes fueron republicados más bien que un 'Salvado', porque los agentes vivos simplemente cambiaron lo que dicen. Dos errores preexistentes encontrados en el camino: - El interruptor 'Auto-sel mejor modelo disponible' nunca ha funcionado. El frontend leer data.autoSelModel y envió autoSelectModel, pero el backend devuelve y espera autoModelEnabled - por lo que el interruptor siempre hecho true y su valor era Desechado en cada salvación. Frente fijo; no se necesita ningún cambio de servidor. - AiGeneralSettings.tsx era código muerto, nunca importado, mientras que un literal en línea duplicado vivió en la parte inferior de SecurityModelsTab.tsx. En lugar de implementar texto requerido dos veces, se suprime el duplicado y SecurityModelsTab importa componente compartido. También sustituye la propina de ayuda a los agentes de ventas, que aún decía a los usuarios que la función era venir pronto.
· AIService
Persista org-wide texto requerido y aplicarlo inmediatamente
AiOrgSettings ganó ya forzarPreamble/forcedFooter y SalesAgentCompiler los dobla en cada agente, pero el controlador de configuración no lee ni escribió ellos - así que la capacidad estaba muerta: una salvación parecía tener éxito y volvió en blanco en recarga. GET devuelve ahora ambos campos (incluyendo los impagos de no fijación) y PUT los persiste, normalizándose en blanco a nulo, por lo que despejar un campo en realidad lo despeja en lugar de dejar una cuerda vacía para ser doblada como un separador extraviado. El texto requerido ahora tiene efecto IMMEDIATELY, recompilando y reeditándose cada agente publicado en la zona. Dejar que se aplique en la próxima publicación de cada agente era más barato y es una trampa: un administrador que añade 'siempre dices que eres un automatizado asistente creerá que está vivo, y un agente que nadie vuelve a publicar Seguiría hablando sin él indefinidamente. Una línea requerida que en silencio lo hace no aplicar es peor que no ofrecer uno. Cada agente afectado se salva un nuevo copiada con por qué, y la respuesta reporta cuántos fueron republicados así la interfaz de usuario puede decir lo que realmente sucedió en lugar de simplemente 'Salvado'.
· kamo-internal
Estudio de Agentes de Ventas de AI de página completa, reemplazando los modales
El editor de agentes era un diálogo MUI de 800 penes de 800 penes cuya superficie era una puntera de 10 libras. textarea, en la única pestaña de IA que usaba un diálogo. Ahora es un dedicado ruta, y el modelo de edición detrás de él está estructurado en lugar de una mancha. - /settings/ai/sales-agents/new , una columna de 720px, no el estudio. Tarjetas de plantilla (la tarjeta ES la industria, por lo que no hay desplegable en la industria), luego dos campos: nombre y una frase sobre el negocio. Un agente de trabajo en menos de un minuto. - /settings/ai/sagents/[id] de ancho completo, documento de desplazamiento único con pegajoso encabezados de sección, contenido tapado en 880px para que las entradas de una sola línea no se estiren a través de una pantalla 4K. No 240px nav rail: nueve tramos es un trabajo espía de desplazamiento, no un el trabajo de nav. - Trato-fuera es un paseo de cabeza en lugar de una columna permanentemente reservada. An panel de chat vacío junto a un nuevo agente es espacio desperdiciado que se lee como el El usuario no lo ha rellenado. - La preparación es una lista ordenada y descartable de lo que ayudaría a nunca una fracción. Una fracción le dice a alguien que está fallando; una lista le dice qué hacer a continuación. - Las reglas bloqueadas se bloquean y se desordenan, y tomando una sección a mano Advierte cuando contiene uno (el compilador ahora los vuelve a gastar independientemente). - Dirente afirma claramente que las ediciones sólo afectan las conversaciones NEW, porque el La pronta toma de instantánea en la creación de sesión y los usuarios de lo contrario concluirían su cambio no funcionó. - outboundHabilitado sólo se envía cuando se cambia realmente: el servidor 403s el todo PUT si ese campo está presente sin MANAGE-SALES-AGENT-OUTREACH, incluyendo en cada autosalvamiento rompería el estudio para cualquiera que careciera de ese derecho. También elimina la caja de "comido del sistema AI" duplicada del canal de chat editor. Era un segundo lugar más débil para escribir lo mismo, sin versiones, sin reglas cerradas y sin antecedentes, sea el editor que le hayas pasado. abierto decidió lo que los clientes escucharon. Los indicios existentes siguen resueltos; canales Usando uno ahora recibe un aviso apuntando a los agentes. Copiar no lleva jerga de IA por diseño, y la matriz de la industria inglesa codificada es sustituidos por etiquetas traducidas.
· AIService
Comprador de agente de ventas, versión, puerta de extensión; corrección de la repetición de la herramienta
Config de agente estructurado compila al sistema rápido, congelaciones por publicación versión, y gana la puerta que un agente debe pasar antes de iniciar el contacto. Compilador - AgenteConfig - SalesAgentCompiler: compilación pura y determinista de estructurado Configar en un aviso seculado. Se omiten secciones vacías por lo que una regla de tres agente no compila a un documento que en su mayoría se dirige. - anulación a nivel de sección ("escribe esta parte usted mismo") en lugar de un nivel de documento interruptor de editar cruda: un autor obtiene pleno poder expresivo en una sección mientras que cada otra sección sigue compilando, mantiene sus reglas cerradas y sigue versionando. - Ese mismo mecanismo hace la migración por inidelita - la prosa de un agente preconfig se almacena como anulación de todo el documento y se compila de nuevo sin cambios, por lo que la migración El día es un no-op para los agentes que ya hablan con los clientes. Probado por prueba. - PhraseBank es deliberadamente dos dimensiones, con la buena prosa en el TEMPLATE. Un banco global clave en cada combinación de enum necesita párrafos escritos a mano, degenera en cláusulas apiladas, y abriría cada org con lo mismo sentencia, que destruye lo único que un org está comprando. - Seis plantillas (primero delantero y plomo entrante: son horizontales y cubren cualquier org cuya vertical no esté listada). Cada barco bloqueado regula el cumplimiento de la El modelo nunca puede eliminar, verificado por prueba. Ciclo de vida - autorización - Publicar congelaciones de Config, compiladoPrompt, hash, modelo, proveedor; reversión vuelve a señalar y restaura el borrador para que el estudio nunca pueda mostrar una cosa mientras el agente sirve a otro. - El controlador está aprobado por primera vez. Anteriormente CUALQUIER autenticado miembro de cualquier org podría reescribir lo que ese org dice a sus clientes. Cae de vuelta a MANAGE-AI-SETTINGS para que ningún administrador existente esté bloqueado en el despliegue. - El chat público prefiere el aviso congelado de la versión publicada en vivo formaciónContexto, y sellos ventasAgentId/versionId en la sesión - el agente Allí ya se resolvió y se estaba descartando. - Redacción asistida por IA: una frase en, una conficción revisable. Las reglas cerradas son llevado en código, nunca mostrado al modelo, por lo que una línea de cumplimiento nunca puede ser eliminados por instrucciones-siguiendo. Puerta de extensión (las 14 reglas probadas) - Opt-out supera a todos los demás cheques Y se informa como la razón, porque el La razón registrada contra una negativa es en sí misma la prueba. - SMS sin registro de consentimiento se rechaza: bajo TCPA la carga de la prueba está en el remitente, por lo que la ausencia de un registro es la ausencia de consentimiento. - Se juzga horas tranquilas donde está el CONTACTO, no donde está el negocio. - Los envíos fallidos no gastan el presupuesto de contacto; los envíos suprimidos no lo hacen, o Una cuadra en cascada en bloquear todo después de ella. - La puerta falla CLOSED - una puerta de divulgación que los errores se abren envía mensajes a nadie autorizado, el único fracaso aquí que no se puede deshacer. Arreglos encontrados en el camino - La repetición de la historia de la llamada de la herramienta se rompía: la fila TOOL no persistió contenido y la El turno de uso de la herramienta nunca se persistió, así que turn 2 envió un nulo contenido bloques. Herramientas Habilitante habrían fallado en cada conversación multigiro. - textoComplete no tuvo tiempo de espera (bloqueo .get(), aferrando un hilo en un lento proveedor) y no registró ningún uso, haciendo que cada ayudante llame invisible a la facturación. - La partición del sistema en ajuste de contexto estaba sin collar, por lo que un agente verbóso más una RAG El bloqueo podría abarrotar toda la historia. - costEstimate está ahora poblada en la ruta de sincronización solamente, de fichas de proveedores reales. El estañal se mantiene nulo: fabrica fichas como contenido.longitud()/4 y multiplicando que por un precio real arroja un número en forma de factura que está mal.
· kamo-shared-library
Config en config de agente de ventas estructurado, versión espina pina y estado de divulgación
Sustituye la mancha de un solo entrenamiento-contexto por un agente estructurado y versionable modelo, y añade la columna vertebral por contacto que un agente necesita antes de iniciar contacto en lugar de sólo respuesta. - SalesAgent gana configJson (jsonb-as-String, que coincide WebChatIntegration .designConfig), has with Config, publishedVersionId, audience and outboundEnabled. formaciónContexto se mantiene como la OUTPUT COMPILED por lo que todo consumidor existente sigue trabajando intacto. ha Config es explícito en lugar de inferir de formaciónContexto en blanco, porque una vez que se compila la producción nunca es En blanco y cualquier prueba de en blanco sería inalcanzable. - SalesAgentVersion congela a "configJson", compiladoHash, modelId, proveedorId por publicación. El modelo está fijado junto al prompt: congelación instrucciones mientras que el modelo de rutas automáticas haría del artefacto una media verdad. - AiChatSession/AiUssageRecorde ventasAgentId . salesAgentVersionId. Anteriormente "qué agente manejó esto?" sólo podía ser contestado caminando por los mutables, nula, no FK WebChatIntegration.salesAgentId hop, así reasignando un canal Reatribuyó silenciosamente toda la historia. - AiOrgSettings gains forcedPreamble/forcedFooter como NEW columns nulas más bien que reutilizar defaultSystemPrompt, por lo que la concatenación es un no-op hasta que un administrador llena uno. Reutilizar el campo existente habría cambiado el comportamiento de cada org que ya tenía uno poblado, el día del despliegue. - AgenteContacto Estado - AgenteAutboundTouch: supresión cruzada por contacto, explícitas columnas de exclusión y consiente de opt-out por canal. Opt-out se almacena como columnas reales en lugar de JSON porque "prueba que este número fue suprimido en esa fecha" no debe depender de la extracción de la ruta JSON. Los registros de troncos táctiles REFUSALS, así como envíos - un registro de envíos prueba lo que hizo, un registro de Las decisiones prueban lo que no harías. - Derechos 168-173 dividido ************* desconectado MANAGE-AI-SETTINGS (53), que previamente no había cerrado nada de esto.
· kamo-internal
Paña de Agentes de Venta de AI - asignación de agentes por canal
Construye out /settings/ai?tab=sagents de ventas (era un tallo): orgs create agentes para su industria de ventas, ya sea de una plantilla incorporada o mediante la redacción del contexto de la formación ellos mismos, luego editar/habilitarlos/dirigirlos. Los canales de chat (/configuraciones/característica/chat) pueden ahora cada elegir qué agente conduce que La IA del canal, independientemente - el agente anula el símbolo del sistema crudo.
· SecurityService
Enriquecedor de chat de enrutado y captura de estado de propiedad de los sujetos
chat-routing ahora devuelve el NMLS del oficial asignado, título, foto, teléfono, correo electrónico y si poseen una licencia válida para el estado de la propiedad de la materia, más se afirma en sí mismo y si todavía tenemos que pedirlo. Reutiliza la tarjeta SAFE-Act's Los datos resueltos para que el chat nunca pueda mostrar una identidad inventada. Añade POST /portal/suject-state: cuando la pista todavía no tiene estado de propiedad, el El prestatario puede ponerlo del chat; fluye a través de patchEstimate (y su asignación de la piscina reentrada) como cualquier otro hecho reclamado, que desbloquea la línea de licencia.
· MediaService
Asignar un agente de ventas por canal . reportar disponibilidad de LO
- WebChatIntegration threads CRUD salesAgentId (Nulll despeja la asignación) - lo-presencia ahora devuelve la disponibilidad del miembroStatus junto a en línea, así que el El widget puede mostrar un estado real en lugar de un punto desnudo. Las sondas cruzadas todavía de vuelta sólo en la línea:false.
· AIService
El agente de ventas CRUD, plantilla hipotecaria y chat impulsado por agentes
- AiSalesAgentController (/api/ai/sales-agents): CRUD , org-scoped . GET /templates - SalesAgentTemplateRegistry: plantillas de arranque incorporadas, comenzando con un asistente hipoteca-presa (consciente de cumplimiento: sin cotizaciones de tipos vinculantes, no Promesas de aprobación, aferramiento al oficial de préstamos con licencia, pide estado sujeto) - PublicAiChatService: la formación asignada de SalesAgentContext se convierte en la parte superior nivel de la cascada rápida (agente --comunicación de integración - org - genérico)

Tu universo está esperando.
Comience gratis en minutos y agregue productos cuando esté listo, sin migración ni nuevos inicios de sesión.
Gratis para siempre: no se requiere tarjeta de crédito