> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ugps.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Runtime y tracing

> Modelos, prompts, LangSmith y operacion local de la capa IA

## Runtime de IA por tenant

`AiRuntime` entrega, por sesion de tenant, el modelo de chat, los embeddings, las trazas y el
costo. Toma las tres credenciales del tenant desde Ajustes → Credenciales (`minimax`,
`langsmith` y `voyage`); no hay respaldo en variables de entorno. Si falta, esta desactivada o
incompleta cualquiera de las tres, la sesion lanza `AiCredentialsMissingError` y la API responde
`409 AI_CREDENTIALS_MISSING` con el proveedor y el problema.

Archivos fuente:

* `apps/api-nestjs/src/shared/application/ports/ai-runtime.port.ts`
* `apps/api-nestjs/src/shared/infrastructure/services/ai/runtime/tenant-ai-runtime.service.ts`
* `apps/api-nestjs/src/shared/infrastructure/services/ai/runtime/ai-runtime.constants.ts`

Proveedor, modelos y endpoints son constantes de codigo: MiniMax-M3 para chat y Voyage
`voyage-4` (1024 dimensiones) para embeddings. Cada perfil solo ajusta sus parametros:

| Perfil | Uso principal | Temperatura |
| - | - | - |
| `message_drafting` | redaccion de borradores (Bandeja y registros) | 0.2 |
| `message_verification` | revisor del borrador, por function calling | 0 |
| `draft_judging` | juez de borradores ya entregados | 0 |
| `teams_router` | clasificacion de mensaje en Teams (`maxTokens: 50`) | 0 |
| `teams_sales_agent` | agente comercial de Teams | 0 |
| `support_agent` | soporte interno y soporte asistido | 0 |
| `prospect_enrichment` | enrichment comercial | 0 |
| `cold_outbound_email` | generacion de outreach | 0.2 |
| `text_generation` | cotizaciones, outreach, publicaciones y lead research | 0.5 |
| `email_classification` | clasificacion de correos entrantes | 0.1 |
| `changelog_summary` | resumen del changelog | 0.3 |

Redaccion y revision piden el modelo con `disableReasoning`: MiniMax corre sin razonamiento en
esas etapas.

## Prompt loading

`PromptLoaderService` lee los prompts del Hub de LangSmith del tenant, con la misma credencial
`langsmith` de Ajustes → Credenciales:

1. cache por schema de tenant y clave durante 60 segundos
2. Hub del tenant con el tag `prod` (salvo que la clave traiga otro tag)
3. respaldo registrado en codigo

Archivo fuente:

* `apps/api-nestjs/src/shared/infrastructure/services/prompt-loader.service.ts`

Mover el tag `prod` en el Hub rige sin redesplegar. Un tenant nunca lee el prompt que otro
guardo con el mismo nombre. Si el prompt no existe o el Hub falla, queda un `error` en el log
(clave y tenant, nunca contenido) y corre el respaldo local.

## Prompt registry

Los modulos registran un respaldo local y luego consultan el texto real al construir la
instancia:

* los providers de `teams-bot` registran `TEAMS_ROUTER_PROMPT_KEY`, `TEAMS_SUPPORT_AGENT_PROMPT_KEY` y `TEAMS_SALES_AGENT_PROMPT_KEY` (`application/prompts/prompt-keys.ts`)
* luego cada factory llama `promptRegistry.getPromptText(...)`

## LangSmith tracing

Las trazas de cada tenant van al proyecto de LangSmith de su credencial (Ajustes →
Credenciales: `apiKey` y `project`). No hay proyecto fijo en codigo ni variables de entorno de
LangSmith; sin la credencial, la IA del tenant no corre.

Archivos fuente:

* `apps/api-nestjs/src/shared/infrastructure/services/ai/runtime/tenant-langsmith-clients.service.ts`
* `apps/api-nestjs/src/modules/plataforma/ai/messaging/application/services/draft-trace-labels.util.ts`
* `apps/api-nestjs/src/modules/plataforma/ai/messaging/application/services/draft-judge.service.ts`

Comportamiento:

* entradas y salidas se ocultan siempre (`hideInputs`/`hideOutputs`): la traza no lleva texto de clientes
* cada traza de redaccion lleva tags (`tenant:`, `target:`, `format:`, `surface:`, `verdict:`) y metadata filtrable: `tenant`, `target_type`, `target_id`, `format`, `surface`, `request_id`, `prompt_version`, `prompt_source`, `prompt_key`, `reviewer_prompt_version` y `reviewer_verdict`
* el texto `internal` no pasa por el revisor y lleva `verdict:not_reviewed`
* el veredicto del revisor se registra como feedback `reviewer_verdict` (1 verificado, 0 revision incompleta, sin puntaje si no hubo revision)
* el juez (`draft_judging`) puntua cada borrador despues de entregarlo, fuera del plazo de la solicitud, y publica solo puntajes como feedback del run del borrador: `judge_score`, `judge_grounded`, `judge_voice`, `judge_format` y `judge_clarity`; un fallo o un JSON invalido deja el borrador sin puntaje
* el uso del borrador suma feedback `operator_edit_similarity` y `draft_regenerated`
* los scripts locales toman el proyecto de `--ai-credentials`; sin LangSmith no trazan

<Note>
  LangSmith cumple dos roles en Raul: fuente de prompts por tenant (Hub con tag `prod`) y
  observabilidad de corridas LLM.
</Note>

## Operacion local

Los scripts de IA (desde `apps/api-nestjs`) leen las credenciales de un archivo JSON con el mismo formato de Ajustes →
Credenciales (`--ai-credentials <archivo.json>`), nunca de variables de entorno:

* `scripts/ai/publish-drafting-prompts.ts` publica los respaldos de redaccion al Hub del tenant y mueve su tag `prod` (sin `--publish` solo lista claves y hashes)
* `scripts/ai/export-inbox-dataset.ts` exporta conversaciones de la Bandeja como dataset seudonimizado (con `--upload` lo sube al LangSmith del tenant)
* `scripts/ai/run-paired-experiment.ts` compara dos versiones de prompt sobre ese dataset con el juez, sin dejar trazas

`scripts/ai/no-ai-environment.spec.ts` falla si vuelve a aparecer una variable de entorno de IA.

## Que revisar si algo falla

1. Credenciales del tenant en Ajustes → Credenciales (`minimax`, `langsmith`, `voyage`).
2. Tag `prod` del prompt en el Hub del tenant y clave correcta en el modulo.
3. Perfil de modelo correcto en el agente.
4. Si el agente recibio el bundle de tools esperado.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.