Saltar al contenido
NiuCore

Documentación

Adjuntar recursos

Darle al turno bibliotecas, archivos, habilidades, conectores y agentes — y saber cuáles podés.

Un turno sin adjuntos usa el conocimiento del modelo y las reglas de la organización. Con adjuntos, además, recibe contexto tuyo: documentos que buscar, instrucciones que seguir, herramientas que usar.

JSON
{
  "content": "Resumí la política de devoluciones y redactá una respuesta al cliente.",
  "permission_mode": "auto",
  "attachments": {
    "workspace_ids": [31],
    "file_ids": [],
    "skill_ids": [147],
    "mcp_server_ids": []
  }
}
CampoQué adjuntaScope adicional
workspace_idsBibliotecas enteras. El modelo busca dentro cuando lo necesita.libraries:read
file_idsArchivos concretos, sin traer su biblioteca entera.libraries:read
skill_idsInstrucciones reutilizables que guían la respuesta. Si citan otros recursos, esos también se suman, dentro del alcance de la credencial (ver).skills:read
mcp_server_idsConectores cuyas herramientas el turno podrá ejecutar.connectors:use
agent_idsAgentes en los que el turno puede delegar tareas (ver).agents:use

Atención

chat:write autoriza conversar, no leer lo que se adjunte. Sin el scope compañero, el turno se rechaza con 403 api_token_scope_not_allowed y data.required_scopes nombra los que faltan. La validación ocurre antes de reservar la idempotencia, así que no te quema la key.

No adivines los ids. GET /chat/catalog devuelve exactamente lo que esta credencial puede usar, ya recortado por los permisos del usuario y por el alcance de la credencial.

curl -sS 'https://api.niucore.com/api/v1/chat/catalog' \
  -H "Authorization: Bearer $NIUCORE_ACCESS_TOKEN" | jq
JSON
{
  "models": [
    { "id": 17, "name": "GPT-4o", "code": "gpt-4o", "type": "COMPLETION" }
  ],
  "permission_modes": ["manual", "auto"],
  "libraries": [{ "id": 31, "name": "Procedimientos de soporte" }],
  "skills": [{ "id": 147, "name": "Redactar respuesta a cliente" }],
  "connectors": [{ "id": 8, "name": "gmail", "display_name": "Gmail" }]
}

Nota

Los bloques son condicionales por scope: sin libraries:read la clave libraries no viene — no viene vacía, no viene. Una lista vacía se leería como «no hay ninguna», y eso sería falso. Programá con catalog.libraries ?? [].

Elegir el modelo

model_id viaja por turno. Sin él se usa el del chat, y sin ese el de la empresa. Los ids válidos son los de catalog.models, que solo trae modelos de tipo COMPLETION: un modelo de embedding nunca aparece ahí, porque mandarlo produciría un turno que falla del otro lado.

Límites

  • Hasta 20 ids por tipo y 50 en total. Pasarse devuelve 422 api_v1_too_many_attachments, con el campo culpable en data.
  • Un id fuera del alcance de la credencial también rechaza el turno, y tampoco consume la idempotencia.
  • Adjuntar mucho no siempre es mejor: cada biblioteca agrega contexto que el modelo tiene que atravesar, y eso se paga en tokens.

Conectores

Adjuntar un mcp_server_id habilita las herramientas de ese conector para el turno — pero solo funcionan las que el usuario ya conectó desde la aplicación. Si el modelo intenta usar una sin autorizar, el turno se detiene con message.action_required de tipo auth_required, y desde la API la única salida es cancelarlo.

Sugerencia

Con conectores conviene permission_mode: "manual": una herramienta de Gmail o Calendar tiene efectos fuera de NiuCore, y aprobarla explícitamente es lo que evita sorpresas. Ver Interacciones.

Agentes

Con agents:use el turno puede delegar: el modelo reparte tareas entre agentes y las coordina. Hay tres formas de usarlo:

  • Sin selección: el turno lleva el catálogo automático de la credencial (el bloque agents de GET /chat/catalog) y el modelo decide si delega. También puede crear agentes temporales para esa solicitud.
  • Con `attachments.agent_ids` (o citas {{agent:N}} en content, que se suman igual): el turno ofrece esos agentes.
  • Con `principal_agent_id`: además, ese agente conduce el turno con sus instrucciones y su persona. Tiene que estar entre los seleccionados.
JSON
{
  "content": "Conciliá agosto y prepará el resumen para el cliente.",
  "permission_mode": "manual",
  "attachments": { "agent_ids": [4, 9], "workspace_ids": [31] },
  "principal_agent_id": 4
}

El agente no amplía la credencial

Cada tarea trabaja con lo que la credencial alcanza, no con lo que cite la definición del agente: sin libraries:read un agente no busca en ninguna biblioteca, sin connectors:use no usa conectores, y una biblioteca fuera de la allowlist no llega ni por nombre. Personas y contextos compartidos no se exponen en la API.

  • Sin agents:use no hay delegación: un agent_ids o una cita {{agent:N}} dan 403 api_token_scope_not_allowed.
  • Las habilidades no suman agentes: un agente citado dentro de una habilidad no se adjunta (ver).
  • Máximo 15 agentes por turno. Los topes de concurrencia y de tareas son los de la empresa, igual que en la aplicación; la API no los relaja.
  • Cada tarea consume niucredits. usage.agent_tokens desglosa ese consumo, que ya está incluido en usage.total_tokens.
  • El progreso llega en message.step y las aprobaciones de los agentes en message.action_required con agent (Eventos). El terminal trae agent_runs; el detalle de cada tarea, en `…/agent-runs`. No hay cancelación por tarea: actions/cancel corta el turno entero.
  • La delegación ocurre dentro del mismo turno y de su tiempo máximo: el stream permite observarla, no la extiende.

Tu propio metadata

metadata es un objeto libre que se guarda con el turno y se devuelve tal cual en la respuesta y en el listado de mensajes. No llega al modelo: es para correlacionar de tu lado. Máximo 2048 bytes serializados.

JSON
{
  "content": "…",
  "metadata": {
    "ticket": "8842",
    "channel": "whatsapp",
    "customer_id": "c-91021"
  }
}

Es la forma recomendada de atar un turno de NiuCore a un registro tuyo: GET /chats/{id}/messages lo devuelve en cada mensaje, así que podés reconstruir la trazabilidad sin mantener una tabla de correspondencias.