chore(i18n): refresh es translations
This commit is contained in:
parent
367ec10a99
commit
c20291d4dc
@ -1,44 +1,43 @@
|
||||
---
|
||||
read_when:
|
||||
- Trabajar en funcionalidades del canal de Microsoft Teams
|
||||
summary: Estado del soporte del bot de Microsoft Teams, capacidades y configuración
|
||||
- Trabajando en las funciones del canal de Microsoft Teams
|
||||
summary: Estado de soporte del bot de Microsoft Teams, capacidades y configuración
|
||||
title: Microsoft Teams
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T12:37:19Z"
|
||||
generated_at: "2026-04-12T00:19:02Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 99fc6e136893ec65dc85d3bc0c0d92134069a2f3b8cb4fcf66c14674399b3eaf
|
||||
source_hash: 3e6841a618fb030e4c2029b3652d45dedd516392e2ae17309ff46b93648ffb79
|
||||
source_path: channels/msteams.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Microsoft Teams
|
||||
|
||||
> "Abandonad toda esperanza quienes entráis aquí."
|
||||
> "Abandonad toda esperanza, quienes entráis aquí."
|
||||
|
||||
Actualizado: 2026-01-21
|
||||
Actualizado: 2026-03-25
|
||||
|
||||
Estado: se admiten texto + archivos adjuntos en MD; el envío de archivos en canales/grupos requiere `sharePointSiteId` + permisos de Graph (consulta [Envío de archivos en chats grupales](#envío-de-archivos-en-chats-grupales)). Las encuestas se envían mediante Adaptive Cards. Las acciones de mensaje exponen `upload-file` explícito para envíos centrados primero en archivos.
|
||||
Estado: se admiten texto + archivos adjuntos en mensajes directos; el envío de archivos en canales/grupos requiere `sharePointSiteId` + permisos de Graph (consulta [Envío de archivos en chats grupales](#sending-files-in-group-chats)). Las encuestas se envían mediante Adaptive Cards. Las acciones de mensaje exponen `upload-file` explícito para envíos centrados primero en archivos.
|
||||
|
||||
## Plugin integrado
|
||||
## Plugin incluido
|
||||
|
||||
Microsoft Teams se incluye como plugin integrado en las versiones actuales de OpenClaw, por lo que no
|
||||
se requiere una instalación aparte en la compilación empaquetada normal.
|
||||
Microsoft Teams se distribuye como un plugin incluido en las versiones actuales de OpenClaw, por lo que no se requiere una instalación independiente en la compilación empaquetada normal.
|
||||
|
||||
Si estás en una compilación anterior o en una instalación personalizada que excluye Teams integrado,
|
||||
Si estás en una compilación anterior o en una instalación personalizada que excluye Teams incluido,
|
||||
instálalo manualmente:
|
||||
|
||||
```bash
|
||||
openclaw plugins install @openclaw/msteams
|
||||
```
|
||||
|
||||
Copia local (al ejecutarse desde un repositorio git):
|
||||
Checkout local (al ejecutarlo desde un repositorio git):
|
||||
|
||||
```bash
|
||||
openclaw plugins install ./path/to/local/msteams-plugin
|
||||
```
|
||||
|
||||
Detalles: [Plugins](/tools/plugin)
|
||||
Detalles: [Plugins](/es/tools/plugin)
|
||||
|
||||
## Configuración rápida (principiante)
|
||||
|
||||
@ -47,10 +46,10 @@ Detalles: [Plugins](/tools/plugin)
|
||||
- Las instalaciones antiguas/personalizadas pueden añadirlo manualmente con los comandos anteriores.
|
||||
2. Crea un **Azure Bot** (App ID + secreto de cliente + tenant ID).
|
||||
3. Configura OpenClaw con esas credenciales.
|
||||
4. Expón `/api/messages` (puerto 3978 de forma predeterminada) mediante una URL pública o túnel.
|
||||
4. Expón `/api/messages` (puerto 3978 de forma predeterminada) mediante una URL pública o un túnel.
|
||||
5. Instala el paquete de la aplicación de Teams e inicia el gateway.
|
||||
|
||||
Configuración mínima:
|
||||
Configuración mínima (secreto de cliente):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -66,13 +65,15 @@ Configuración mínima:
|
||||
}
|
||||
```
|
||||
|
||||
Nota: los chats grupales están bloqueados de forma predeterminada (`channels.msteams.groupPolicy: "allowlist"`). Para permitir respuestas en grupos, establece `channels.msteams.groupAllowFrom` (o usa `groupPolicy: "open"` para permitir a cualquier miembro, con control por mención).
|
||||
Para implementaciones de producción, considera usar [autenticación federada](#federated-authentication-certificate--managed-identity) (certificado o identidad administrada) en lugar de secretos de cliente.
|
||||
|
||||
Nota: los chats grupales están bloqueados de forma predeterminada (`channels.msteams.groupPolicy: "allowlist"`). Para permitir respuestas en grupo, establece `channels.msteams.groupAllowFrom` (o usa `groupPolicy: "open"` para permitir cualquier miembro, con restricción por mención).
|
||||
|
||||
## Objetivos
|
||||
|
||||
- Hablar con OpenClaw mediante MD de Teams, chats grupales o canales.
|
||||
- Hablar con OpenClaw mediante mensajes directos de Teams, chats grupales o canales.
|
||||
- Mantener el enrutamiento determinista: las respuestas siempre vuelven al canal por el que llegaron.
|
||||
- Aplicar un comportamiento de canal seguro de forma predeterminada (menciones obligatorias salvo que se configure lo contrario).
|
||||
- Usar un comportamiento de canal seguro de forma predeterminada (se requieren menciones salvo que se configure lo contrario).
|
||||
|
||||
## Escrituras de configuración
|
||||
|
||||
@ -86,20 +87,20 @@ Desactívalo con:
|
||||
}
|
||||
```
|
||||
|
||||
## Control de acceso (MD + grupos)
|
||||
## Control de acceso (mensajes directos + grupos)
|
||||
|
||||
**Acceso por MD**
|
||||
**Acceso a mensajes directos**
|
||||
|
||||
- Predeterminado: `channels.msteams.dmPolicy = "pairing"`. Los remitentes desconocidos se ignoran hasta que se aprueban.
|
||||
- `channels.msteams.allowFrom` debe usar IDs de objeto AAD estables.
|
||||
- Los UPN/nombres para mostrar son mutables; la coincidencia directa está deshabilitada de forma predeterminada y solo se habilita con `channels.msteams.dangerouslyAllowNameMatching: true`.
|
||||
- Los UPN/nombres para mostrar son mutables; la coincidencia directa está desactivada de forma predeterminada y solo se habilita con `channels.msteams.dangerouslyAllowNameMatching: true`.
|
||||
- El asistente puede resolver nombres a IDs mediante Microsoft Graph cuando las credenciales lo permiten.
|
||||
|
||||
**Acceso por grupo**
|
||||
**Acceso a grupos**
|
||||
|
||||
- Predeterminado: `channels.msteams.groupPolicy = "allowlist"` (bloqueado a menos que añadas `groupAllowFrom`). Usa `channels.defaults.groupPolicy` para anular el valor predeterminado cuando no esté establecido.
|
||||
- Predeterminado: `channels.msteams.groupPolicy = "allowlist"` (bloqueado a menos que añadas `groupAllowFrom`). Usa `channels.defaults.groupPolicy` para sobrescribir el valor predeterminado cuando no esté establecido.
|
||||
- `channels.msteams.groupAllowFrom` controla qué remitentes pueden activar en chats grupales/canales (recurre a `channels.msteams.allowFrom`).
|
||||
- Establece `groupPolicy: "open"` para permitir a cualquier miembro (aun así, con control por mención de forma predeterminada).
|
||||
- Establece `groupPolicy: "open"` para permitir cualquier miembro (aun así, con restricción por mención de forma predeterminada).
|
||||
- Para no permitir **ningún canal**, establece `channels.msteams.groupPolicy: "disabled"`.
|
||||
|
||||
Ejemplo:
|
||||
@ -115,14 +116,14 @@ Ejemplo:
|
||||
}
|
||||
```
|
||||
|
||||
**Teams + lista de permitidos de canales**
|
||||
**Lista de permitidos de Teams + canal**
|
||||
|
||||
- Limita las respuestas en grupos/canales enumerando equipos y canales en `channels.msteams.teams`.
|
||||
- Limita las respuestas de grupo/canal listando equipos y canales en `channels.msteams.teams`.
|
||||
- Las claves deben usar IDs estables de equipo e IDs de conversación de canal.
|
||||
- Cuando `groupPolicy="allowlist"` y hay una lista de permitidos de equipos, solo se aceptan los equipos/canales enumerados (con control por mención).
|
||||
- El asistente de configuración acepta entradas `Team/Channel` y las almacena por ti.
|
||||
- Al iniciarse, OpenClaw resuelve los nombres de equipos/canales y de usuarios de la lista de permitidos a IDs (cuando los permisos de Graph lo permiten)
|
||||
y registra la asignación; los nombres de equipos/canales no resueltos se conservan tal como se escribieron, pero se ignoran para el enrutamiento de forma predeterminada a menos que `channels.msteams.dangerouslyAllowNameMatching: true` esté habilitado.
|
||||
- Cuando `groupPolicy="allowlist"` y hay una lista de permitidos de equipos presente, solo se aceptan los equipos/canales listados (con restricción por mención).
|
||||
- El asistente de configuración acepta entradas `Team/Channel` y las guarda por ti.
|
||||
- Al iniciar, OpenClaw resuelve nombres de equipo/canal y nombres de usuario de la lista de permitidos a IDs (cuando los permisos de Graph lo permiten)
|
||||
y registra la asignación; los nombres de equipo/canal no resueltos se conservan tal como se escribieron, pero se ignoran para el enrutamiento de forma predeterminada a menos que `channels.msteams.dangerouslyAllowNameMatching: true` esté habilitado.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
@ -149,36 +150,36 @@ Ejemplo:
|
||||
- Las versiones empaquetadas actuales de OpenClaw ya lo incluyen.
|
||||
- Las instalaciones antiguas/personalizadas pueden añadirlo manualmente con los comandos anteriores.
|
||||
2. Crea un **Azure Bot** (App ID + secreto + tenant ID).
|
||||
3. Crea un **paquete de aplicación de Teams** que haga referencia al bot e incluya los permisos RSC indicados a continuación.
|
||||
4. Carga/instala la aplicación de Teams en un equipo (o en ámbito personal para MD).
|
||||
3. Crea un **paquete de aplicación de Teams** que haga referencia al bot e incluya los permisos RSC de abajo.
|
||||
4. Carga/instala la aplicación de Teams en un equipo (o en alcance personal para mensajes directos).
|
||||
5. Configura `msteams` en `~/.openclaw/openclaw.json` (o variables de entorno) e inicia el gateway.
|
||||
6. El gateway escucha el tráfico de webhook de Bot Framework en `/api/messages` de forma predeterminada.
|
||||
6. El gateway escucha el tráfico del webhook de Bot Framework en `/api/messages` de forma predeterminada.
|
||||
|
||||
## Configuración de Azure Bot (requisitos previos)
|
||||
|
||||
Antes de configurar OpenClaw, necesitas crear un recurso de Azure Bot.
|
||||
Antes de configurar OpenClaw, necesitas crear un recurso Azure Bot.
|
||||
|
||||
### Paso 1: Crear Azure Bot
|
||||
|
||||
1. Ve a [Crear Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot)
|
||||
2. Completa la pestaña **Básico**:
|
||||
1. Ve a [Create Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot)
|
||||
2. Completa la pestaña **Basics**:
|
||||
|
||||
| Campo | Valor |
|
||||
| ------------------ | -------------------------------------------------------- |
|
||||
| **Identificador del bot** | El nombre de tu bot, p. ej., `openclaw-msteams` (debe ser único) |
|
||||
| **Suscripción** | Selecciona tu suscripción de Azure |
|
||||
| **Grupo de recursos** | Crea uno nuevo o usa uno existente |
|
||||
| **Plan de precios** | **Gratis** para desarrollo/pruebas |
|
||||
| **Tipo de aplicación** | **Single Tenant** (recomendado; consulta la nota abajo) |
|
||||
| **Tipo de creación** | **Create new Microsoft App ID** |
|
||||
| **Bot handle** | El nombre de tu bot, p. ej., `openclaw-msteams` (debe ser único) |
|
||||
| **Subscription** | Selecciona tu suscripción de Azure |
|
||||
| **Resource group** | Crea uno nuevo o usa uno existente |
|
||||
| **Pricing tier** | **Free** para desarrollo/pruebas |
|
||||
| **Type of App** | **Single Tenant** (recomendado: consulta la nota abajo) |
|
||||
| **Creation type** | **Create new Microsoft App ID** |
|
||||
|
||||
> **Aviso de retirada:** La creación de nuevos bots multiinquilino quedó obsoleta después del 2025-07-31. Usa **Single Tenant** para bots nuevos.
|
||||
> **Aviso de retirada:** La creación de nuevos bots multi-tenant quedó obsoleta después del 2025-07-31. Usa **Single Tenant** para bots nuevos.
|
||||
|
||||
3. Haz clic en **Revisar + crear** → **Crear** (espera ~1-2 minutos)
|
||||
3. Haz clic en **Review + create** → **Create** (espera ~1-2 minutos)
|
||||
|
||||
### Paso 2: Obtener credenciales
|
||||
|
||||
1. Ve a tu recurso de Azure Bot → **Configuración**
|
||||
1. Ve a tu recurso Azure Bot → **Configuration**
|
||||
2. Copia **Microsoft App ID** → este es tu `appId`
|
||||
3. Haz clic en **Manage Password** → ve al registro de la aplicación
|
||||
4. En **Certificates & secrets** → **New client secret** → copia el **Value** → este es tu `appPassword`
|
||||
@ -186,26 +187,168 @@ Antes de configurar OpenClaw, necesitas crear un recurso de Azure Bot.
|
||||
|
||||
### Paso 3: Configurar el endpoint de mensajería
|
||||
|
||||
1. En Azure Bot → **Configuración**
|
||||
2. Establece **Messaging endpoint** en la URL de tu webhook:
|
||||
1. En Azure Bot → **Configuration**
|
||||
2. Establece **Messaging endpoint** en tu URL de webhook:
|
||||
- Producción: `https://your-domain.com/api/messages`
|
||||
- Desarrollo local: usa un túnel (consulta [Desarrollo local](#desarrollo-local-túneles) abajo)
|
||||
- Desarrollo local: usa un túnel (consulta [Desarrollo local](#local-development-tunneling) abajo)
|
||||
|
||||
### Paso 4: Habilitar el canal Teams
|
||||
### Paso 4: Habilitar el canal de Teams
|
||||
|
||||
1. En Azure Bot → **Channels**
|
||||
2. Haz clic en **Microsoft Teams** → Configurar → Guardar
|
||||
3. Acepta los términos del servicio
|
||||
2. Haz clic en **Microsoft Teams** → Configure → Save
|
||||
3. Acepta las Condiciones del servicio
|
||||
|
||||
## Autenticación federada (certificado + identidad administrada)
|
||||
|
||||
> Añadido en 2026.3.24
|
||||
|
||||
Para implementaciones de producción, OpenClaw admite **autenticación federada** como alternativa más segura a los secretos de cliente. Hay dos métodos disponibles:
|
||||
|
||||
### Opción A: autenticación basada en certificado
|
||||
|
||||
Usa un certificado PEM registrado con el registro de tu aplicación de Entra ID.
|
||||
|
||||
**Configuración:**
|
||||
|
||||
1. Genera u obtén un certificado (formato PEM con clave privada).
|
||||
2. En Entra ID → App Registration → **Certificates & secrets** → **Certificates** → carga el certificado público.
|
||||
|
||||
**Config:**
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
msteams: {
|
||||
enabled: true,
|
||||
appId: "<APP_ID>",
|
||||
tenantId: "<TENANT_ID>",
|
||||
authType: "federated",
|
||||
certificatePath: "/path/to/cert.pem",
|
||||
webhook: { port: 3978, path: "/api/messages" },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Variables de entorno:**
|
||||
|
||||
- `MSTEAMS_AUTH_TYPE=federated`
|
||||
- `MSTEAMS_CERTIFICATE_PATH=/path/to/cert.pem`
|
||||
|
||||
### Opción B: Azure Managed Identity
|
||||
|
||||
Usa Azure Managed Identity para autenticación sin contraseña. Esto es ideal para implementaciones en infraestructura de Azure (AKS, App Service, máquinas virtuales de Azure) donde hay una identidad administrada disponible.
|
||||
|
||||
**Cómo funciona:**
|
||||
|
||||
1. El pod/VM del bot tiene una identidad administrada (asignada por el sistema o por el usuario).
|
||||
2. Una **credencial de identidad federada** vincula la identidad administrada con el registro de la aplicación de Entra ID.
|
||||
3. En tiempo de ejecución, OpenClaw usa `@azure/identity` para adquirir tokens desde el endpoint Azure IMDS (`169.254.169.254`).
|
||||
4. El token se pasa al SDK de Teams para la autenticación del bot.
|
||||
|
||||
**Requisitos previos:**
|
||||
|
||||
- Infraestructura de Azure con identidad administrada habilitada (identidad de carga de trabajo de AKS, App Service, VM)
|
||||
- Credencial de identidad federada creada en el registro de la aplicación de Entra ID
|
||||
- Acceso de red a IMDS (`169.254.169.254:80`) desde el pod/VM
|
||||
|
||||
**Config (identidad administrada asignada por el sistema):**
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
msteams: {
|
||||
enabled: true,
|
||||
appId: "<APP_ID>",
|
||||
tenantId: "<TENANT_ID>",
|
||||
authType: "federated",
|
||||
useManagedIdentity: true,
|
||||
webhook: { port: 3978, path: "/api/messages" },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Config (identidad administrada asignada por el usuario):**
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
msteams: {
|
||||
enabled: true,
|
||||
appId: "<APP_ID>",
|
||||
tenantId: "<TENANT_ID>",
|
||||
authType: "federated",
|
||||
useManagedIdentity: true,
|
||||
managedIdentityClientId: "<MI_CLIENT_ID>",
|
||||
webhook: { port: 3978, path: "/api/messages" },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Variables de entorno:**
|
||||
|
||||
- `MSTEAMS_AUTH_TYPE=federated`
|
||||
- `MSTEAMS_USE_MANAGED_IDENTITY=true`
|
||||
- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=<client-id>` (solo para identidades asignadas por el usuario)
|
||||
|
||||
### Configuración de identidad de carga de trabajo de AKS
|
||||
|
||||
Para implementaciones de AKS que usan identidad de carga de trabajo:
|
||||
|
||||
1. **Habilita la identidad de carga de trabajo** en tu clúster de AKS.
|
||||
2. **Crea una credencial de identidad federada** en el registro de la aplicación de Entra ID:
|
||||
|
||||
```bash
|
||||
az ad app federated-credential create --id <APP_OBJECT_ID> --parameters '{
|
||||
"name": "my-bot-workload-identity",
|
||||
"issuer": "<AKS_OIDC_ISSUER_URL>",
|
||||
"subject": "system:serviceaccount:<NAMESPACE>:<SERVICE_ACCOUNT>",
|
||||
"audiences": ["api://AzureADTokenExchange"]
|
||||
}'
|
||||
```
|
||||
|
||||
3. **Anota la cuenta de servicio de Kubernetes** con el client ID de la aplicación:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: my-bot-sa
|
||||
annotations:
|
||||
azure.workload.identity/client-id: "<APP_CLIENT_ID>"
|
||||
```
|
||||
|
||||
4. **Etiqueta el pod** para la inyección de identidad de carga de trabajo:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
labels:
|
||||
azure.workload.identity/use: "true"
|
||||
```
|
||||
|
||||
5. **Asegura el acceso de red** a IMDS (`169.254.169.254`) — si usas NetworkPolicy, añade una regla de salida que permita tráfico a `169.254.169.254/32` en el puerto 80.
|
||||
|
||||
### Comparación de tipos de autenticación
|
||||
|
||||
| Método | Configuración | Ventajas | Desventajas |
|
||||
| -------------------- | ---------------------------------------------- | ---------------------------------- | ------------------------------------- |
|
||||
| **Secreto de cliente** | `appPassword` | Configuración simple | Requiere rotación de secretos, menos seguro |
|
||||
| **Certificado** | `authType: "federated"` + `certificatePath` | No hay secreto compartido por la red | Sobrecarga de gestión de certificados |
|
||||
| **Managed Identity** | `authType: "federated"` + `useManagedIdentity` | Sin contraseña, sin secretos que gestionar | Requiere infraestructura de Azure |
|
||||
|
||||
**Comportamiento predeterminado:** Cuando `authType` no está establecido, OpenClaw usa autenticación con secreto de cliente de forma predeterminada. Las configuraciones existentes siguen funcionando sin cambios.
|
||||
|
||||
## Desarrollo local (túneles)
|
||||
|
||||
Teams no puede acceder a `localhost`. Usa un túnel para el desarrollo local:
|
||||
Teams no puede llegar a `localhost`. Usa un túnel para desarrollo local:
|
||||
|
||||
**Opción A: ngrok**
|
||||
|
||||
```bash
|
||||
ngrok http 3978
|
||||
# Copia la URL https, por ejemplo, https://abc123.ngrok.io
|
||||
# Copia la URL https, p. ej., https://abc123.ngrok.io
|
||||
# Establece el endpoint de mensajería en: https://abc123.ngrok.io/api/messages
|
||||
```
|
||||
|
||||
@ -213,35 +356,35 @@ ngrok http 3978
|
||||
|
||||
```bash
|
||||
tailscale funnel 3978
|
||||
# Usa tu URL de Tailscale Funnel como endpoint de mensajería
|
||||
# Usa tu URL de funnel de Tailscale como endpoint de mensajería
|
||||
```
|
||||
|
||||
## Teams Developer Portal (alternativa)
|
||||
|
||||
En lugar de crear manualmente un ZIP de manifiesto, puedes usar el [Teams Developer Portal](https://dev.teams.microsoft.com/apps):
|
||||
En lugar de crear manualmente un ZIP del manifiesto, puedes usar el [Teams Developer Portal](https://dev.teams.microsoft.com/apps):
|
||||
|
||||
1. Haz clic en **+ New app**
|
||||
2. Completa la información básica (nombre, descripción, información del desarrollador)
|
||||
3. Ve a **App features** → **Bot**
|
||||
4. Selecciona **Enter a bot ID manually** y pega tu Azure Bot App ID
|
||||
5. Marca los ámbitos: **Personal**, **Team**, **Group Chat**
|
||||
4. Selecciona **Enter a bot ID manually** y pega el App ID de tu Azure Bot
|
||||
5. Marca los alcances: **Personal**, **Team**, **Group Chat**
|
||||
6. Haz clic en **Distribute** → **Download app package**
|
||||
7. En Teams: **Apps** → **Manage your apps** → **Upload a custom app** → selecciona el ZIP
|
||||
|
||||
Esto suele ser más sencillo que editar manualmente manifiestos JSON.
|
||||
Esto suele ser más fácil que editar manifiestos JSON a mano.
|
||||
|
||||
## Probar el bot
|
||||
|
||||
**Opción A: Azure Web Chat (verifica primero el webhook)**
|
||||
|
||||
1. En Azure Portal → tu recurso de Azure Bot → **Test in Web Chat**
|
||||
2. Envía un mensaje: deberías ver una respuesta
|
||||
3. Esto confirma que tu endpoint de webhook funciona antes de la configuración de Teams
|
||||
1. En Azure Portal → tu recurso Azure Bot → **Test in Web Chat**
|
||||
2. Envía un mensaje; deberías ver una respuesta
|
||||
3. Esto confirma que tu endpoint de webhook funciona antes de configurar Teams
|
||||
|
||||
**Opción B: Teams (después de instalar la aplicación)**
|
||||
|
||||
1. Instala la aplicación de Teams (carga lateral o catálogo de la organización)
|
||||
2. Busca el bot en Teams y envía un MD
|
||||
2. Encuentra el bot en Teams y envíale un mensaje directo
|
||||
3. Revisa los registros del gateway para ver la actividad entrante
|
||||
|
||||
## Configuración (mínima, solo texto)
|
||||
@ -250,21 +393,21 @@ Esto suele ser más sencillo que editar manualmente manifiestos JSON.
|
||||
- Las versiones empaquetadas actuales de OpenClaw ya lo incluyen.
|
||||
- Las instalaciones antiguas/personalizadas pueden añadirlo manualmente:
|
||||
- Desde npm: `openclaw plugins install @openclaw/msteams`
|
||||
- Desde una copia local: `openclaw plugins install ./path/to/local/msteams-plugin`
|
||||
- Desde un checkout local: `openclaw plugins install ./path/to/local/msteams-plugin`
|
||||
|
||||
2. **Registro del bot**
|
||||
- Crea un Azure Bot (consulta arriba) y anota:
|
||||
- App ID
|
||||
- Secreto de cliente (contraseña de la app)
|
||||
- Secreto de cliente (contraseña de la aplicación)
|
||||
- Tenant ID (single-tenant)
|
||||
|
||||
3. **Manifiesto de la aplicación de Teams**
|
||||
- Incluye una entrada `bot` con `botId = <App ID>`.
|
||||
- Ámbitos: `personal`, `team`, `groupChat`.
|
||||
- `supportsFiles: true` (obligatorio para el manejo de archivos en ámbito personal).
|
||||
- Alcances: `personal`, `team`, `groupChat`.
|
||||
- `supportsFiles: true` (obligatorio para el manejo de archivos en el alcance personal).
|
||||
- Añade permisos RSC (abajo).
|
||||
- Crea iconos: `outline.png` (32x32) y `color.png` (192x192).
|
||||
- Comprime los tres archivos juntos: `manifest.json`, `outline.png`, `color.png`.
|
||||
- Comprime juntos los tres archivos: `manifest.json`, `outline.png`, `color.png`.
|
||||
|
||||
4. **Configura OpenClaw**
|
||||
|
||||
@ -286,41 +429,46 @@ Esto suele ser más sencillo que editar manualmente manifiestos JSON.
|
||||
- `MSTEAMS_APP_ID`
|
||||
- `MSTEAMS_APP_PASSWORD`
|
||||
- `MSTEAMS_TENANT_ID`
|
||||
- `MSTEAMS_AUTH_TYPE` (opcional: `"secret"` o `"federated"`)
|
||||
- `MSTEAMS_CERTIFICATE_PATH` (federada + certificado)
|
||||
- `MSTEAMS_CERTIFICATE_THUMBPRINT` (opcional, no requerido para la autenticación)
|
||||
- `MSTEAMS_USE_MANAGED_IDENTITY` (federada + identidad administrada)
|
||||
- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID` (solo MI asignada por el usuario)
|
||||
|
||||
5. **Endpoint del bot**
|
||||
- Establece el Azure Bot Messaging Endpoint en:
|
||||
- `https://<host>:3978/api/messages` (o la ruta/puerto que hayas elegido).
|
||||
- `https://<host>:3978/api/messages` (o la ruta/puerto que elijas).
|
||||
|
||||
6. **Ejecuta el gateway**
|
||||
- El canal Teams se inicia automáticamente cuando el plugin integrado o instalado manualmente está disponible y existe configuración `msteams` con credenciales.
|
||||
- El canal de Teams se inicia automáticamente cuando el plugin incluido o instalado manualmente está disponible y existe configuración `msteams` con credenciales.
|
||||
|
||||
## Acción de información de miembro
|
||||
|
||||
OpenClaw expone una acción `member-info` respaldada por Graph para Microsoft Teams, de modo que los agentes y las automatizaciones pueden resolver detalles de miembros del canal (nombre para mostrar, correo electrónico, rol) directamente desde Microsoft Graph.
|
||||
OpenClaw expone una acción `member-info` respaldada por Graph para Microsoft Teams, de modo que los agentes y las automatizaciones puedan resolver directamente desde Microsoft Graph los detalles de miembros del canal (nombre para mostrar, correo electrónico, rol).
|
||||
|
||||
Requisitos:
|
||||
|
||||
- Permiso RSC `Member.Read.Group` (ya incluido en el manifiesto recomendado)
|
||||
- Permiso RSC `Member.Read.Group` (ya está en el manifiesto recomendado)
|
||||
- Para búsquedas entre equipos: permiso de aplicación Graph `User.Read.All` con consentimiento de administrador
|
||||
|
||||
La acción está controlada por `channels.msteams.actions.memberInfo` (habilitada de forma predeterminada cuando hay credenciales de Graph disponibles).
|
||||
La acción está controlada por `channels.msteams.actions.memberInfo` (predeterminado: habilitada cuando hay credenciales de Graph disponibles).
|
||||
|
||||
## Contexto del historial
|
||||
## Contexto de historial
|
||||
|
||||
- `channels.msteams.historyLimit` controla cuántos mensajes recientes de canal/grupo se encapsulan en el prompt.
|
||||
- Recurre a `messages.groupChat.historyLimit`. Establece `0` para deshabilitarlo (predeterminado 50).
|
||||
- El historial de hilos recuperado se filtra por las listas de permitidos de remitentes (`allowFrom` / `groupAllowFrom`), de modo que la siembra del contexto del hilo solo incluye mensajes de remitentes permitidos.
|
||||
- El contexto de archivos adjuntos citados (`ReplyTo*` derivado del HTML de respuesta de Teams) actualmente se transmite tal como se recibe.
|
||||
- En otras palabras, las listas de permitidos controlan quién puede activar al agente; solo determinadas rutas de contexto suplementario se filtran actualmente.
|
||||
- El historial de MD puede limitarse con `channels.msteams.dmHistoryLimit` (turnos del usuario). Anulaciones por usuario: `channels.msteams.dms["<user_id>"].historyLimit`.
|
||||
- `channels.msteams.historyLimit` controla cuántos mensajes recientes de canal/grupo se incluyen en el prompt.
|
||||
- Recurre a `messages.groupChat.historyLimit`. Establece `0` para desactivarlo (predeterminado: 50).
|
||||
- El historial de hilo recuperado se filtra por listas de remitentes permitidos (`allowFrom` / `groupAllowFrom`), por lo que la inicialización del contexto del hilo solo incluye mensajes de remitentes permitidos.
|
||||
- El contexto de archivos adjuntos citados (`ReplyTo*` derivado del HTML de respuesta de Teams) actualmente se pasa tal como se recibe.
|
||||
- En otras palabras, las listas de permitidos controlan quién puede activar el agente; hoy solo se filtran determinadas rutas de contexto complementario.
|
||||
- El historial de mensajes directos puede limitarse con `channels.msteams.dmHistoryLimit` (turnos del usuario). Sobrescrituras por usuario: `channels.msteams.dms["<user_id>"].historyLimit`.
|
||||
|
||||
## Permisos RSC actuales de Teams (manifiesto)
|
||||
|
||||
Estos son los **permisos resourceSpecific existentes** en nuestro manifiesto de la aplicación de Teams. Solo se aplican dentro del equipo/chat donde la aplicación está instalada.
|
||||
|
||||
**Para canales (ámbito de equipo):**
|
||||
**Para canales (alcance de equipo):**
|
||||
|
||||
- `ChannelMessage.Read.Group` (Application) - recibir todos los mensajes del canal sin @mention
|
||||
- `ChannelMessage.Read.Group` (Application) - recibir todo el contenido de texto de los mensajes de canal sin @mention
|
||||
- `ChannelMessage.Send.Group` (Application)
|
||||
- `Member.Read.Group` (Application)
|
||||
- `Owner.Read.Group` (Application)
|
||||
@ -332,9 +480,9 @@ Estos son los **permisos resourceSpecific existentes** en nuestro manifiesto de
|
||||
|
||||
- `ChatMessage.Read.Chat` (Application) - recibir todos los mensajes del chat grupal sin @mention
|
||||
|
||||
## Ejemplo de manifiesto de Teams (redactado)
|
||||
## Ejemplo de manifiesto de Teams (con datos ocultos)
|
||||
|
||||
Ejemplo mínimo y válido con los campos obligatorios. Sustituye los IDs y las URL.
|
||||
Ejemplo mínimo y válido con los campos requeridos. Sustituye los ID y las URL.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -382,12 +530,12 @@ Ejemplo mínimo y válido con los campos obligatorios. Sustituye los IDs y las U
|
||||
}
|
||||
```
|
||||
|
||||
### Advertencias del manifiesto (campos imprescindibles)
|
||||
### Advertencias sobre el manifiesto (campos obligatorios)
|
||||
|
||||
- `bots[].botId` **debe** coincidir con el Azure Bot App ID.
|
||||
- `webApplicationInfo.id` **debe** coincidir con el Azure Bot App ID.
|
||||
- `bots[].scopes` debe incluir las superficies que planeas usar (`personal`, `team`, `groupChat`).
|
||||
- `bots[].supportsFiles: true` es obligatorio para el manejo de archivos en ámbito personal.
|
||||
- `bots[].supportsFiles: true` es obligatorio para el manejo de archivos en el alcance personal.
|
||||
- `authorization.permissions.resourceSpecific` debe incluir lectura/envío de canal si quieres tráfico de canal.
|
||||
|
||||
### Actualizar una aplicación existente
|
||||
@ -397,27 +545,27 @@ Para actualizar una aplicación de Teams ya instalada (por ejemplo, para añadir
|
||||
1. Actualiza tu `manifest.json` con la nueva configuración
|
||||
2. **Incrementa el campo `version`** (por ejemplo, `1.0.0` → `1.1.0`)
|
||||
3. **Vuelve a comprimir** el manifiesto con los iconos (`manifest.json`, `outline.png`, `color.png`)
|
||||
4. Carga el nuevo ZIP:
|
||||
4. Carga el nuevo zip:
|
||||
- **Opción A (Teams Admin Center):** Teams Admin Center → Teams apps → Manage apps → busca tu aplicación → Upload new version
|
||||
- **Opción B (carga lateral):** En Teams → Apps → Manage your apps → Upload a custom app
|
||||
5. **Para canales de equipo:** reinstala la aplicación en cada equipo para que los nuevos permisos surtan efecto
|
||||
6. **Cierra Teams por completo y vuelve a iniciarlo** (no basta con cerrar la ventana) para borrar los metadatos de aplicación en caché
|
||||
6. **Cierra completamente y vuelve a abrir Teams** (no solo cierres la ventana) para borrar los metadatos en caché de la aplicación
|
||||
|
||||
## Capacidades: solo RSC frente a Graph
|
||||
|
||||
### Con **solo Teams RSC** (aplicación instalada, sin permisos de Graph API)
|
||||
### Con **solo Teams RSC** (aplicación instalada, sin permisos de la API de Graph)
|
||||
|
||||
Funciona:
|
||||
|
||||
- Leer contenido de **texto** de mensajes de canal.
|
||||
- Enviar contenido de **texto** de mensajes de canal.
|
||||
- Recibir archivos adjuntos de **archivos en chats personales (MD)**.
|
||||
- Leer el contenido de **texto** de mensajes de canal.
|
||||
- Enviar contenido de **texto** en mensajes de canal.
|
||||
- Recibir archivos adjuntos en **mensajes directos**.
|
||||
|
||||
NO funciona:
|
||||
|
||||
- Contenido de **imágenes o archivos** de canal/grupo (la carga útil solo incluye un stub HTML).
|
||||
- Contenido de **imágenes o archivos** en canales/grupos (la carga útil solo incluye un stub HTML).
|
||||
- Descargar archivos adjuntos almacenados en SharePoint/OneDrive.
|
||||
- Leer el historial de mensajes (más allá del evento del webhook en vivo).
|
||||
- Leer el historial de mensajes (más allá del evento en vivo del webhook).
|
||||
|
||||
### Con **Teams RSC + permisos de aplicación de Microsoft Graph**
|
||||
|
||||
@ -427,41 +575,41 @@ Añade:
|
||||
- Descarga de archivos adjuntos almacenados en SharePoint/OneDrive.
|
||||
- Lectura del historial de mensajes de canal/chat mediante Graph.
|
||||
|
||||
### RSC frente a Graph API
|
||||
### RSC frente a la API de Graph
|
||||
|
||||
| Capacidad | Permisos RSC | Graph API |
|
||||
| ---------------------- | -------------------- | ----------------------------------- |
|
||||
| **Mensajes en tiempo real** | Sí (mediante webhook) | No (solo sondeo) |
|
||||
| **Mensajes históricos** | No | Sí (puede consultar historial) |
|
||||
| **Complejidad de configuración** | Solo manifiesto de la aplicación | Requiere consentimiento de administrador + flujo de tokens |
|
||||
| **Funciona sin conexión** | No (debe estar en ejecución) | Sí (puede consultar en cualquier momento) |
|
||||
| Capacidad | Permisos RSC | API de Graph |
|
||||
| ----------------------- | ------------------- | ------------------------------------ |
|
||||
| **Mensajes en tiempo real** | Sí (mediante webhook) | No (solo sondeo) |
|
||||
| **Mensajes históricos** | No | Sí (puede consultar el historial) |
|
||||
| **Complejidad de configuración** | Solo manifiesto de la aplicación | Requiere consentimiento de administrador + flujo de tokens |
|
||||
| **Funciona sin conexión** | No (debe estar ejecutándose) | Sí (puede consultar en cualquier momento) |
|
||||
|
||||
**En resumen:** RSC es para escucha en tiempo real; Graph API es para acceso histórico. Para ponerse al día con mensajes perdidos mientras estabas desconectado, necesitas Graph API con `ChannelMessage.Read.All` (requiere consentimiento de administrador).
|
||||
**En resumen:** RSC sirve para escucha en tiempo real; la API de Graph es para acceso histórico. Para ponerse al día con mensajes perdidos mientras estabas desconectado, necesitas la API de Graph con `ChannelMessage.Read.All` (requiere consentimiento de administrador).
|
||||
|
||||
## Medios + historial con Graph habilitado (obligatorio para canales)
|
||||
## Medios + historial habilitados con Graph (obligatorio para canales)
|
||||
|
||||
Si necesitas imágenes/archivos en **canales** o quieres obtener **historial de mensajes**, debes habilitar permisos de Microsoft Graph y conceder consentimiento de administrador.
|
||||
Si necesitas imágenes/archivos en **canales** o quieres obtener el **historial de mensajes**, debes habilitar permisos de Microsoft Graph y conceder consentimiento de administrador.
|
||||
|
||||
1. En **App Registration** de Entra ID (Azure AD), añade permisos de **Application** de Microsoft Graph:
|
||||
- `ChannelMessage.Read.All` (archivos adjuntos e historial de canal)
|
||||
- `Chat.Read.All` o `ChatMessage.Read.All` (chats grupales)
|
||||
2. **Concede consentimiento de administrador** para el tenant.
|
||||
3. Incrementa la **versión del manifiesto** de la aplicación de Teams, vuelve a cargarlo y **reinstala la aplicación en Teams**.
|
||||
4. **Cierra Teams por completo y vuelve a iniciarlo** para borrar los metadatos de aplicación en caché.
|
||||
4. **Cierra completamente y vuelve a abrir Teams** para borrar los metadatos en caché de la aplicación.
|
||||
|
||||
**Permiso adicional para menciones de usuario:** Las menciones @user funcionan de inmediato para usuarios que están en la conversación. Sin embargo, si quieres buscar y mencionar dinámicamente a usuarios que **no están en la conversación actual**, añade el permiso `User.Read.All` (Application) y concede consentimiento de administrador.
|
||||
**Permiso adicional para menciones de usuario:** Las @mentions de usuario funcionan de inmediato para usuarios que están en la conversación. Sin embargo, si quieres buscar y mencionar dinámicamente usuarios que **no están en la conversación actual**, añade el permiso de aplicación `User.Read.All` y concede consentimiento de administrador.
|
||||
|
||||
## Limitaciones conocidas
|
||||
|
||||
### Tiempos de espera del webhook
|
||||
|
||||
Teams entrega mensajes mediante webhook HTTP. Si el procesamiento tarda demasiado (por ejemplo, respuestas lentas del LLM), puedes ver:
|
||||
Teams entrega los mensajes mediante webhook HTTP. Si el procesamiento tarda demasiado (por ejemplo, respuestas lentas del LLM), puedes ver:
|
||||
|
||||
- Tiempos de espera del gateway
|
||||
- Teams reintentando el mensaje (provocando duplicados)
|
||||
- Teams reintentando el mensaje (causando duplicados)
|
||||
- Respuestas descartadas
|
||||
|
||||
OpenClaw gestiona esto devolviendo rápidamente y enviando respuestas de forma proactiva, pero las respuestas muy lentas aún pueden causar problemas.
|
||||
OpenClaw maneja esto devolviendo rápido y enviando respuestas de forma proactiva, pero las respuestas muy lentas pueden seguir causando problemas.
|
||||
|
||||
### Formato
|
||||
|
||||
@ -469,41 +617,46 @@ El markdown de Teams es más limitado que el de Slack o Discord:
|
||||
|
||||
- El formato básico funciona: **negrita**, _cursiva_, `code`, enlaces
|
||||
- El markdown complejo (tablas, listas anidadas) puede no renderizarse correctamente
|
||||
- Adaptive Cards son compatibles para encuestas y envíos arbitrarios de tarjetas (consulta abajo)
|
||||
- Se admiten Adaptive Cards para encuestas y envíos arbitrarios de tarjetas (consulta abajo)
|
||||
|
||||
## Configuración
|
||||
|
||||
Ajustes clave (consulta `/gateway/configuration` para patrones de canal compartidos):
|
||||
Ajustes clave (consulta `/gateway/configuration` para patrones compartidos de canales):
|
||||
|
||||
- `channels.msteams.enabled`: habilitar/deshabilitar el canal.
|
||||
- `channels.msteams.enabled`: habilita/deshabilita el canal.
|
||||
- `channels.msteams.appId`, `channels.msteams.appPassword`, `channels.msteams.tenantId`: credenciales del bot.
|
||||
- `channels.msteams.webhook.port` (predeterminado `3978`)
|
||||
- `channels.msteams.webhook.path` (predeterminado `/api/messages`)
|
||||
- `channels.msteams.webhook.port` (predeterminado: `3978`)
|
||||
- `channels.msteams.webhook.path` (predeterminado: `/api/messages`)
|
||||
- `channels.msteams.dmPolicy`: `pairing | allowlist | open | disabled` (predeterminado: pairing)
|
||||
- `channels.msteams.allowFrom`: lista de permitidos de MD (se recomiendan IDs de objeto AAD). El asistente resuelve nombres a IDs durante la configuración cuando el acceso a Graph está disponible.
|
||||
- `channels.msteams.dangerouslyAllowNameMatching`: interruptor de emergencia para volver a habilitar la coincidencia mutable de UPN/nombre para mostrar y el enrutamiento directo por nombre de equipo/canal.
|
||||
- `channels.msteams.textChunkLimit`: tamaño del fragmento de texto saliente.
|
||||
- `channels.msteams.chunkMode`: `length` (predeterminado) o `newline` para dividir en líneas en blanco (límites de párrafo) antes de fragmentar por longitud.
|
||||
- `channels.msteams.mediaAllowHosts`: lista de permitidos de hosts para archivos adjuntos entrantes (predeterminada para dominios de Microsoft/Teams).
|
||||
- `channels.msteams.mediaAuthAllowHosts`: lista de permitidos para adjuntar encabezados Authorization en reintentos de medios (predeterminada para hosts de Graph + Bot Framework).
|
||||
- `channels.msteams.requireMention`: exigir @mention en canales/grupos (predeterminado true).
|
||||
- `channels.msteams.replyStyle`: `thread | top-level` (consulta [Estilo de respuesta](#estilo-de-respuesta-hilos-frente-a-publicaciones)).
|
||||
- `channels.msteams.teams.<teamId>.replyStyle`: anulación por equipo.
|
||||
- `channels.msteams.teams.<teamId>.requireMention`: anulación por equipo.
|
||||
- `channels.msteams.teams.<teamId>.tools`: anulaciones predeterminadas de política de herramientas por equipo (`allow`/`deny`/`alsoAllow`) usadas cuando falta una anulación de canal.
|
||||
- `channels.msteams.teams.<teamId>.toolsBySender`: anulaciones predeterminadas de política de herramientas por equipo y remitente (`"*"` comodín admitido).
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle`: anulación por canal.
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention`: anulación por canal.
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.tools`: anulaciones de política de herramientas por canal (`allow`/`deny`/`alsoAllow`).
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender`: anulaciones de política de herramientas por canal y remitente (`"*"` comodín admitido).
|
||||
- `channels.msteams.allowFrom`: lista de permitidos para mensajes directos (se recomiendan IDs de objeto AAD). El asistente resuelve nombres a IDs durante la configuración cuando hay acceso a Graph disponible.
|
||||
- `channels.msteams.dangerouslyAllowNameMatching`: interruptor de emergencia para volver a habilitar la coincidencia de UPN/nombre para mostrar mutable y el enrutamiento directo por nombre de equipo/canal.
|
||||
- `channels.msteams.textChunkLimit`: tamaño de fragmentación del texto saliente.
|
||||
- `channels.msteams.chunkMode`: `length` (predeterminado) o `newline` para dividir por líneas en blanco (límites de párrafo) antes de fragmentar por longitud.
|
||||
- `channels.msteams.mediaAllowHosts`: lista de permitidos para hosts de archivos adjuntos entrantes (predeterminado: dominios de Microsoft/Teams).
|
||||
- `channels.msteams.mediaAuthAllowHosts`: lista de permitidos para adjuntar encabezados Authorization en reintentos de medios (predeterminado: hosts de Graph + Bot Framework).
|
||||
- `channels.msteams.requireMention`: requiere @mention en canales/grupos (predeterminado: true).
|
||||
- `channels.msteams.replyStyle`: `thread | top-level` (consulta [Estilo de respuesta](#reply-style-threads-vs-posts)).
|
||||
- `channels.msteams.teams.<teamId>.replyStyle`: sobrescritura por equipo.
|
||||
- `channels.msteams.teams.<teamId>.requireMention`: sobrescritura por equipo.
|
||||
- `channels.msteams.teams.<teamId>.tools`: sobrescrituras predeterminadas de la política de herramientas por equipo (`allow`/`deny`/`alsoAllow`) usadas cuando falta una sobrescritura de canal.
|
||||
- `channels.msteams.teams.<teamId>.toolsBySender`: sobrescrituras predeterminadas de la política de herramientas por equipo y por remitente (se admite el comodín `"*"`).
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle`: sobrescritura por canal.
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention`: sobrescritura por canal.
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.tools`: sobrescrituras de la política de herramientas por canal (`allow`/`deny`/`alsoAllow`).
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender`: sobrescrituras de la política de herramientas por canal y por remitente (se admite el comodín `"*"`).
|
||||
- Las claves `toolsBySender` deben usar prefijos explícitos:
|
||||
`id:`, `e164:`, `username:`, `name:` (las claves heredadas sin prefijo siguen asignándose solo a `id:`).
|
||||
- `channels.msteams.actions.memberInfo`: habilitar o deshabilitar la acción de información de miembro respaldada por Graph (habilitada de forma predeterminada cuando hay credenciales de Graph disponibles).
|
||||
- `channels.msteams.sharePointSiteId`: ID del sitio de SharePoint para cargas de archivos en chats grupales/canales (consulta [Envío de archivos en chats grupales](#envío-de-archivos-en-chats-grupales)).
|
||||
- `channels.msteams.actions.memberInfo`: habilita o deshabilita la acción de información de miembro respaldada por Graph (predeterminado: habilitada cuando hay credenciales de Graph disponibles).
|
||||
- `channels.msteams.authType`: tipo de autenticación — `"secret"` (predeterminado) o `"federated"`.
|
||||
- `channels.msteams.certificatePath`: ruta al archivo de certificado PEM (federada + autenticación por certificado).
|
||||
- `channels.msteams.certificateThumbprint`: huella digital del certificado (opcional, no requerida para la autenticación).
|
||||
- `channels.msteams.useManagedIdentity`: habilita autenticación con identidad administrada (modo federado).
|
||||
- `channels.msteams.managedIdentityClientId`: client ID para identidad administrada asignada por el usuario.
|
||||
- `channels.msteams.sharePointSiteId`: ID del sitio de SharePoint para cargas de archivos en chats grupales/canales (consulta [Envío de archivos en chats grupales](#sending-files-in-group-chats)).
|
||||
|
||||
## Enrutamiento y sesiones
|
||||
|
||||
- Las claves de sesión siguen el formato estándar de agente (consulta [/concepts/session](/concepts/session)):
|
||||
- Las claves de sesión siguen el formato estándar de agente (consulta [/concepts/session](/es/concepts/session)):
|
||||
- Los mensajes directos comparten la sesión principal (`agent:<agentId>:<mainKey>`).
|
||||
- Los mensajes de canal/grupo usan el ID de conversación:
|
||||
- `agent:<agentId>:msteams:channel:<conversationId>`
|
||||
@ -513,15 +666,15 @@ Ajustes clave (consulta `/gateway/configuration` para patrones de canal comparti
|
||||
|
||||
Teams introdujo recientemente dos estilos de interfaz de canal sobre el mismo modelo de datos subyacente:
|
||||
|
||||
| Estilo | Descripción | `replyStyle` recomendado |
|
||||
| ------------------------ | --------------------------------------------------------- | ------------------------ |
|
||||
| **Posts** (clásico) | Los mensajes aparecen como tarjetas con respuestas en hilo debajo | `thread` (predeterminado) |
|
||||
| **Threads** (tipo Slack) | Los mensajes fluyen linealmente, más parecido a Slack | `top-level` |
|
||||
| Estilo | Descripción | `replyStyle` recomendado |
|
||||
| ----------------------- | -------------------------------------------------------- | ------------------------ |
|
||||
| **Posts** (clásico) | Los mensajes aparecen como tarjetas con respuestas en hilo debajo | `thread` (predeterminado) |
|
||||
| **Threads** (tipo Slack) | Los mensajes fluyen linealmente, más parecido a Slack | `top-level` |
|
||||
|
||||
**El problema:** La API de Teams no expone qué estilo de interfaz usa un canal. Si usas el `replyStyle` incorrecto:
|
||||
|
||||
- `thread` en un canal con estilo Threads → las respuestas aparecen anidadas de forma extraña
|
||||
- `top-level` en un canal con estilo Posts → las respuestas aparecen como publicaciones separadas de nivel superior en lugar de en el hilo
|
||||
- `top-level` en un canal con estilo Posts → las respuestas aparecen como publicaciones independientes de nivel superior en lugar de dentro del hilo
|
||||
|
||||
**Solución:** Configura `replyStyle` por canal según cómo esté configurado el canal:
|
||||
|
||||
@ -548,31 +701,31 @@ Teams introdujo recientemente dos estilos de interfaz de canal sobre el mismo mo
|
||||
|
||||
**Limitaciones actuales:**
|
||||
|
||||
- **MD:** Las imágenes y los archivos adjuntos funcionan mediante las API de archivos del bot de Teams.
|
||||
- **Canales/grupos:** Los archivos adjuntos residen en el almacenamiento de M365 (SharePoint/OneDrive). La carga útil del webhook solo incluye un stub HTML, no los bytes reales del archivo. **Se requieren permisos de Graph API** para descargar archivos adjuntos de canal.
|
||||
- Para envíos explícitos centrados primero en archivos, usa `action=upload-file` con `media` / `filePath` / `path`; el `message` opcional se convierte en el texto/comentario adjunto, y `filename` sustituye el nombre cargado.
|
||||
- **Mensajes directos:** las imágenes y los archivos adjuntos funcionan mediante las API de archivos del bot de Teams.
|
||||
- **Canales/grupos:** los archivos adjuntos viven en el almacenamiento de M365 (SharePoint/OneDrive). La carga útil del webhook solo incluye un stub HTML, no los bytes reales del archivo. **Se requieren permisos de la API de Graph** para descargar archivos adjuntos de canal.
|
||||
- Para envíos explícitos centrados primero en archivos, usa `action=upload-file` con `media` / `filePath` / `path`; el `message` opcional pasa a ser el texto/comentario adjunto, y `filename` sobrescribe el nombre cargado.
|
||||
|
||||
Sin permisos de Graph, los mensajes de canal con imágenes se recibirán solo como texto (el contenido de la imagen no es accesible para el bot).
|
||||
De forma predeterminada, OpenClaw solo descarga medios desde nombres de host de Microsoft/Teams. Anúlalo con `channels.msteams.mediaAllowHosts` (usa `["*"]` para permitir cualquier host).
|
||||
Los encabezados Authorization solo se adjuntan para los hosts de `channels.msteams.mediaAuthAllowHosts` (predeterminados para hosts de Graph + Bot Framework). Mantén esta lista estricta (evita sufijos multiinquilino).
|
||||
De forma predeterminada, OpenClaw solo descarga medios desde nombres de host de Microsoft/Teams. Sobrescribe esto con `channels.msteams.mediaAllowHosts` (usa `["*"]` para permitir cualquier host).
|
||||
Los encabezados Authorization solo se adjuntan para hosts en `channels.msteams.mediaAuthAllowHosts` (predeterminado: hosts de Graph + Bot Framework). Mantén esta lista estricta (evita sufijos multi-tenant).
|
||||
|
||||
## Envío de archivos en chats grupales
|
||||
|
||||
Los bots pueden enviar archivos en MD usando el flujo FileConsentCard (integrado). Sin embargo, **enviar archivos en chats grupales/canales** requiere configuración adicional:
|
||||
Los bots pueden enviar archivos en mensajes directos mediante el flujo FileConsentCard (integrado). Sin embargo, **enviar archivos en chats grupales/canales** requiere configuración adicional:
|
||||
|
||||
| Contexto | Cómo se envían los archivos | Configuración necesaria |
|
||||
| ------------------------ | -------------------------------------------- | ----------------------------------------------- |
|
||||
| **MD** | FileConsentCard → el usuario acepta → el bot carga | Funciona sin configuración adicional |
|
||||
| **Chats grupales/canales** | Cargar en SharePoint → compartir enlace | Requiere `sharePointSiteId` + permisos de Graph |
|
||||
| **Imágenes (cualquier contexto)** | Inline codificado en Base64 | Funciona sin configuración adicional |
|
||||
| Contexto | Cómo se envían los archivos | Configuración necesaria |
|
||||
| ------------------------ | ----------------------------------------- | ------------------------------------------------ |
|
||||
| **Mensajes directos** | FileConsentCard → el usuario acepta → el bot carga | Funciona de inmediato |
|
||||
| **Chats grupales/canales** | Cargar en SharePoint → compartir enlace | Requiere `sharePointSiteId` + permisos de Graph |
|
||||
| **Imágenes (cualquier contexto)** | Inline codificado en Base64 | Funciona de inmediato |
|
||||
|
||||
### Por qué los chats grupales necesitan SharePoint
|
||||
|
||||
Los bots no tienen una unidad personal de OneDrive (el endpoint `/me/drive` de Graph API no funciona para identidades de aplicación). Para enviar archivos en chats grupales/canales, el bot carga el archivo en un **sitio de SharePoint** y crea un enlace para compartir.
|
||||
Los bots no tienen una unidad personal de OneDrive (el endpoint de la API de Graph `/me/drive` no funciona para identidades de aplicación). Para enviar archivos en chats grupales/canales, el bot carga el archivo en un **sitio de SharePoint** y crea un enlace para compartir.
|
||||
|
||||
### Configuración
|
||||
|
||||
1. **Añade permisos de Graph API** en Entra ID (Azure AD) → App Registration:
|
||||
1. **Añade permisos de la API de Graph** en Entra ID (Azure AD) → App Registration:
|
||||
- `Sites.ReadWrite.All` (Application) - cargar archivos en SharePoint
|
||||
- `Chat.Read.All` (Application) - opcional, habilita enlaces para compartir por usuario
|
||||
|
||||
@ -607,34 +760,34 @@ Los bots no tienen una unidad personal de OneDrive (el endpoint `/me/drive` de G
|
||||
|
||||
### Comportamiento de uso compartido
|
||||
|
||||
| Permiso | Comportamiento de uso compartido |
|
||||
| --------------------------------------- | --------------------------------------------------------- |
|
||||
| `Sites.ReadWrite.All` solo | Enlace de uso compartido para toda la organización (cualquiera en la organización puede acceder) |
|
||||
| `Sites.ReadWrite.All` + `Chat.Read.All` | Enlace de uso compartido por usuario (solo los miembros del chat pueden acceder) |
|
||||
| Permiso | Comportamiento de uso compartido |
|
||||
| -------------------------------------- | -------------------------------------------------------- |
|
||||
| `Sites.ReadWrite.All` solo | Enlace para compartir en toda la organización (cualquiera en la organización puede acceder) |
|
||||
| `Sites.ReadWrite.All` + `Chat.Read.All` | Enlace para compartir por usuario (solo los miembros del chat pueden acceder) |
|
||||
|
||||
El uso compartido por usuario es más seguro, ya que solo los participantes del chat pueden acceder al archivo. Si falta el permiso `Chat.Read.All`, el bot recurre al uso compartido para toda la organización.
|
||||
|
||||
### Comportamiento de respaldo
|
||||
|
||||
| Escenario | Resultado |
|
||||
| ------------------------------------------------- | -------------------------------------------------- |
|
||||
| Chat grupal + archivo + `sharePointSiteId` configurado | Cargar en SharePoint, enviar enlace para compartir |
|
||||
| Chat grupal + archivo + sin `sharePointSiteId` | Intentar carga en OneDrive (puede fallar), enviar solo texto |
|
||||
| Chat personal + archivo | Flujo FileConsentCard (funciona sin SharePoint) |
|
||||
| Cualquier contexto + imagen | Inline codificado en Base64 (funciona sin SharePoint) |
|
||||
| Escenario | Resultado |
|
||||
| ------------------------------------------------- | ------------------------------------------------- |
|
||||
| Chat grupal + archivo + `sharePointSiteId` configurado | Carga en SharePoint, envía enlace para compartir |
|
||||
| Chat grupal + archivo + sin `sharePointSiteId` | Intenta cargar en OneDrive (puede fallar), envía solo texto |
|
||||
| Chat personal + archivo | Flujo FileConsentCard (funciona sin SharePoint) |
|
||||
| Cualquier contexto + imagen | Inline codificado en Base64 (funciona sin SharePoint) |
|
||||
|
||||
### Ubicación de almacenamiento de archivos
|
||||
### Ubicación donde se almacenan los archivos
|
||||
|
||||
Los archivos cargados se almacenan en una carpeta `/OpenClawShared/` dentro de la biblioteca de documentos predeterminada del sitio de SharePoint configurado.
|
||||
|
||||
## Encuestas (Adaptive Cards)
|
||||
|
||||
OpenClaw envía encuestas de Teams como Adaptive Cards (no existe una API nativa de encuestas de Teams).
|
||||
OpenClaw envía encuestas de Teams como Adaptive Cards (no hay una API nativa de encuestas en Teams).
|
||||
|
||||
- CLI: `openclaw message poll --channel msteams --target conversation:<id> ...`
|
||||
- Los votos se registran por el gateway en `~/.openclaw/msteams-polls.json`.
|
||||
- Los votos los registra el gateway en `~/.openclaw/msteams-polls.json`.
|
||||
- El gateway debe permanecer en línea para registrar votos.
|
||||
- Las encuestas aún no publican automáticamente resúmenes de resultados (inspecciona el archivo de almacenamiento si es necesario).
|
||||
- Las encuestas aún no publican automáticamente resúmenes de resultados (inspecciona el archivo de almacenamiento si hace falta).
|
||||
|
||||
## Adaptive Cards (arbitrarias)
|
||||
|
||||
@ -642,7 +795,7 @@ Envía cualquier JSON de Adaptive Card a usuarios o conversaciones de Teams usan
|
||||
|
||||
El parámetro `card` acepta un objeto JSON de Adaptive Card. Cuando se proporciona `card`, el texto del mensaje es opcional.
|
||||
|
||||
**Herramienta de agente:**
|
||||
**Herramienta del agente:**
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -665,18 +818,18 @@ openclaw message send --channel msteams \
|
||||
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'
|
||||
```
|
||||
|
||||
Consulta la [documentación de Adaptive Cards](https://adaptivecards.io/) para ver el esquema de tarjetas y ejemplos. Para detalles sobre el formato de destino, consulta [Formatos de destino](#formatos-de-destino) abajo.
|
||||
Consulta la [documentación de Adaptive Cards](https://adaptivecards.io/) para ver el esquema de tarjetas y ejemplos. Para conocer los detalles del formato de destino, consulta [Formatos de destino](#target-formats) abajo.
|
||||
|
||||
## Formatos de destino
|
||||
|
||||
Los destinos de MSTeams usan prefijos para distinguir entre usuarios y conversaciones:
|
||||
|
||||
| Tipo de destino | Formato | Ejemplo |
|
||||
| ------------------- | -------------------------------- | --------------------------------------------------- |
|
||||
| Usuario (por ID) | `user:<aad-object-id>` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` |
|
||||
| Usuario (por nombre) | `user:<display-name>` | `user:John Smith` (requiere Graph API) |
|
||||
| Grupo/canal | `conversation:<conversation-id>` | `conversation:19:abc123...@thread.tacv2` |
|
||||
| Grupo/canal (sin procesar) | `<conversation-id>` | `19:abc123...@thread.tacv2` (si contiene `@thread`) |
|
||||
| Tipo de destino | Formato | Ejemplo |
|
||||
| ---------------------- | -------------------------------- | --------------------------------------------------- |
|
||||
| Usuario (por ID) | `user:<aad-object-id>` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` |
|
||||
| Usuario (por nombre) | `user:<display-name>` | `user:John Smith` (requiere la API de Graph) |
|
||||
| Grupo/canal | `conversation:<conversation-id>` | `conversation:19:abc123...@thread.tacv2` |
|
||||
| Grupo/canal (sin procesar) | `<conversation-id>` | `19:abc123...@thread.tacv2` (si contiene `@thread`) |
|
||||
|
||||
**Ejemplos de CLI:**
|
||||
|
||||
@ -684,7 +837,7 @@ Los destinos de MSTeams usan prefijos para distinguir entre usuarios y conversac
|
||||
# Enviar a un usuario por ID
|
||||
openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
|
||||
|
||||
# Enviar a un usuario por nombre para mostrar (activa búsqueda en Graph API)
|
||||
# Enviar a un usuario por nombre para mostrar (activa la búsqueda con la API de Graph)
|
||||
openclaw message send --channel msteams --target "user:John Smith" --message "Hello"
|
||||
|
||||
# Enviar a un chat grupal o canal
|
||||
@ -695,7 +848,7 @@ openclaw message send --channel msteams --target "conversation:19:abc...@thread.
|
||||
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'
|
||||
```
|
||||
|
||||
**Ejemplos de herramienta de agente:**
|
||||
**Ejemplos de herramientas del agente:**
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -719,56 +872,56 @@ openclaw message send --channel msteams --target "conversation:19:abc...@thread.
|
||||
}
|
||||
```
|
||||
|
||||
Nota: Sin el prefijo `user:`, los nombres se interpretan por defecto como resolución de grupo/equipo. Usa siempre `user:` cuando apuntes a personas por nombre para mostrar.
|
||||
Nota: Sin el prefijo `user:`, los nombres usan por defecto la resolución de grupo/equipo. Usa siempre `user:` cuando apuntes a personas por nombre para mostrar.
|
||||
|
||||
## Mensajería proactiva
|
||||
|
||||
- Los mensajes proactivos solo son posibles **después** de que un usuario haya interactuado, porque almacenamos las referencias de conversación en ese momento.
|
||||
- Consulta `/gateway/configuration` para `dmPolicy` y el control por lista de permitidos.
|
||||
- Los mensajes proactivos solo son posibles **después** de que un usuario haya interactuado, porque almacenamos referencias de conversación en ese momento.
|
||||
- Consulta `/gateway/configuration` para `dmPolicy` y el control mediante lista de permitidos.
|
||||
|
||||
## IDs de equipo y canal (error habitual)
|
||||
## IDs de equipo y canal (error común)
|
||||
|
||||
El parámetro de consulta `groupId` en las URL de Teams **NO** es el ID de equipo usado para la configuración. Extrae los IDs de la ruta de la URL:
|
||||
El parámetro de consulta `groupId` en las URL de Teams **NO** es el ID de equipo usado para la configuración. Extrae los IDs de la ruta de la URL en su lugar:
|
||||
|
||||
**URL de equipo:**
|
||||
**URL del equipo:**
|
||||
|
||||
```
|
||||
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
|
||||
└────────────────────────────┘
|
||||
ID de equipo (decodifica la URL)
|
||||
ID del equipo (decodifica esta URL)
|
||||
```
|
||||
|
||||
**URL de canal:**
|
||||
**URL del canal:**
|
||||
|
||||
```
|
||||
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
|
||||
└─────────────────────────┘
|
||||
ID de canal (decodifica la URL)
|
||||
ID del canal (decodifica esta URL)
|
||||
```
|
||||
|
||||
**Para la configuración:**
|
||||
|
||||
- ID de equipo = segmento de ruta después de `/team/` (decodificado de URL, p. ej., `19:Bk4j...@thread.tacv2`)
|
||||
- ID de canal = segmento de ruta después de `/channel/` (decodificado de URL)
|
||||
- ID del equipo = segmento de ruta después de `/team/` (URL decodificada, por ejemplo, `19:Bk4j...@thread.tacv2`)
|
||||
- ID del canal = segmento de ruta después de `/channel/` (URL decodificada)
|
||||
- **Ignora** el parámetro de consulta `groupId`
|
||||
|
||||
## Canales privados
|
||||
|
||||
Los bots tienen compatibilidad limitada en canales privados:
|
||||
Los bots tienen soporte limitado en canales privados:
|
||||
|
||||
| Función | Canales estándar | Canales privados |
|
||||
| ---------------------------- | ----------------- | ---------------------- |
|
||||
| Instalación del bot | Sí | Limitada |
|
||||
| Mensajes en tiempo real (webhook) | Sí | Puede que no funcione |
|
||||
| Permisos RSC | Sí | Puede comportarse de forma diferente |
|
||||
| @mentions | Sí | Si el bot es accesible |
|
||||
| Historial de Graph API | Sí | Sí (con permisos) |
|
||||
| Función | Canales estándar | Canales privados |
|
||||
| --------------------------- | ---------------- | --------------------- |
|
||||
| Instalación del bot | Sí | Limitada |
|
||||
| Mensajes en tiempo real (webhook) | Sí | Puede no funcionar |
|
||||
| Permisos RSC | Sí | Pueden comportarse de forma distinta |
|
||||
| @mentions | Sí | Si el bot es accesible |
|
||||
| Historial con la API de Graph | Sí | Sí (con permisos) |
|
||||
|
||||
**Soluciones alternativas si los canales privados no funcionan:**
|
||||
**Soluciones si los canales privados no funcionan:**
|
||||
|
||||
1. Usa canales estándar para las interacciones con el bot
|
||||
2. Usa MD: los usuarios siempre pueden enviar mensajes directos al bot
|
||||
3. Usa Graph API para acceso histórico (requiere `ChannelMessage.Read.All`)
|
||||
1. Usa canales estándar para interacciones con el bot
|
||||
2. Usa mensajes directos: los usuarios siempre pueden enviar mensajes directamente al bot
|
||||
3. Usa la API de Graph para acceso histórico (requiere `ChannelMessage.Read.All`)
|
||||
|
||||
## Solución de problemas
|
||||
|
||||
@ -776,37 +929,37 @@ Los bots tienen compatibilidad limitada en canales privados:
|
||||
|
||||
- **Las imágenes no aparecen en canales:** faltan permisos de Graph o consentimiento de administrador. Reinstala la aplicación de Teams y cierra/reabre Teams por completo.
|
||||
- **No hay respuestas en el canal:** las menciones son obligatorias de forma predeterminada; establece `channels.msteams.requireMention=false` o configúralo por equipo/canal.
|
||||
- **Incompatibilidad de versión (Teams sigue mostrando el manifiesto antiguo):** elimina y vuelve a añadir la aplicación y cierra Teams por completo para actualizar.
|
||||
- **401 Unauthorized del webhook:** Esperado al probar manualmente sin JWT de Azure; significa que el endpoint es accesible, pero la autenticación falló. Usa Azure Web Chat para probar correctamente.
|
||||
- **Desajuste de versión (Teams sigue mostrando el manifiesto anterior):** elimina y vuelve a añadir la aplicación, y cierra Teams por completo para actualizar.
|
||||
- **401 Unauthorized desde el webhook:** es lo esperado al probar manualmente sin Azure JWT; significa que el endpoint es accesible, pero la autenticación falló. Usa Azure Web Chat para probar correctamente.
|
||||
|
||||
### Errores al cargar el manifiesto
|
||||
|
||||
- **"Icon file cannot be empty":** El manifiesto hace referencia a archivos de icono de 0 bytes. Crea iconos PNG válidos (32x32 para `outline.png`, 192x192 para `color.png`).
|
||||
- **"webApplicationInfo.Id already in use":** La aplicación sigue instalada en otro equipo/chat. Búscala y desinstálala primero, o espera 5-10 minutos para la propagación.
|
||||
- **"Something went wrong" al cargar:** Cárgalo mediante [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com), abre las DevTools del navegador (F12) → pestaña Network, y revisa el cuerpo de la respuesta para ver el error real.
|
||||
- **Fallo en la carga lateral:** Prueba "Upload an app to your org's app catalog" en lugar de "Upload a custom app"; esto suele evitar restricciones de carga lateral.
|
||||
- **"Something went wrong" al cargar:** Cárgala mediante [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com) en su lugar, abre las herramientas de desarrollo del navegador (F12) → pestaña Network, y revisa el cuerpo de la respuesta para ver el error real.
|
||||
- **Fallo de carga lateral:** Prueba con "Upload an app to your org's app catalog" en lugar de "Upload a custom app"; esto suele omitir las restricciones de carga lateral.
|
||||
|
||||
### Los permisos RSC no funcionan
|
||||
|
||||
1. Verifica que `webApplicationInfo.id` coincida exactamente con el App ID de tu bot
|
||||
2. Vuelve a cargar la aplicación y reinstálala en el equipo/chat
|
||||
3. Comprueba si el administrador de tu organización ha bloqueado los permisos RSC
|
||||
4. Confirma que estás usando el ámbito correcto: `ChannelMessage.Read.Group` para equipos, `ChatMessage.Read.Chat` para chats grupales
|
||||
4. Confirma que estás usando el alcance correcto: `ChannelMessage.Read.Group` para equipos, `ChatMessage.Read.Chat` para chats grupales
|
||||
|
||||
## Referencias
|
||||
|
||||
- [Create Azure Bot](https://learn.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) - guía de configuración de Azure Bot
|
||||
- [Teams Developer Portal](https://dev.teams.microsoft.com/apps) - crear/gestionar aplicaciones de Teams
|
||||
- [Esquema del manifiesto de la aplicación de Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema)
|
||||
- [Recibir mensajes de canal con RSC](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc)
|
||||
- [Referencia de permisos RSC](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent)
|
||||
- [Manejo de archivos del bot de Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4) (canal/grupo requiere Graph)
|
||||
- [Mensajería proactiva](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages)
|
||||
- [Teams app manifest schema](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema)
|
||||
- [Receive channel messages with RSC](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc)
|
||||
- [RSC permissions reference](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent)
|
||||
- [Teams bot file handling](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4) (canal/grupo requiere Graph)
|
||||
- [Proactive messaging](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages)
|
||||
|
||||
## Relacionado
|
||||
|
||||
- [Resumen de canales](/channels) — todos los canales compatibles
|
||||
- [Emparejamiento](/channels/pairing) — autenticación de MD y flujo de emparejamiento
|
||||
- [Grupos](/channels/groups) — comportamiento del chat grupal y control por mención
|
||||
- [Enrutamiento de canales](/channels/channel-routing) — enrutamiento de sesiones para mensajes
|
||||
- [Seguridad](/gateway/security) — modelo de acceso y endurecimiento
|
||||
- [Resumen de canales](/es/channels) — todos los canales compatibles
|
||||
- [Pairing](/es/channels/pairing) — autenticación de mensajes directos y flujo de emparejamiento
|
||||
- [Grupos](/es/channels/groups) — comportamiento del chat grupal y restricción por mención
|
||||
- [Enrutamiento de canales](/es/channels/channel-routing) — enrutamiento de sesiones para mensajes
|
||||
- [Seguridad](/es/gateway/security) — modelo de acceso y fortalecimiento
|
||||
|
||||
@ -1,60 +1,53 @@
|
||||
---
|
||||
read_when:
|
||||
- Estás cambiando el runtime del agente integrado o el registro del arnés
|
||||
- Estás registrando un arnés de agente desde un plugin integrado o de confianza
|
||||
- Estás cambiando el tiempo de ejecución integrado del agente o el registro del harness
|
||||
- Estás registrando un harness de agente desde un plugin incluido o de confianza
|
||||
- Necesitas entender cómo se relaciona el plugin Codex con los proveedores de modelos
|
||||
sidebarTitle: Agent Harness
|
||||
summary: Superficie experimental del SDK para plugins que reemplazan el ejecutor de agente integrado de bajo nivel
|
||||
title: Plugins de arnés de agente
|
||||
summary: Superficie experimental del SDK para plugins que reemplazan el ejecutor integrado de agentes de bajo nivel
|
||||
title: Plugins de Agent Harness
|
||||
x-i18n:
|
||||
generated_at: "2026-04-11T02:46:17Z"
|
||||
generated_at: "2026-04-12T00:19:04Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 43c1f2c087230398b0162ed98449f239c8db1e822e51c7dcd40c54fa6c3374e1
|
||||
source_hash: 62b88fd24ce8b600179db27e16e8d764a2cd7a14e5c5df76374c33121aa5e365
|
||||
source_path: plugins/sdk-agent-harness.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Plugins de arnés de agente
|
||||
# Plugins de Agent Harness
|
||||
|
||||
Un **arnés de agente** es el ejecutor de bajo nivel para un turno preparado de un agente de OpenClaw.
|
||||
No es un proveedor de modelos, ni un canal, ni un registro de herramientas.
|
||||
Un **agent harness** es el ejecutor de bajo nivel para un turno preparado de un agente de OpenClaw. No es un proveedor de modelos, no es un canal y no es un registro de herramientas.
|
||||
|
||||
Usa esta superficie solo para plugins nativos integrados o de confianza. El contrato
|
||||
sigue siendo experimental porque los tipos de parámetros reflejan intencionalmente el ejecutor
|
||||
integrado actual.
|
||||
Usa esta superficie solo para plugins nativos incluidos o de confianza. El contrato sigue siendo experimental porque los tipos de parámetros reflejan intencionalmente el ejecutor integrado actual.
|
||||
|
||||
## Cuándo usar un arnés
|
||||
## Cuándo usar un harness
|
||||
|
||||
Registra un arnés de agente cuando una familia de modelos tiene su propio runtime
|
||||
nativo de sesión y el transporte normal de proveedor de OpenClaw es la abstracción incorrecta.
|
||||
Registra un agent harness cuando una familia de modelos tiene su propio tiempo de ejecución de sesión nativo y el transporte normal de proveedores de OpenClaw es la abstracción incorrecta.
|
||||
|
||||
Ejemplos:
|
||||
|
||||
- un servidor nativo de agente de coding que gestiona hilos y compactación
|
||||
- una CLI o daemon local que debe transmitir eventos nativos de plan/razonamiento/herramientas
|
||||
- un runtime de modelo que necesita su propio ID de reanudación además de la
|
||||
transcripción de sesión de OpenClaw
|
||||
- un servidor nativo de agente de programación que administra hilos y compactación
|
||||
- una CLI o un daemon local que debe transmitir eventos nativos de plan/razonamiento/herramientas
|
||||
- un tiempo de ejecución de modelos que necesita su propio id de reanudación además del transcrito de sesión de OpenClaw
|
||||
|
||||
**No** registres un arnés solo para agregar una nueva API de LLM. Para APIs normales de modelos por HTTP o
|
||||
WebSocket, crea un [plugin de proveedor](/es/plugins/sdk-provider-plugins).
|
||||
**No** registres un harness solo para agregar una nueva API de LLM. Para APIs de modelos HTTP o WebSocket normales, crea un [plugin de proveedor](/es/plugins/sdk-provider-plugins).
|
||||
|
||||
## Qué sigue gestionando el núcleo
|
||||
## Lo que el núcleo sigue administrando
|
||||
|
||||
Antes de que se seleccione un arnés, OpenClaw ya ha resuelto:
|
||||
Antes de que se seleccione un harness, OpenClaw ya ha resuelto:
|
||||
|
||||
- proveedor y modelo
|
||||
- estado de autenticación de runtime
|
||||
- nivel de pensamiento y presupuesto de contexto
|
||||
- la transcripción/archivo de sesión de OpenClaw
|
||||
- estado de autenticación del tiempo de ejecución
|
||||
- nivel de razonamiento y presupuesto de contexto
|
||||
- el archivo de transcripción/sesión de OpenClaw
|
||||
- espacio de trabajo, sandbox y política de herramientas
|
||||
- callbacks de respuesta del canal y callbacks de streaming
|
||||
- política de respaldo de modelos y cambio de modelos en vivo
|
||||
- callbacks de respuesta del canal y callbacks de transmisión
|
||||
- política de fallback de modelo y cambio de modelo en vivo
|
||||
|
||||
Esa división es intencional. Un arnés ejecuta un intento preparado; no elige
|
||||
proveedores, no reemplaza la entrega por canal ni cambia modelos silenciosamente.
|
||||
Esta separación es intencional. Un harness ejecuta un intento preparado; no elige proveedores, no reemplaza la entrega del canal ni cambia modelos silenciosamente.
|
||||
|
||||
## Registrar un arnés
|
||||
## Registrar un harness
|
||||
|
||||
**Importación:** `openclaw/plugin-sdk/agent-harness`
|
||||
|
||||
@ -64,7 +57,7 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
|
||||
const myHarness: AgentHarness = {
|
||||
id: "my-harness",
|
||||
label: "Mi arnés de agente nativo",
|
||||
label: "My native agent harness",
|
||||
|
||||
supports(ctx) {
|
||||
return ctx.provider === "my-provider"
|
||||
@ -73,17 +66,17 @@ const myHarness: AgentHarness = {
|
||||
},
|
||||
|
||||
async runAttempt(params) {
|
||||
// Inicia o reanuda tu hilo nativo.
|
||||
// Usa params.prompt, params.tools, params.images, params.onPartialReply,
|
||||
// params.onAgentEvent y los demás campos del intento preparado.
|
||||
// Start or resume your native thread.
|
||||
// Use params.prompt, params.tools, params.images, params.onPartialReply,
|
||||
// params.onAgentEvent, and the other prepared attempt fields.
|
||||
return await runMyNativeTurn(params);
|
||||
},
|
||||
};
|
||||
|
||||
export default definePluginEntry({
|
||||
id: "my-native-agent",
|
||||
name: "Mi agente nativo",
|
||||
description: "Ejecuta modelos seleccionados mediante un daemon nativo de agente.",
|
||||
name: "My Native Agent",
|
||||
description: "Runs selected models through a native agent daemon.",
|
||||
register(api) {
|
||||
api.registerAgentHarness(myHarness);
|
||||
},
|
||||
@ -92,66 +85,51 @@ export default definePluginEntry({
|
||||
|
||||
## Política de selección
|
||||
|
||||
OpenClaw elige un arnés después de resolver proveedor/modelo:
|
||||
OpenClaw elige un harness después de la resolución de proveedor/modelo:
|
||||
|
||||
1. `OPENCLAW_AGENT_RUNTIME=<id>` fuerza un arnés registrado con ese id.
|
||||
2. `OPENCLAW_AGENT_RUNTIME=pi` fuerza el arnés PI integrado.
|
||||
3. `OPENCLAW_AGENT_RUNTIME=auto` pide a los arneses registrados si admiten el
|
||||
proveedor/modelo resuelto.
|
||||
4. Si ningún arnés registrado coincide, OpenClaw usa PI a menos que el respaldo a PI
|
||||
esté desactivado.
|
||||
1. `OPENCLAW_AGENT_RUNTIME=<id>` fuerza un harness registrado con ese id.
|
||||
2. `OPENCLAW_AGENT_RUNTIME=pi` fuerza el harness PI integrado.
|
||||
3. `OPENCLAW_AGENT_RUNTIME=auto` pide a los harnesses registrados si admiten el proveedor/modelo resuelto.
|
||||
4. Si ningún harness registrado coincide, OpenClaw usa PI a menos que el fallback a PI esté deshabilitado.
|
||||
|
||||
Los fallos de arneses de plugin forzados aparecen como fallos de ejecución. En modo `auto`,
|
||||
OpenClaw puede recurrir a PI cuando el arnés de plugin seleccionado falla antes de que un
|
||||
turno haya producido efectos secundarios. Configura `OPENCLAW_AGENT_HARNESS_FALLBACK=none` o
|
||||
`embeddedHarness.fallback: "none"` para convertir ese respaldo en un fallo definitivo.
|
||||
Los fallos de un harness de plugin forzado se muestran como fallos de ejecución. En modo `auto`, OpenClaw puede volver a PI cuando el harness de plugin seleccionado falla antes de que un turno haya producido efectos secundarios. Configura `OPENCLAW_AGENT_HARNESS_FALLBACK=none` o `embeddedHarness.fallback: "none"` para que ese fallback sea en cambio un fallo definitivo.
|
||||
|
||||
El plugin Codex integrado registra `codex` como su ID de arnés. El núcleo trata eso
|
||||
como un ID ordinario de arnés de plugin; los alias específicos de Codex pertenecen al plugin
|
||||
o a la configuración del operador, no al selector de runtime compartido.
|
||||
El plugin Codex incluido registra `codex` como su id de harness. El núcleo trata eso como un id de harness de plugin normal; los alias específicos de Codex pertenecen al plugin o a la configuración del operador, no al selector de tiempo de ejecución compartido.
|
||||
|
||||
## Emparejamiento de proveedor y arnés
|
||||
## Emparejamiento de proveedor y harness
|
||||
|
||||
La mayoría de los arneses también deberían registrar un proveedor. El proveedor hace visibles al resto de
|
||||
OpenClaw las referencias de modelo, el estado de autenticación, los metadatos del modelo y la selección de `/model`.
|
||||
Luego el arnés reclama ese proveedor en `supports(...)`.
|
||||
La mayoría de los harnesses también deberían registrar un proveedor. El proveedor hace que las referencias de modelos, el estado de autenticación, los metadatos del modelo y la selección de `/model` sean visibles para el resto de OpenClaw. Luego, el harness reclama ese proveedor en `supports(...)`.
|
||||
|
||||
El plugin Codex integrado sigue este patrón:
|
||||
El plugin Codex incluido sigue este patrón:
|
||||
|
||||
- ID de proveedor: `codex`
|
||||
- referencias de modelo para el usuario: `codex/gpt-5.4`, `codex/gpt-5.2` u otro modelo devuelto
|
||||
por el servidor de aplicaciones de Codex
|
||||
- ID de arnés: `codex`
|
||||
- autenticación: disponibilidad sintética del proveedor, porque el arnés Codex gestiona el
|
||||
inicio de sesión/sesión nativos de Codex
|
||||
- solicitud al servidor de aplicaciones: OpenClaw envía el ID de modelo sin prefijo a Codex y deja que el
|
||||
arnés hable con el protocolo nativo del servidor de aplicaciones
|
||||
- id del proveedor: `codex`
|
||||
- referencias de modelos del usuario: `codex/gpt-5.4`, `codex/gpt-5.2` u otro modelo devuelto por el servidor de aplicaciones de Codex
|
||||
- id del harness: `codex`
|
||||
- autenticación: disponibilidad sintética del proveedor, porque el harness de Codex administra el inicio de sesión/sesión nativos de Codex
|
||||
- solicitud al servidor de aplicaciones: OpenClaw envía el id de modelo sin prefijo a Codex y permite que el harness hable con el protocolo nativo del servidor de aplicaciones
|
||||
|
||||
El plugin Codex es aditivo. Las referencias simples `openai/gpt-*` siguen siendo referencias del proveedor OpenAI
|
||||
y continúan usando la ruta normal de proveedor de OpenClaw. Selecciona `codex/gpt-*`
|
||||
cuando quieras autenticación gestionada por Codex, detección de modelos de Codex, hilos nativos y
|
||||
ejecución en servidor de aplicaciones de Codex. `/model` puede cambiar entre los modelos de Codex devueltos
|
||||
por el servidor de aplicaciones de Codex sin requerir credenciales del proveedor OpenAI.
|
||||
El plugin Codex es aditivo. Las referencias simples `openai/gpt-*` siguen siendo referencias del proveedor OpenAI y continúan usando la ruta normal de proveedores de OpenClaw. Selecciona `codex/gpt-*` cuando quieras autenticación administrada por Codex, descubrimiento de modelos de Codex, hilos nativos y ejecución del servidor de aplicaciones de Codex. `/model` puede cambiar entre los modelos de Codex devueltos por el servidor de aplicaciones de Codex sin requerir credenciales del proveedor OpenAI.
|
||||
|
||||
Para la configuración del operador, ejemplos de prefijos de modelo y configuraciones solo de Codex, consulta
|
||||
[Codex Harness](/es/plugins/codex-harness).
|
||||
Para la configuración del operador, ejemplos de prefijos de modelo y configuraciones exclusivas de Codex, consulta [Codex Harness](/es/plugins/codex-harness).
|
||||
|
||||
OpenClaw requiere Codex app-server `0.118.0` o posterior. El plugin Codex verifica el handshake
|
||||
de inicialización del servidor de aplicaciones y bloquea servidores más antiguos o sin versión para que
|
||||
OpenClaw solo se ejecute sobre la superficie de protocolo con la que se ha probado.
|
||||
OpenClaw requiere Codex app-server `0.118.0` o una versión más reciente. El plugin Codex verifica el handshake de inicialización del servidor de aplicaciones y bloquea servidores más antiguos o sin versión para que OpenClaw solo se ejecute contra la superficie de protocolo con la que se ha probado.
|
||||
|
||||
## Desactivar el respaldo a PI
|
||||
### Modo de harness nativo de Codex
|
||||
|
||||
De forma predeterminada, OpenClaw ejecuta agentes integrados con `agents.defaults.embeddedHarness`
|
||||
configurado como `{ runtime: "auto", fallback: "pi" }`. En modo `auto`, los plugins registrados
|
||||
de arnés pueden reclamar un par proveedor/modelo. Si ninguno coincide, o si un
|
||||
arnés de plugin seleccionado automáticamente falla antes de producir salida, OpenClaw recurre a PI.
|
||||
El harness `codex` incluido es el modo nativo de Codex para los turnos integrados de agentes de OpenClaw. Primero habilita el plugin `codex` incluido e incluye `codex` en `plugins.allow` si tu configuración usa una allowlist restrictiva. Es diferente de `openai-codex/*`:
|
||||
|
||||
Configura `fallback: "none"` cuando necesites demostrar que un arnés de plugin es el único
|
||||
runtime que se está usando. Esto desactiva el respaldo automático a PI; no bloquea
|
||||
un `runtime: "pi"` explícito ni `OPENCLAW_AGENT_RUNTIME=pi`.
|
||||
- `openai-codex/*` usa OAuth de ChatGPT/Codex a través de la ruta normal de proveedores de OpenClaw.
|
||||
- `codex/*` usa el proveedor Codex incluido y enruta el turno a través de Codex app-server.
|
||||
|
||||
Para ejecuciones integradas solo con Codex:
|
||||
Cuando se ejecuta este modo, Codex administra el id del hilo nativo, el comportamiento de reanudación, la compactación y la ejecución del servidor de aplicaciones. OpenClaw sigue administrando el canal de chat, el espejo visible de la transcripción, la política de herramientas, las aprobaciones, la entrega de medios y la selección de sesión. Usa `embeddedHarness.runtime: "codex"` con `embeddedHarness.fallback: "none"` cuando necesites demostrar que se usa la ruta de Codex app-server y que el fallback a PI no está ocultando un harness nativo defectuoso.
|
||||
|
||||
## Deshabilitar el fallback a PI
|
||||
|
||||
De forma predeterminada, OpenClaw ejecuta agentes integrados con `agents.defaults.embeddedHarness` configurado como `{ runtime: "auto", fallback: "pi" }`. En el modo `auto`, los harnesses de plugin registrados pueden reclamar un par proveedor/modelo. Si ninguno coincide, o si un harness de plugin seleccionado automáticamente falla antes de producir salida, OpenClaw vuelve a PI.
|
||||
|
||||
Configura `fallback: "none"` cuando necesites demostrar que un harness de plugin es el único tiempo de ejecución que se está usando. Esto deshabilita el fallback automático a PI; no bloquea un `runtime: "pi"` explícito ni `OPENCLAW_AGENT_RUNTIME=pi`.
|
||||
|
||||
Para ejecuciones integradas exclusivas de Codex:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -167,9 +145,7 @@ Para ejecuciones integradas solo con Codex:
|
||||
}
|
||||
```
|
||||
|
||||
Si quieres que cualquier arnés de plugin registrado reclame modelos coincidentes pero nunca
|
||||
quieres que OpenClaw recurra silenciosamente a PI, mantén `runtime: "auto"` y desactiva
|
||||
el respaldo:
|
||||
Si quieres que cualquier harness de plugin registrado reclame modelos coincidentes pero nunca quieres que OpenClaw vuelva silenciosamente a PI, mantén `runtime: "auto"` y deshabilita el fallback:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -209,9 +185,7 @@ Las anulaciones por agente usan la misma forma:
|
||||
}
|
||||
```
|
||||
|
||||
`OPENCLAW_AGENT_RUNTIME` sigue anulando el runtime configurado. Usa
|
||||
`OPENCLAW_AGENT_HARNESS_FALLBACK=none` para desactivar el respaldo a PI desde el
|
||||
entorno.
|
||||
`OPENCLAW_AGENT_RUNTIME` sigue anulando el tiempo de ejecución configurado. Usa `OPENCLAW_AGENT_HARNESS_FALLBACK=none` para deshabilitar el fallback a PI desde el entorno.
|
||||
|
||||
```bash
|
||||
OPENCLAW_AGENT_RUNTIME=codex \
|
||||
@ -219,53 +193,39 @@ OPENCLAW_AGENT_HARNESS_FALLBACK=none \
|
||||
openclaw gateway run
|
||||
```
|
||||
|
||||
Con el respaldo desactivado, una sesión falla temprano cuando el arnés solicitado no está
|
||||
registrado, no admite el proveedor/modelo resuelto o falla antes de
|
||||
producir efectos secundarios del turno. Eso es intencional para despliegues solo con Codex y
|
||||
para pruebas en vivo que deben demostrar que realmente se está usando la ruta del servidor de aplicaciones de Codex.
|
||||
Con el fallback deshabilitado, una sesión falla pronto cuando el harness solicitado no está registrado, no admite el proveedor/modelo resuelto o falla antes de producir efectos secundarios del turno. Eso es intencional para implementaciones exclusivas de Codex y para pruebas en vivo que deben demostrar que la ruta de Codex app-server realmente está en uso.
|
||||
|
||||
Esta configuración solo controla el arnés de agente integrado. No desactiva
|
||||
el enrutamiento específico de modelos para imagen, video, música, TTS, PDF u otros proveedores.
|
||||
Esta configuración solo controla el harness integrado del agente. No deshabilita el enrutamiento específico del proveedor para modelos de imagen, video, música, TTS, PDF u otros.
|
||||
|
||||
## Sesiones nativas y espejo de transcripción
|
||||
|
||||
Un arnés puede conservar un ID de sesión nativa, ID de hilo o token de reanudación del lado del daemon.
|
||||
Mantén esa asociación vinculada explícitamente con la sesión de OpenClaw y sigue
|
||||
reflejando la salida visible para el usuario del asistente/herramienta en la transcripción de OpenClaw.
|
||||
Un harness puede conservar un id de sesión nativo, id de hilo o token de reanudación del lado del daemon. Mantén esa vinculación asociada explícitamente con la sesión de OpenClaw y sigue reflejando en la transcripción de OpenClaw la salida visible para el usuario del asistente/herramienta.
|
||||
|
||||
La transcripción de OpenClaw sigue siendo la capa de compatibilidad para:
|
||||
|
||||
- historial de sesión visible en el canal
|
||||
- búsqueda e indexación de transcripciones
|
||||
- volver al arnés PI integrado en un turno posterior
|
||||
- comportamiento genérico de `/new`, `/reset` y eliminación de sesiones
|
||||
- volver al harness PI integrado en un turno posterior
|
||||
- comportamiento genérico de `/new`, `/reset` y eliminación de sesión
|
||||
|
||||
Si tu arnés almacena una asociación auxiliar, implementa `reset(...)` para que OpenClaw pueda
|
||||
borrarla cuando se restablezca la sesión de OpenClaw propietaria.
|
||||
Si tu harness almacena una vinculación sidecar, implementa `reset(...)` para que OpenClaw pueda borrarla cuando se restablezca la sesión de OpenClaw propietaria.
|
||||
|
||||
## Resultados de herramientas y medios
|
||||
|
||||
El núcleo construye la lista de herramientas de OpenClaw y la pasa al intento preparado.
|
||||
Cuando un arnés ejecuta una llamada de herramienta dinámica, devuelve el resultado de la herramienta mediante
|
||||
la forma de resultado del arnés en lugar de enviar tú mismo el contenido multimedia por el canal.
|
||||
El núcleo construye la lista de herramientas de OpenClaw y la pasa al intento preparado. Cuando un harness ejecuta una llamada de herramienta dinámica, devuelve el resultado de la herramienta a través de la forma de resultado del harness en lugar de enviar tú mismo los medios del canal.
|
||||
|
||||
Esto mantiene las salidas de texto, imagen, video, música, TTS, aprobación y herramientas de mensajería
|
||||
en la misma ruta de entrega que las ejecuciones respaldadas por PI.
|
||||
Esto mantiene las salidas de texto, imagen, video, música, TTS, aprobación y herramientas de mensajería en la misma ruta de entrega que las ejecuciones respaldadas por PI.
|
||||
|
||||
## Limitaciones actuales
|
||||
|
||||
- La ruta pública de importación es genérica, pero algunos alias de tipos de intento/resultado todavía
|
||||
llevan nombres `Pi` por compatibilidad.
|
||||
- La instalación de arneses de terceros es experimental. Prefiere plugins de proveedor
|
||||
hasta que necesites un runtime de sesión nativa.
|
||||
- Se admite el cambio de arnés entre turnos. No cambies de arnés en medio de un
|
||||
turno después de que hayan comenzado herramientas nativas, aprobaciones, texto del asistente o
|
||||
envíos de mensajes.
|
||||
- La ruta de importación pública es genérica, pero algunos alias de tipos de intento/resultado todavía llevan nombres `Pi` por compatibilidad.
|
||||
- La instalación de harnesses de terceros es experimental. Prefiere plugins de proveedor hasta que necesites un tiempo de ejecución de sesión nativo.
|
||||
- Se admite el cambio de harness entre turnos. No cambies de harness en medio de un turno después de que hayan comenzado herramientas nativas, aprobaciones, texto del asistente o envíos de mensajes.
|
||||
|
||||
## Relacionado
|
||||
|
||||
- [SDK Overview](/es/plugins/sdk-overview)
|
||||
- [Runtime Helpers](/es/plugins/sdk-runtime)
|
||||
- [Provider Plugins](/es/plugins/sdk-provider-plugins)
|
||||
- [Resumen del SDK](/es/plugins/sdk-overview)
|
||||
- [Helpers de tiempo de ejecución](/es/plugins/sdk-runtime)
|
||||
- [Plugins de proveedor](/es/plugins/sdk-provider-plugins)
|
||||
- [Codex Harness](/es/plugins/codex-harness)
|
||||
- [Model Providers](/es/concepts/model-providers)
|
||||
- [Proveedores de modelos](/es/concepts/model-providers)
|
||||
|
||||
@ -1,31 +1,31 @@
|
||||
---
|
||||
read_when:
|
||||
- Quieres usar modelos de OpenAI en OpenClaw
|
||||
- Quieres autenticación con suscripción de Codex en lugar de API keys
|
||||
summary: Usa OpenAI mediante API keys o suscripción de Codex en OpenClaw
|
||||
- Quieres la autenticación mediante suscripción a Codex en lugar de claves de API
|
||||
- Necesitas un comportamiento de ejecución del agente GPT-5 más estricto
|
||||
summary: Usa OpenAI mediante claves de API o una suscripción a Codex en OpenClaw
|
||||
title: OpenAI
|
||||
x-i18n:
|
||||
generated_at: "2026-04-07T05:06:32Z"
|
||||
generated_at: "2026-04-12T00:19:04Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 6a2ce1ce5f085fe55ec50b8d20359180b9002c9730820cd5b0e011c3bf807b64
|
||||
source_hash: 7aa06fba9ac901e663685a6b26443a2f6aeb6ec3589d939522dc87cbb43497b4
|
||||
source_path: providers/openai.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# OpenAI
|
||||
|
||||
OpenAI proporciona APIs para desarrolladores de modelos GPT. Codex admite **inicio de sesión con ChatGPT** para acceso
|
||||
por suscripción o **inicio de sesión con API key** para acceso basado en uso. La nube de Codex requiere inicio de sesión con ChatGPT.
|
||||
OpenAI admite explícitamente el uso de OAuth con suscripción en herramientas/flujos de trabajo externos como OpenClaw.
|
||||
OpenAI proporciona API para desarrolladores para modelos GPT. Codex admite **inicio de sesión con ChatGPT** para acceso por suscripción o **inicio de sesión con clave de API** para acceso basado en uso. Codex cloud requiere inicio de sesión con ChatGPT.
|
||||
OpenAI admite explícitamente el uso de OAuth de suscripción en herramientas/flujos de trabajo externos como OpenClaw.
|
||||
|
||||
## Estilo de interacción predeterminado
|
||||
|
||||
OpenClaw puede agregar una pequeña superposición de prompt específica de OpenAI tanto para ejecuciones `openai/*` como
|
||||
`openai-codex/*`. De forma predeterminada, la superposición mantiene al asistente cálido,
|
||||
colaborativo, conciso, directo y un poco más expresivo emocionalmente
|
||||
sin reemplazar el prompt base del sistema de OpenClaw. La superposición amistosa también
|
||||
permite el emoji ocasional cuando encaja de forma natural, al tiempo que mantiene la
|
||||
`openai-codex/*`. De forma predeterminada, la superposición mantiene al asistente cercano,
|
||||
colaborativo, conciso, directo y un poco más expresivo emocionalmente,
|
||||
sin reemplazar el prompt base del sistema de OpenClaw. La superposición amigable también
|
||||
permite algún emoji ocasional cuando encaja de forma natural, manteniendo a la vez la
|
||||
salida general concisa.
|
||||
|
||||
Clave de configuración:
|
||||
@ -36,7 +36,7 @@ Valores permitidos:
|
||||
|
||||
- `"friendly"`: predeterminado; habilita la superposición específica de OpenAI.
|
||||
- `"on"`: alias de `"friendly"`.
|
||||
- `"off"`: desactiva la superposición y usa solo el prompt base de OpenClaw.
|
||||
- `"off"`: deshabilita la superposición y usa solo el prompt base de OpenClaw.
|
||||
|
||||
Alcance:
|
||||
|
||||
@ -44,8 +44,8 @@ Alcance:
|
||||
- Se aplica a los modelos `openai-codex/*`.
|
||||
- No afecta a otros proveedores.
|
||||
|
||||
Este comportamiento está activado de forma predeterminada. Mantén `"friendly"` explícitamente si quieres que esto
|
||||
sobreviva a futuros cambios locales de configuración:
|
||||
Este comportamiento está activado de forma predeterminada. Mantén `"friendly"` explícitamente si quieres que
|
||||
esto sobreviva a futuros cambios locales de configuración:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -61,9 +61,9 @@ sobreviva a futuros cambios locales de configuración:
|
||||
}
|
||||
```
|
||||
|
||||
### Desactivar la superposición de prompt de OpenAI
|
||||
### Deshabilitar la superposición de prompt de OpenAI
|
||||
|
||||
Si quieres el prompt base de OpenClaw sin modificar, establece la superposición en `"off"`:
|
||||
Si quieres el prompt base de OpenClaw sin modificaciones, establece la superposición en `"off"`:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -86,24 +86,24 @@ openclaw config set plugins.entries.openai.config.personality off
|
||||
```
|
||||
|
||||
OpenClaw normaliza esta configuración sin distinguir mayúsculas y minúsculas en tiempo de ejecución, por lo que valores como
|
||||
`"Off"` también desactivan la superposición amistosa.
|
||||
`"Off"` siguen deshabilitando la superposición amigable.
|
||||
|
||||
## Opción A: API key de OpenAI (OpenAI Platform)
|
||||
## Opción A: clave de API de OpenAI (OpenAI Platform)
|
||||
|
||||
**Ideal para:** acceso directo a la API y facturación basada en uso.
|
||||
Obtén tu API key desde el panel de OpenAI.
|
||||
Obtén tu clave de API desde el panel de OpenAI.
|
||||
|
||||
Resumen de rutas:
|
||||
|
||||
- `openai/gpt-5.4` = ruta directa de la API de OpenAI Platform
|
||||
- Requiere `OPENAI_API_KEY` (o configuración equivalente del proveedor OpenAI)
|
||||
- Requiere `OPENAI_API_KEY` (o una configuración equivalente del proveedor OpenAI)
|
||||
- En OpenClaw, el inicio de sesión con ChatGPT/Codex se enruta mediante `openai-codex/*`, no `openai/*`
|
||||
|
||||
### Configuración en CLI
|
||||
### Configuración en la CLI
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice openai-api-key
|
||||
# o no interactivo
|
||||
# o de forma no interactiva
|
||||
openclaw onboard --openai-api-key "$OPENAI_API_KEY"
|
||||
```
|
||||
|
||||
@ -116,25 +116,25 @@ openclaw onboard --openai-api-key "$OPENAI_API_KEY"
|
||||
}
|
||||
```
|
||||
|
||||
La documentación actual de modelos de la API de OpenAI enumera `gpt-5.4` y `gpt-5.4-pro` para uso directo de la
|
||||
API de OpenAI. OpenClaw reenvía ambos mediante la ruta de Responses `openai/*`.
|
||||
OpenClaw suprime intencionadamente la fila obsoleta `openai/gpt-5.3-codex-spark`,
|
||||
La documentación actual de modelos de API de OpenAI enumera `gpt-5.4` y `gpt-5.4-pro` para uso directo de la
|
||||
API de OpenAI. OpenClaw reenvía ambos a través de la ruta `openai/*` Responses.
|
||||
OpenClaw suprime intencionalmente la fila obsoleta `openai/gpt-5.3-codex-spark`,
|
||||
porque las llamadas directas a la API de OpenAI la rechazan en tráfico real.
|
||||
|
||||
OpenClaw **no** expone `openai/gpt-5.3-codex-spark` en la ruta directa de la API de OpenAI.
|
||||
`pi-ai` sigue incluyendo una fila integrada para ese modelo, pero las solicitudes reales a la API de OpenAI
|
||||
la rechazan actualmente. En OpenClaw, Spark se considera solo de Codex.
|
||||
OpenClaw **no** expone `openai/gpt-5.3-codex-spark` en la ruta directa de la
|
||||
API de OpenAI. `pi-ai` sigue incluyendo una fila integrada para ese modelo, pero las solicitudes reales a la API de OpenAI
|
||||
actualmente la rechazan. Spark se trata como exclusivo de Codex en OpenClaw.
|
||||
|
||||
## Generación de imágenes
|
||||
|
||||
El plugin empaquetado `openai` también registra la generación de imágenes mediante la herramienta compartida
|
||||
El plugin `openai` incluido también registra la generación de imágenes mediante la herramienta compartida
|
||||
`image_generate`.
|
||||
|
||||
- Modelo de imagen predeterminado: `openai/gpt-image-1`
|
||||
- Generación: hasta 4 imágenes por solicitud
|
||||
- Modo de edición: habilitado, hasta 5 imágenes de referencia
|
||||
- Admite `size`
|
||||
- Advertencia específica actual de OpenAI: OpenClaw no reenvía hoy anulaciones de `aspectRatio` ni
|
||||
- Limitación actual específica de OpenAI: OpenClaw no reenvía hoy las anulaciones de `aspectRatio` ni
|
||||
`resolution` a la API de imágenes de OpenAI
|
||||
|
||||
Para usar OpenAI como proveedor de imágenes predeterminado:
|
||||
@ -151,21 +151,21 @@ Para usar OpenAI como proveedor de imágenes predeterminado:
|
||||
}
|
||||
```
|
||||
|
||||
Consulta [Generación de imágenes](/es/tools/image-generation) para los parámetros
|
||||
compartidos de herramientas, la selección de proveedor y el comportamiento de failover.
|
||||
Consulta [Generación de imágenes](/es/tools/image-generation) para ver los parámetros
|
||||
de la herramienta compartida, la selección de proveedor y el comportamiento de conmutación por error.
|
||||
|
||||
## Generación de video
|
||||
|
||||
El plugin empaquetado `openai` también registra la generación de video mediante la herramienta compartida
|
||||
El plugin `openai` incluido también registra la generación de video mediante la herramienta compartida
|
||||
`video_generate`.
|
||||
|
||||
- Modelo de video predeterminado: `openai/sora-2`
|
||||
- Modos: texto a video, imagen a video y flujos de referencia/edición con un solo video
|
||||
- Límites actuales: 1 imagen o 1 entrada de referencia de video
|
||||
- Advertencia específica actual de OpenAI: OpenClaw actualmente solo reenvía anulaciones de `size`
|
||||
para la generación nativa de video de OpenAI. Las anulaciones opcionales no compatibles
|
||||
- Límites actuales: 1 imagen o 1 video de referencia como entrada
|
||||
- Limitación actual específica de OpenAI: OpenClaw actualmente solo reenvía las anulaciones de `size`
|
||||
para la generación de video nativa de OpenAI. Las anulaciones opcionales no admitidas
|
||||
como `aspectRatio`, `resolution`, `audio` y `watermark` se ignoran
|
||||
y se devuelven como advertencia de herramienta.
|
||||
y se devuelven como una advertencia de herramienta.
|
||||
|
||||
Para usar OpenAI como proveedor de video predeterminado:
|
||||
|
||||
@ -181,31 +181,31 @@ Para usar OpenAI como proveedor de video predeterminado:
|
||||
}
|
||||
```
|
||||
|
||||
Consulta [Generación de video](/es/tools/video-generation) para los parámetros
|
||||
compartidos de herramientas, la selección de proveedor y el comportamiento de failover.
|
||||
Consulta [Generación de video](/es/tools/video-generation) para ver los parámetros
|
||||
de la herramienta compartida, la selección de proveedor y el comportamiento de conmutación por error.
|
||||
|
||||
## Opción B: suscripción a OpenAI Code (Codex)
|
||||
|
||||
**Ideal para:** usar acceso por suscripción de ChatGPT/Codex en lugar de una API key.
|
||||
La nube de Codex requiere inicio de sesión con ChatGPT, mientras que la CLI de Codex admite inicio de sesión con ChatGPT o API key.
|
||||
**Ideal para:** usar acceso por suscripción de ChatGPT/Codex en lugar de una clave de API.
|
||||
Codex cloud requiere inicio de sesión con ChatGPT, mientras que la CLI de Codex admite inicio de sesión con ChatGPT o con clave de API.
|
||||
|
||||
Resumen de rutas:
|
||||
|
||||
- `openai-codex/gpt-5.4` = ruta OAuth de ChatGPT/Codex
|
||||
- Usa inicio de sesión con ChatGPT/Codex, no una API key directa de OpenAI Platform
|
||||
- Los límites del proveedor para `openai-codex/*` pueden diferir de la experiencia web/app de ChatGPT
|
||||
- Usa inicio de sesión con ChatGPT/Codex, no una clave directa de API de OpenAI Platform
|
||||
- Los límites del lado del proveedor para `openai-codex/*` pueden diferir de la experiencia web/app de ChatGPT
|
||||
|
||||
### Configuración en CLI (OAuth de Codex)
|
||||
### Configuración en la CLI (OAuth de Codex)
|
||||
|
||||
```bash
|
||||
# Ejecutar OAuth de Codex en el asistente
|
||||
# Ejecuta OAuth de Codex en el asistente
|
||||
openclaw onboard --auth-choice openai-codex
|
||||
|
||||
# O ejecutar OAuth directamente
|
||||
# O ejecuta OAuth directamente
|
||||
openclaw models auth login --provider openai-codex
|
||||
```
|
||||
|
||||
### Fragmento de configuración (suscripción de Codex)
|
||||
### Fragmento de configuración (suscripción a Codex)
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -216,39 +216,40 @@ openclaw models auth login --provider openai-codex
|
||||
La documentación actual de Codex de OpenAI enumera `gpt-5.4` como el modelo actual de Codex. OpenClaw
|
||||
lo asigna a `openai-codex/gpt-5.4` para uso con OAuth de ChatGPT/Codex.
|
||||
|
||||
Esta ruta está intencionadamente separada de `openai/gpt-5.4`. Si quieres la
|
||||
ruta directa de la API de OpenAI Platform, usa `openai/*` con una API key. Si quieres
|
||||
Esta ruta se mantiene intencionalmente separada de `openai/gpt-5.4`. Si quieres la
|
||||
ruta directa de la API de OpenAI Platform, usa `openai/*` con una clave de API. Si quieres
|
||||
inicio de sesión con ChatGPT/Codex, usa `openai-codex/*`.
|
||||
|
||||
Si la incorporación reutiliza un inicio de sesión existente de Codex CLI, esas credenciales siguen
|
||||
gestionadas por Codex CLI. Al caducar, OpenClaw vuelve a leer primero la fuente externa de Codex
|
||||
y, cuando el proveedor puede actualizarla, escribe la credencial actualizada
|
||||
de vuelta en el almacenamiento de Codex en lugar de asumir la propiedad en una copia separada exclusiva de OpenClaw.
|
||||
Si el onboarding reutiliza un inicio de sesión existente de la CLI de Codex, esas credenciales seguirán
|
||||
gestionadas por la CLI de Codex. Cuando caduquen, OpenClaw vuelve a leer primero la fuente externa de Codex
|
||||
y, cuando el proveedor puede actualizarlas, escribe la credencial actualizada
|
||||
de vuelta en el almacenamiento de Codex en lugar de asumir la propiedad en una copia separada
|
||||
solo de OpenClaw.
|
||||
|
||||
Si tu cuenta de Codex tiene derecho a Codex Spark, OpenClaw también admite:
|
||||
|
||||
- `openai-codex/gpt-5.3-codex-spark`
|
||||
|
||||
OpenClaw trata Codex Spark como exclusivo de Codex. No expone una ruta directa
|
||||
`openai/gpt-5.3-codex-spark` con API key.
|
||||
OpenClaw trata Codex Spark como exclusivo de Codex. No expone una ruta directa con clave de API
|
||||
`openai/gpt-5.3-codex-spark`.
|
||||
|
||||
OpenClaw también conserva `openai-codex/gpt-5.3-codex-spark` cuando `pi-ai`
|
||||
lo detecta. Trátalo como dependiente de derechos y experimental: Codex Spark está
|
||||
separado de GPT-5.4 `/fast`, y la disponibilidad depende de la cuenta de Codex /
|
||||
ChatGPT con sesión iniciada.
|
||||
lo detecta. Trátalo como dependiente de derechos y experimental: Codex Spark es
|
||||
independiente de GPT-5.4 `/fast`, y la disponibilidad depende de la cuenta de Codex /
|
||||
ChatGPT que haya iniciado sesión.
|
||||
|
||||
### Límite de ventana de contexto de Codex
|
||||
|
||||
OpenClaw trata los metadatos del modelo de Codex y el límite de contexto en tiempo de ejecución como valores
|
||||
separados.
|
||||
OpenClaw trata los metadatos del modelo Codex y el límite de contexto en tiempo de ejecución como
|
||||
valores separados.
|
||||
|
||||
Para `openai-codex/gpt-5.4`:
|
||||
|
||||
- `contextWindow` nativo: `1050000`
|
||||
- límite predeterminado de `contextTokens` en tiempo de ejecución: `272000`
|
||||
- límite `contextTokens` predeterminado en tiempo de ejecución: `272000`
|
||||
|
||||
Esto mantiene fieles los metadatos del modelo mientras conserva la ventana predeterminada
|
||||
más pequeña en tiempo de ejecución, que en la práctica tiene mejores características de latencia y calidad.
|
||||
Esto mantiene fieles los metadatos del modelo y a la vez conserva la ventana predeterminada más pequeña en tiempo de ejecución,
|
||||
que en la práctica tiene mejores características de latencia y calidad.
|
||||
|
||||
Si quieres un límite efectivo diferente, establece `models.providers.<provider>.models[].contextTokens`:
|
||||
|
||||
@ -269,50 +270,51 @@ Si quieres un límite efectivo diferente, establece `models.providers.<provider>
|
||||
}
|
||||
```
|
||||
|
||||
Usa `contextWindow` solo cuando estés declarando o anulando metadatos nativos del
|
||||
modelo. Usa `contextTokens` cuando quieras limitar el presupuesto de contexto en tiempo de ejecución.
|
||||
Usa `contextWindow` solo cuando estés declarando o anulando metadatos nativos del modelo.
|
||||
Usa `contextTokens` cuando quieras limitar el presupuesto de contexto en tiempo de ejecución.
|
||||
|
||||
### Transporte predeterminado
|
||||
|
||||
OpenClaw usa `pi-ai` para el streaming del modelo. Tanto para `openai/*` como para
|
||||
`openai-codex/*`, el transporte predeterminado es `"auto"` (primero WebSocket, luego
|
||||
alternativa SSE).
|
||||
OpenClaw usa `pi-ai` para el streaming de modelos. Tanto para `openai/*` como para
|
||||
`openai-codex/*`, el transporte predeterminado es `"auto"` (WebSocket primero, luego
|
||||
respaldo con SSE).
|
||||
|
||||
En modo `"auto"`, OpenClaw también reintenta un fallo temprano de WebSocket que se pueda reintentar
|
||||
antes de pasar a SSE. El modo forzado `"websocket"` sigue mostrando errores de transporte directamente
|
||||
en lugar de ocultarlos detrás de la alternativa.
|
||||
En modo `"auto"`, OpenClaw también reintenta un fallo temprano de WebSocket que pueda reintentarse
|
||||
antes de pasar a SSE. El modo `"websocket"` forzado sigue mostrando los errores de transporte
|
||||
directamente en lugar de ocultarlos detrás del respaldo.
|
||||
|
||||
Después de un fallo de conexión o de un fallo temprano de WebSocket durante el turno en modo `"auto"`, OpenClaw marca
|
||||
la ruta WebSocket de esa sesión como degradada durante unos 60 segundos y envía los
|
||||
turnos posteriores por SSE durante el enfriamiento en lugar de alternar continuamente entre
|
||||
transportes.
|
||||
Después de un fallo de conexión de WebSocket o de un fallo al inicio del turno en modo `"auto"`, OpenClaw marca
|
||||
la ruta WebSocket de esa sesión como degradada durante unos 60 segundos y envía
|
||||
los turnos posteriores por SSE durante el enfriamiento en lugar de alternar
|
||||
constantemente entre transportes.
|
||||
|
||||
Para endpoints nativos de la familia OpenAI (`openai/*`, `openai-codex/*` y Azure
|
||||
OpenAI Responses), OpenClaw también adjunta estado estable de identidad de sesión y turno
|
||||
a las solicitudes para que los reintentos, las reconexiones y la alternativa SSE permanezcan alineados con la misma
|
||||
identidad de conversación. En las rutas nativas de la familia OpenAI, esto incluye encabezados estables de identidad de solicitud de sesión/turno más metadatos de transporte coincidentes.
|
||||
a las solicitudes para que los reintentos, las reconexiones y el respaldo con SSE permanezcan alineados con la misma
|
||||
identidad de conversación. En las rutas nativas de la familia OpenAI esto incluye encabezados estables de identidad de solicitud
|
||||
de sesión/turno, además de metadatos de transporte coincidentes.
|
||||
|
||||
OpenClaw también normaliza los contadores de uso de OpenAI entre variantes de transporte antes de
|
||||
que lleguen a las superficies de sesión/estado. El tráfico nativo de OpenAI/Codex Responses puede
|
||||
OpenClaw también normaliza los contadores de uso de OpenAI entre variantes de transporte antes de que
|
||||
lleguen a las superficies de sesión/estado. El tráfico nativo de OpenAI/Codex Responses puede
|
||||
informar el uso como `input_tokens` / `output_tokens` o
|
||||
`prompt_tokens` / `completion_tokens`; OpenClaw los trata como los mismos contadores de entrada
|
||||
y salida para `/status`, `/usage` y los registros de sesión. Cuando el tráfico nativo
|
||||
de WebSocket omite `total_tokens` (o informa `0`), OpenClaw recurre al total normalizado
|
||||
de entrada + salida para que las pantallas de sesión/estado sigan mostrando datos.
|
||||
y salida para `/status`, `/usage` y los registros de sesión. Cuando el tráfico nativo por
|
||||
WebSocket omite `total_tokens` (o informa `0`), OpenClaw recurre al total normalizado de entrada + salida
|
||||
para que las vistas de sesión/estado sigan mostrando datos.
|
||||
|
||||
Puedes establecer `agents.defaults.models.<provider/model>.params.transport`:
|
||||
|
||||
- `"sse"`: forzar SSE
|
||||
- `"websocket"`: forzar WebSocket
|
||||
- `"auto"`: probar WebSocket y luego usar SSE como alternativa
|
||||
- `"auto"`: intentar WebSocket y luego pasar a SSE
|
||||
|
||||
Para `openai/*` (API de Responses), OpenClaw también habilita el calentamiento de WebSocket de forma
|
||||
predeterminada (`openaiWsWarmup: true`) cuando se usa transporte WebSocket.
|
||||
Para `openai/*` (API de Responses), OpenClaw también habilita por defecto el calentamiento de WebSocket
|
||||
(`openaiWsWarmup: true`) cuando se usa transporte WebSocket.
|
||||
|
||||
Documentación relacionada de OpenAI:
|
||||
|
||||
- [Realtime API with WebSocket](https://platform.openai.com/docs/guides/realtime-websocket)
|
||||
- [Streaming API responses (SSE)](https://platform.openai.com/docs/guides/streaming-responses)
|
||||
- [Realtime API con WebSocket](https://platform.openai.com/docs/guides/realtime-websocket)
|
||||
- [Respuestas de API en streaming (SSE)](https://platform.openai.com/docs/guides/streaming-responses)
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -336,7 +338,7 @@ Documentación relacionada de OpenAI:
|
||||
La documentación de OpenAI describe el calentamiento como opcional. OpenClaw lo habilita de forma predeterminada para
|
||||
`openai/*` para reducir la latencia del primer turno cuando se usa transporte WebSocket.
|
||||
|
||||
### Desactivar el calentamiento
|
||||
### Deshabilitar el calentamiento
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -354,7 +356,7 @@ La documentación de OpenAI describe el calentamiento como opcional. OpenClaw lo
|
||||
}
|
||||
```
|
||||
|
||||
### Habilitar explícitamente el calentamiento
|
||||
### Habilitar el calentamiento explícitamente
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -372,11 +374,11 @@ La documentación de OpenAI describe el calentamiento como opcional. OpenClaw lo
|
||||
}
|
||||
```
|
||||
|
||||
### Procesamiento prioritario para OpenAI y Codex
|
||||
### Procesamiento prioritario de OpenAI y Codex
|
||||
|
||||
La API de OpenAI expone procesamiento prioritario mediante `service_tier=priority`. En
|
||||
OpenClaw, establece `agents.defaults.models["<provider>/<model>"].params.serviceTier`
|
||||
para reenviar ese campo en endpoints nativos de OpenAI/Codex Responses.
|
||||
para transmitir ese campo en los endpoints nativos de OpenAI/Codex Responses.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -401,19 +403,19 @@ para reenviar ese campo en endpoints nativos de OpenAI/Codex Responses.
|
||||
|
||||
Los valores admitidos son `auto`, `default`, `flex` y `priority`.
|
||||
|
||||
OpenClaw reenvía `params.serviceTier` tanto a solicitudes directas de Responses `openai/*`
|
||||
como a solicitudes de Codex Responses `openai-codex/*` cuando esos modelos apuntan
|
||||
OpenClaw reenvía `params.serviceTier` tanto a las solicitudes directas de `openai/*` Responses
|
||||
como a las solicitudes de `openai-codex/*` Codex Responses cuando esos modelos apuntan
|
||||
a los endpoints nativos de OpenAI/Codex.
|
||||
|
||||
Comportamiento importante:
|
||||
|
||||
- `openai/*` directo debe apuntar a `api.openai.com`
|
||||
- `openai-codex/*` debe apuntar a `chatgpt.com/backend-api`
|
||||
- si enrutas cualquiera de los dos proveedores mediante otra URL base o proxy, OpenClaw deja `service_tier` sin cambios
|
||||
- si enrutas cualquiera de los proveedores a través de otra URL base o proxy, OpenClaw deja `service_tier` intacto
|
||||
|
||||
### Modo rápido de OpenAI
|
||||
|
||||
OpenClaw expone un interruptor compartido de modo rápido tanto para sesiones `openai/*` como
|
||||
OpenClaw expone un interruptor compartido de modo rápido para sesiones tanto `openai/*` como
|
||||
`openai-codex/*`:
|
||||
|
||||
- Chat/UI: `/fast status|on|off`
|
||||
@ -421,12 +423,12 @@ OpenClaw expone un interruptor compartido de modo rápido tanto para sesiones `o
|
||||
|
||||
Cuando el modo rápido está habilitado, OpenClaw lo asigna al procesamiento prioritario de OpenAI:
|
||||
|
||||
- las llamadas directas de Responses `openai/*` a `api.openai.com` envían `service_tier = "priority"`
|
||||
- las llamadas de Responses `openai-codex/*` a `chatgpt.com/backend-api` también envían `service_tier = "priority"`
|
||||
- las llamadas directas de `openai/*` Responses a `api.openai.com` envían `service_tier = "priority"`
|
||||
- las llamadas de `openai-codex/*` Responses a `chatgpt.com/backend-api` también envían `service_tier = "priority"`
|
||||
- se conservan los valores existentes de `service_tier` en la carga útil
|
||||
- el modo rápido no reescribe `reasoning` ni `text.verbosity`
|
||||
|
||||
Para GPT 5.4 concretamente, la configuración más habitual es:
|
||||
Para GPT 5.4 en concreto, la configuración más común es:
|
||||
|
||||
- enviar `/fast on` en una sesión que use `openai/gpt-5.4` o `openai-codex/gpt-5.4`
|
||||
- o establecer `agents.defaults.models["openai/gpt-5.4"].params.fastMode = true`
|
||||
@ -455,49 +457,75 @@ Ejemplo:
|
||||
}
|
||||
```
|
||||
|
||||
Las anulaciones de sesión prevalecen sobre la configuración. Limpiar la anulación de sesión en la interfaz de Sessions
|
||||
Las anulaciones de sesión tienen prioridad sobre la configuración. Borrar la anulación de sesión en la UI de Sesiones
|
||||
devuelve la sesión al valor predeterminado configurado.
|
||||
|
||||
### Rutas nativas de OpenAI frente a rutas compatibles con OpenAI
|
||||
|
||||
OpenClaw trata los endpoints directos de OpenAI, Codex y Azure OpenAI de manera diferente
|
||||
a los proxies genéricos compatibles con OpenAI `/v1`:
|
||||
OpenClaw trata los endpoints directos de OpenAI, Codex y Azure OpenAI de forma diferente
|
||||
a los proxies `/v1` genéricos compatibles con OpenAI:
|
||||
|
||||
- las rutas nativas `openai/*`, `openai-codex/*` y Azure OpenAI mantienen
|
||||
`reasoning: { effort: "none" }` intacto cuando desactivas explícitamente el razonamiento
|
||||
- las rutas nativas de la familia OpenAI usan por defecto esquemas de herramientas en modo estricto
|
||||
`reasoning: { effort: "none" }` intacto cuando deshabilitas explícitamente el razonamiento
|
||||
- las rutas nativas de la familia OpenAI usan por defecto el modo estricto para los esquemas de herramientas
|
||||
- los encabezados ocultos de atribución de OpenClaw (`originator`, `version` y
|
||||
`User-Agent`) solo se adjuntan en hosts nativos verificados de OpenAI
|
||||
(`api.openai.com`) y hosts nativos de Codex (`chatgpt.com/backend-api`)
|
||||
- las rutas nativas de OpenAI/Codex mantienen el moldeado de solicitudes exclusivo de OpenAI, como
|
||||
- las rutas nativas de OpenAI/Codex mantienen el modelado de solicitudes exclusivo de OpenAI, como
|
||||
`service_tier`, `store` de Responses, cargas útiles de compatibilidad de razonamiento de OpenAI y
|
||||
pistas de caché de prompt
|
||||
sugerencias de caché de prompt
|
||||
- las rutas compatibles con OpenAI de estilo proxy mantienen el comportamiento de compatibilidad más flexible y no
|
||||
fuerzan esquemas estrictos de herramientas, moldeado de solicitudes exclusivo nativo ni encabezados ocultos
|
||||
fuerzan esquemas de herramientas estrictos, modelado de solicitudes exclusivo nativo ni encabezados ocultos
|
||||
de atribución de OpenAI/Codex
|
||||
|
||||
Azure OpenAI permanece dentro del grupo de enrutamiento nativo para el comportamiento de transporte y compatibilidad,
|
||||
Azure OpenAI permanece en el grupo de rutas nativas para el comportamiento de transporte y compatibilidad,
|
||||
pero no recibe los encabezados ocultos de atribución de OpenAI/Codex.
|
||||
|
||||
Esto preserva el comportamiento actual de Responses nativas de OpenAI sin forzar
|
||||
shims antiguos compatibles con OpenAI sobre backends `/v1` de terceros.
|
||||
Esto preserva el comportamiento actual de OpenAI Responses nativo sin forzar adaptadores compatibles con OpenAI más antiguos sobre backends `/v1` de terceros.
|
||||
|
||||
### Modo GPT agéntico estricto
|
||||
|
||||
Para ejecuciones de la familia GPT-5 de `openai/*` y `openai-codex/*`, OpenClaw puede usar un
|
||||
contrato de ejecución de Pi incrustado más estricto:
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
embeddedPi: {
|
||||
executionContract: "strict-agentic",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Con `strict-agentic`, OpenClaw ya no trata un turno del asistente que solo planifica como
|
||||
un progreso exitoso cuando hay disponible una acción concreta con herramienta. Reintenta el
|
||||
turno con una directiva para actuar ahora, habilita automáticamente la herramienta estructurada `update_plan` para
|
||||
trabajo sustancial y muestra un estado explícito de bloqueo si el modelo sigue
|
||||
planificando sin actuar.
|
||||
|
||||
Este modo se limita a ejecuciones de la familia GPT-5 de OpenAI y OpenAI Codex. Otros proveedores
|
||||
y familias de modelos anteriores mantienen el comportamiento predeterminado de Pi incrustado, a menos que los incorpores
|
||||
a otras configuraciones de tiempo de ejecución.
|
||||
|
||||
### Compactación del lado del servidor de OpenAI Responses
|
||||
|
||||
Para modelos directos de OpenAI Responses (`openai/*` usando `api: "openai-responses"` con
|
||||
`baseUrl` en `api.openai.com`), OpenClaw ahora habilita automáticamente pistas de carga útil
|
||||
`baseUrl` en `api.openai.com`), OpenClaw ahora habilita automáticamente las sugerencias de carga útil
|
||||
de compactación del lado del servidor de OpenAI:
|
||||
|
||||
- Fuerza `store: true` (a menos que la compatibilidad del modelo establezca `supportsStore: false`)
|
||||
- Inyecta `context_management: [{ type: "compaction", compact_threshold: ... }]`
|
||||
|
||||
De forma predeterminada, `compact_threshold` es el `70%` de `contextWindow` del modelo (o `80000`
|
||||
De forma predeterminada, `compact_threshold` es el `70%` del `contextWindow` del modelo (o `80000`
|
||||
cuando no está disponible).
|
||||
|
||||
### Habilitar explícitamente la compactación del lado del servidor
|
||||
|
||||
Úsalo cuando quieras forzar la inyección de `context_management` en modelos de
|
||||
Responses compatibles (por ejemplo Azure OpenAI Responses):
|
||||
Úsalo cuando quieras forzar la inyección de `context_management` en modelos
|
||||
Responses compatibles (por ejemplo, Azure OpenAI Responses):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -534,7 +562,7 @@ Responses compatibles (por ejemplo Azure OpenAI Responses):
|
||||
}
|
||||
```
|
||||
|
||||
### Desactivar la compactación del lado del servidor
|
||||
### Deshabilitar la compactación del lado del servidor
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -558,5 +586,5 @@ Los modelos directos de OpenAI Responses siguen forzando `store: true` a menos q
|
||||
|
||||
## Notas
|
||||
|
||||
- Las referencias de modelo siempre usan `provider/model` (ver [/concepts/models](/es/concepts/models)).
|
||||
- Los detalles de autenticación + reglas de reutilización están en [/concepts/oauth](/es/concepts/oauth).
|
||||
- Las referencias de modelo siempre usan `provider/model` (consulta [/concepts/models](/es/concepts/models)).
|
||||
- Los detalles de autenticación y las reglas de reutilización están en [/concepts/oauth](/es/concepts/oauth).
|
||||
|
||||
Loading…
Reference in New Issue
Block a user