Referencia del SDK
Toda la API de @beeuni/sdk: métodos del cliente, módulos, turnos y distribución.
Esta página recoge toda la superficie de la API de @beeuni/sdk: cada método del cliente, los
módulos independientes de frameworks, las utilidades de turnos y cómo se distribuye el paquete. Consulta
SDK para empezar y Sesiones para conocer a fondo el
ciclo de vida de las sesiones.
El cliente
createBeeuni(config) devuelve un cliente. Cada método es una llamada tipada a
la API de la plataforma. Los manejadores project(id) y session(pid, sid) vinculan los identificadores
para que nunca tengas que repetirlos.
const beeuni = createBeeuni({ backendUrl, getToken });
beeuni.accounts; // account / team operations
beeuni.accountInvites; // invite accept/decline by token alone
beeuni.projects; // top-level project operations
beeuni.connectors; // Connector calls scoped by an agent-minted token
beeuni.connector(slug); // one connector in the token's scope → see p.connector(slug)
beeuni.project(id); // id-bound project handle
beeuni.session(pid, sid); // id-bound session handle → see Sessions
beeuni.github; // GitHub App install + repo linking (account-scoped)
beeuni.gitBackend; // the instance git backend ("Beeuni managed")
beeuni.billing; // credits, subscription, tier, transactions
beeuni.sandboxShares; // public share links for a sandbox port
beeuni.connectStatus; // easy-connect status
beeuni.marketplace; // public marketplace catalog
beeuni.validateToken; // pasted-API-key check
beeuni.config; // platform config in effect
beeuni.runtime(); // runtime REST compatibility client
Cuentas — beeuni.accounts
| método | función |
|---|---|
list() · get(accountId) |
cuentas a las que perteneces · una cuenta |
create({ name }) · updateName(accountId, name) |
crear · renombrar una cuenta |
branding.get(accountId) · branding.update(accountId, { app_name }) · branding.uploadAsset(accountId, kind, file) · branding.removeAsset(accountId, kind) · branding.reset(accountId) |
identidad de marca de la organización (Enterprise): logotipo / icono / favicon y nombre de producto propios; kind es logo · icon · favicon, o logo_dark · icon_dark · favicon_dark para la variante del esquema oscuro |
members(accountId) · invite(accountId, input) |
listar miembros · invitar a uno |
updateMemberRole(accountId, userId, role) · removeMember(accountId, userId) |
asignar el rol de la cuenta · eliminar un miembro |
invites(accountId) |
invitaciones pendientes |
cancelInvite(accountId, inviteId) · resendInvite(accountId, inviteId) |
cancelar · reenviar una invitación pendiente |
leave(accountId) |
abandonar la cuenta |
accounts.tokens genera claves de API con alcance de cuenta (beeuni_pat_...). Consulta
Autenticación del SDK para conocer el modelo completo de tokens.
| método | función |
|---|---|
tokens.list(accountId?, options?) |
listar claves de API — las de toda la cuenta, o solo las tuyas con { mine: true } |
tokens.create(input) |
generar una — { accountId?, name, expiresAt?, projectId? } |
tokens.revoke(tokenId, accountId?) |
revocar una |
accounts.audit es el registro de reconstrucción empresarial. Combina solicitudes
autenticadas a la API con eventos semánticos de sesiones, conectores, aprobaciones y equipos.
| método | función |
|---|---|
audit.log(accountId, filters?) |
listar eventos por proyecto, sesión, actor, origen, resultado, solicitud, correlación, recurso, acción o tiempo |
audit.export(accountId, filters?) |
exportar el mismo flujo de eventos filtrado como CSV o JSONL |
audit.webhooks.list/create/update/remove(...) |
gestionar webhooks SIEM firmados para el flujo centralizado |
Cada evento incluye project_id, session_id, actor_type, source, outcome,
request_id, trace_id y correlation_id cuando la acción los proporciona.
La API no almacena cuerpos de solicitudes, prompts, secretos, credenciales ni argumentos
sin procesar de los conectores en el evento centralizado. Los eventos de conectores pueden incluir una
vista previa limitada de los argumentos que oculta campos con formato de credenciales y datos opacos.
Asignaciones de acceso
Beeuni tiene un único registro de concesión: una asignación. Vincula una entidad principal (user,
group, service_account o pending) a un rol, en un ámbito (account,
o un project), opcionalmente limitado a un objeto (agent, skill, secret,
app o trigger) y opcionalmente con un expires_at. El acceso de grupos,
el acceso por recurso y las vinculaciones de roles personalizados son todos asignaciones. Consulta
Cuentas y acceso para conocer el modelo.
La superficie REST canónica es:
| Método + ruta | Función |
|---|---|
GET /v1/accounts/{accountId}/iam/assignments |
listar asignaciones, filtradas por entidad principal, ámbito, objeto o rol |
POST /v1/accounts/{accountId}/iam/assignments |
crear una asignación |
DELETE /v1/accounts/{accountId}/iam/assignments/{assignmentId} |
revocar una asignación |
GET /v1/accounts/{accountId}/iam/permissions |
el catálogo de permisos, como datos |
GET /v1/accounts/{accountId}/iam/roles · …/roles/{roleId}/permissions |
roles · permisos de un rol |
El SDK los expone como listAssignments, createAssignment,
revokeAssignment y listPermissions. Una fila del catálogo contiene action,
scope_type, resource_type, delegable, description, area, level y
implies — léela en lugar de codificar de forma fija las cadenas de acciones.
Asignar un rol personalizado requiere que la cuenta tenga el derecho rbac; sin él, la ruta responde
402 con code: "entitlement_required".
Invitaciones a cuentas — beeuni.accountInvites
Se accede solo con el token de invitación — la persona invitada puede no ser miembro todavía.
| método | función |
|---|---|
listMine() |
todas las invitaciones pendientes y no caducadas dirigidas a tu correo electrónico, con el espacio de trabajo y los proyectos a los que dan acceso |
describe(inviteId) · accept(inviteId) · decline(inviteId) |
previsualizar · aceptar · rechazar una invitación |
Proyectos — beeuni.projects
| método | función |
|---|---|
list() · listForAccount(accountId) |
tus proyectos · proyectos de una cuenta |
get(id) · detail(id) |
resumen · detalles completos |
create(input) · createRepo(input) |
a partir de un repo_url existente · repositorio nuevo y vacío de GitHub |
provision(input) |
proyecto nuevo en un repositorio nuevo gestionado por Beeuni, inicializado con una plantilla de inicio — { name, account_id?, seed_starter?, starter_template?, marketplace_items?, source_item_id?, idempotency_key? } |
update(id, input) · archive(id) |
actualizar ajustes · archivar |
llmCatalog(id) · modelPicker(id) |
catálogo de modelos completo · compacto para un selector |
sandboxTemplates(id) · sandboxHealth(id) |
plantillas de compilación del sandbox · estado de la compilación |
sessions(id) · createSession(id, input?) |
listar sesiones visibles · crear una sesión |
provision crea un proyecto nuevo; no inicia el sandbox de un proyecto
existente. Inicia una sesión en su lugar — consulta Sesiones.
Envía idempotency_key cuando pueda haber un reintento — una recarga, una segunda pestaña o un
tiempo de espera agotado tras el que reintentaste. provision genera un repositorio gestionado completamente nuevo por llamada, así que
sin una clave todos esos casos crean proyectos duplicados reales. Reutiliza una clave para cada
intento de una misma creación lógica y las repeticiones devolverán el proyecto creado en el primer
intento (201, mismos project_id y push_token: null). La clave identifica el
intento, no la carga útil — reutilizarla con un name diferente devuelve el primer
proyecto e ignora el nuevo valor, así que genera una clave nueva para cada creación distinta.
Crear un segundo proyecto con el mismo nombre y sin clave sigue funcionando.
Una repetición que llega mientras la primera llamada aún está aprovisionando recibe 409 con
code: 'provision_in_flight' en lugar de un project_id que esa llamada aún podría
revertir. Reintenta con la misma clave.
project(id).sessions.list({ scope: 'project' }) es un inventario del ciclo de vida para
un solicitante con permisos de administrador de proyectos. Añade sesiones accesibles no disponibles, preparadas y eliminadas de forma lógica, con
metadatos de propiedad y estado de ejecución. Ambos ámbitos de listado omiten todas las sesiones que el
solicitante no puede abrir.
sessions.list y sessions.listPage también aceptan los filtros de jerarquía y
atribución. Sin ellos, la lista sigue siendo plana y no cambia.
| opción | función |
|---|---|
parent: 'root' |
Solo sesiones de nivel superior. Cada fila contiene child_count. |
parent: '<sessionId>' |
Las sesiones hijas de esa sesión, de más reciente a más antigua. |
startedBy: 'me' | 'others' | 'automated' |
Filtrar por initiator, en relación con el solicitante. |
q |
Búsqueda sin distinción entre mayúsculas y minúsculas por título, etiqueta de iniciador, slug de activador y prefijo del identificador de sesión, en todas las sesiones que el solicitante puede abrir. Con parent: 'root', una raíz que coincide a través de una sesión hija tiene search_match: 'child'. |
Cada fila de sesión tiene parent_session_id y initiator
({ type: 'member' | 'trigger' | 'channel' | 'api' | 'system', id, label }).
initiator indica quién inició toda la ejecución; una sesión hija copia el valor de su sesión padre.
sessionParentId(session) lee parent_session_id y después el valor heredado
metadata.spawned_by_session. Un cursor solo es válido para el conjunto de filtros que
lo emitió.
GitHub — beeuni.github
Instalación de GitHub App y vinculación de repositorios con alcance de cuenta, no de proyecto.
| método | función |
|---|---|
getInstallation(accountId) · listInstallations(accountId) |
instalación de esta cuenta · instalaciones a las que el usuario tiene acceso |
saveInstallation(input) · deleteInstallation(accountId, installationId?) |
registrar · desvincular una instalación |
listLinkableInstallations(input) |
instalaciones que el usuario autorizado de GitHub puede vincular; cada entrada incluye linked_to_other_accounts, el número de otras cuentas de Beeuni que la tienen, nunca sus nombres |
listRepositories(accountId, installationId?) · listRepositoryBranches(...) |
repositorios visibles para la instalación · ramas y la predeterminada de GitHub |
linkRepository(input) |
Importar un repositorio como proyecto mediante una instalación autorizada de GitHub. |
replaceProjectRepository({ project_id, repo_url, expected_repo_url, github_token }) |
sustituir el repositorio de GitHub de un proyecto existente. Usa github_token con acceso de lectura/escritura a Contents, o installation_id junto con github_user_token temporal para verificar el acceso de administrador de la organización y conceder acceso solo a este repositorio mediante la GitHub App. copy_shared_secrets_from_project_id junto con copy_shared_secret_identifiers copia los secretos compartidos de ejecución seleccionados en la misma transacción. Un expected_repo_url desactualizado devuelve 409. El repositorio anterior permanece en GitHub. Las sesiones nuevas usan el repositorio de sustitución; las existentes conservan su copia de trabajo. |
Esta lista contiene solo conexiones reales de cuentas. “Beeuni managed” no es una de ellas: es el backend de la instancia que se describe a continuación.
Backend de git de la instancia — beeuni.gitBackend
Un único propietario y una credencial para todo el despliegue, usados para los repositorios
administrados por Beeuni. Nunca es una conexión de cuenta ni aparece en
beeuni.github.listInstallations.
| método | función |
|---|---|
get() |
{ configured, kind: 'app' | 'pat' | null, owner } — cualquier usuario autenticado puede leerlo; solo expone el nombre de usuario del propietario que ya incluye cada repo_url administrado |
Facturación — beeuni.billing
Consulta créditos, suscripción, plan e historial de transacciones. Usa el pago y la gestión de facturación de Beeuni para gestionar pagos y compras de créditos.
| método | función |
|---|---|
accountState(accountId?) · accountStateMinimal(accountId?) |
estado de facturación completo · mínimo |
transactions(params?) · transactionsSummary(params?) |
historial · totales resumidos |
creditBreakdown(accountId?) · usageHistory(params?) |
saldo de créditos por origen · uso a lo largo del tiempo |
sessionCosts.list(options?) · sessionCosts.get(sessionId, options?) |
registros paginados de costes de sesiones · registro detallado de una sesión |
tierConfigurations() |
niveles de plan disponibles |
checkout.createSession(input) · checkout.confirmSession(sessionId, accountId?) |
Obsoletos. Rechazan con ENDPOINT_RETIRED. Se eliminarán en la próxima versión principal. |
subscription.createPortalSession(...) · subscription.cancel(...) · subscription.reactivate(...) |
abrir el portal del cliente · cancelar · reactivar |
subscription.cancelScheduledChange(...) · prorationPreview(...) |
cancelar · previsualizar un cambio de plan |
subscription.scheduleDowngrade(...) |
Obsoleto. Rechaza con ENDPOINT_RETIRED. Cambia el plan en el portal del cliente. Se eliminará en la próxima versión principal. |
credits.purchase(input) · credits.autoTopupSettings(...) · credits.configureAutoTopup(...) |
compra puntual · consultar · configurar la recarga automática |
sessionCosts.list() acepta accountId, projectId, limit y offset.
Cada fila combina el coste definitivo del LLM y el coste facturado de cómputo del sandbox.
sessionCosts.get() añade el uso del modelo y el registro desglosado de LLM/cómputo.
La lista incluye un total de conciliación de los costes sin sesión.
Enlaces compartidos del sandbox — beeuni.sandboxShares
Enlaces públicos para compartir un puerto expuesto del sandbox. Su ámbito es el sandbox, no el proyecto.
| método | función |
|---|---|
list(sandboxId) |
enlaces compartidos activos |
create(input) |
crear uno — { sandboxId, port, ttl?, label? } |
revoke(sandboxId, token) |
revocar uno |
Catálogo del marketplace — beeuni.marketplace
Exploración del catálogo público, de solo lectura; distinta de project(id).marketplace,
que instala un elemento en un proyecto.
| método | función |
|---|---|
items(options?) · item(id) · itemFile(id, path) |
explorar · un elemento · un archivo dentro de un elemento |
marketplaces() · featured() |
todos los marketplaces · destacados |
sources.list() · sources.add(input) · sources.remove(id) |
listar · añadir · eliminar una fuente |
Notificaciones — beeuni.notifications
Las notificaciones del invocador, en todas las cuentas y proyectos. Cada persona con sesión iniciada
tiene una bandeja de entrada, un registro de preferencias y suscripciones Web Push para
sus navegadores. Todos los métodos requieren la credencial de una persona: una cuenta de servicio
recibe 403.
const page = await beeuni.notifications.list({ limit: 20 });
await beeuni.notifications.markRead({ ids: [page.notifications[0].id] });
await beeuni.notifications.updatePreferences({ kinds: { turn_done: { push: false } } });
| método | función |
|---|---|
list({ limit?, before? }, { signal? }) |
la página más reciente: { notifications, unread_count, next_before }. limit va de 1 a 50 (20 por defecto). Pasa next_before como before para la página siguiente. Se omiten las filas que el invocador ya no puede ver. Un fallo no llama al gestor de errores del host. |
markRead({ ids }) · markRead({ all: true }) · markRead({ sessionId }) |
marcar como leídas de 1 a 100 filas, todas las filas o todas las filas de una sesión. Solo modifica las filas del invocador. Devuelve { updated, unread_count }. |
preferences() · updatePreferences({ kinds }) |
consultar · cambiar la elección de push y correo por tipo. Devuelve { kinds, email_available }. Un parche solo modifica los tipos y canales que especifica. |
webPushPublicKey() |
{ public_key }: el applicationServerKey para pushManager.subscribe |
registerWebPushSubscription({ endpoint, keys }) |
enviar notificaciones push a este navegador. Requiere iniciar sesión en el navegador: un token personal recibe 403. Un endpoint de un servicio push desconocido recibe 400. |
unregisterWebPushSubscription(endpoint, { signal? }) |
dejar de enviar notificaciones push a este navegador. Devuelve { deleted }. |
registerDeviceToken(input) · unregisterDeviceToken(token, { signal? }) |
registrar · eliminar el token push de Expo de una aplicación nativa |
Tipos (InboxNotificationKind, enumerados en INBOX_NOTIFICATION_KINDS):
| tipo | se envía cuando | push | correo (por defecto) |
|---|---|---|---|
turn_done |
termina un turno que solicitaste o sigues | activado | desactivado |
turn_error |
ese turno termina con un error | activado | activado, en un resumen |
question |
el agente hace una pregunta | activado | activado, en un resumen |
permission |
el agente solicita permiso | activado | desactivado |
shared |
alguien comparte una sesión contigo | activado | activado, en un resumen |
automation_failed |
una automatización que sigues empieza a fallar | activado | activado, de inmediato |
automation_recovered |
esa automatización vuelve a funcionar | activado | desactivado |
DEFAULT_NOTIFICATION_PREFERENCES contiene estos valores predeterminados. La fila de la bandeja de entrada
siempre se crea; las preferencias solo determinan las notificaciones push y el correo. Un correo de resumen
incluye las filas que siguen sin leerse 15 minutos después de llegar, con un máximo de un resumen
por hora. Oculta la columna de correo cuando email_available sea false.
El url de cada fila abre su tema. Su parámetro de consulta ?notification=<id> permite que la
página marque la fila como leída.
El identificador de sesión mantiene el seguimiento del invocador de una sesión:
| método | función |
|---|---|
session(pid, sid).watch() |
{ watching }: si el invocador recibe notificaciones de esta sesión |
session(pid, sid).setWatch(watching) |
false silencia la sesión para el invocador, true vuelve a seguirla. Enviar una instrucción a una sesión activa su seguimiento, pero nunca deshace el silencio. |
session(pid, sid).presence({ tab_id, active, alerts? }, { keepalive? }) |
concesión de presencia de esta pestaña. alerts: true indica que la pestaña muestra sus propias notificaciones: con notification_center activado, el servidor omite las notificaciones al teléfono y Web Push solo mientras se usa una pestaña que muestra alertas. Si está desactivado, se ignora alerts y cualquier pestaña presente retiene las notificaciones push al teléfono. keepalive permite que la solicitud continúe tras cerrar una página. Por defecto: activado para un informe de ausencia, desactivado para uno de presencia. useSession envía keepalive solo con presencePageExit. |
El identificador de proyecto — beeuni.project(id)
Vincula el id del proyecto; todos los subrecursos dependen de él.
const p = beeuni.project(projectId);
await p.detail();
await p.update({ name });
await p.llmCatalog();
| método | función |
|---|---|
get · detail · update · archive |
leer · detalles completos · actualizar · archivar |
llmCatalog · modelPicker · sandboxHealth |
lecturas del modelo y de la compilación del sandbox |
onboardingComplete |
marcar la incorporación al proyecto como completada |
validateManifest(raw) |
validar un manifiesto beeuni.yaml (o el antiguo beeuni.toml) en el servidor |
gitToken() |
generar un nuevo token de git push con alcance limitado (409 para un repositorio propio) |
setAgentScope(agentName, scope) |
establecer los secretos y conectores permitidos de un agente en el manifiesto: la segunda vinculación, no un rol |
p.tokens — claves de API con alcance de proyecto
Se generan automáticamente al crear una sesión como BEEUNI_TOKEN; también pueden generarse manualmente.
| método | función |
|---|---|
list() |
claves de API del proyecto |
create(input?) |
generar una nueva |
revoke(tokenId) |
revocar una |
p.setupLinks — enlaces de configuración generados por agentes
Un enlace que una persona abre para introducir un secreto o conectar una aplicación, sin acceso completo al proyecto.
| método | función |
|---|---|
requestSecret(input) · requestConnector(input) |
enlace para recopilar un secreto · conectar una aplicación |
p.apps — Apps (versiones, máquinas, volúmenes)
Depende de la función de proyecto apps. Guía: SDK → Apps.
| método | función |
|---|---|
list() · get(appId) · create(input) · update(appId, input) · remove(appId) |
inventario y ciclo de vida; create acepta uses, update también acepta labels |
deployments.* · artifacts.* · access.* · rollback · start · stop |
despliegues, artefactos, política de acceso, tráfico y entorno de ejecución |
machines.list/start/stop/restart/destroy · scale(appId, count) · exec(appId, input) |
máquinas por grupo de procesos; exec necesita project.app.admin |
volumes.list/create/update/destroy/snapshots/snapshot/restore/fork |
volúmenes persistentes, instantáneas diarias, restauración, bifurcación |
token(appId) |
un token de inicio de sesión de 15 minutos; 409 app_capability_unsupported sin member_tokens |
p.secrets — secretos del proyecto
| método | función |
|---|---|
list() · upsert(input) |
listar metadatos · crear o actualizar un valor de solo escritura y una política de entrega |
setStrategy(identifier, strategy, options?) |
cambiar la exposición y su lista de hosts |
broker(identifier, request) |
ejecutar una solicitud HTTPS autorizada por la sesión y sujeta a una política |
remove(identifier) |
eliminar un secreto |
setPersonal(name, value) · removePersonal(name) |
establecer · eliminar una anulación por usuario |
setGitCredential(input) |
establecer una credencial de autenticación de git |
runtime con el consumidor sandbox es la exposición de entorno: la predeterminada,
y la única política que coloca un valor en texto plano en la sesión. egress con
el consumidor network es la exposición controlada a la salida: la sesión conserva un identificador
y Beeuni sustituye el valor real fuera del sandbox, para los hosts HTTPS exactos
que enumera la política. La exposición controlada a la salida es experimental; necesita la
marca de función secrets_egress (Settings → Feature flags). Con la marca desactivada,
setStrategy(identifier, 'egress', …) y upsert(...) con una política de salida
devuelven 403 feature_disabled. Ningún consumidor broker tiene presencia
alguna en la sesión. Consulta
Secretos. El método broker(...) requiere un
token con alcance de sesión y un identificador de sesión activo.
p.access — asignaciones, invitaciones y solicitudes del proyecto
Cada método aquí lee o escribe una asignación con alcance limitado a este proyecto. Los roles
del proyecto son manager y member.
| método | función |
|---|---|
list() · invite(email, role) |
entidades con acceso · invitar a un usuario |
update(userId, role) · revoke(userId) |
asignar un rol de proyecto · revocar la asignación |
pendingInvites() · requests() |
invitaciones pendientes · solicitudes de acceso pendientes |
resendInvite(inviteId) · revokeInvite(inviteId) · approveRequest(id) · rejectRequest(id) |
reenviar/revocar una invitación · aprobar/rechazar una solicitud |
groupGrants() · attachGroupGrant(...) · updateGroupGrant(...) · detachGroupGrant(...) |
las mismas asignaciones, con una entidad group |
p.access.resourceGrants es la vista de asignación de objetos: limita una
entidad a un objeto del proyecto en lugar de a todo el proyecto. Actualmente, Beeuni
aplica las asignaciones de objetos a agentes y habilidades. Un agente está cerrado por
defecto: un miembro solo puede acceder a él cuando una asignación lo nombra a él o a uno de sus
grupos. Una asignación de objeto no incluye permisos propios y restringe a un
gestor del proyecto tanto como a un miembro.
| método | función |
|---|---|
resourceGrants.list() |
asignaciones de objetos en este proyecto |
resourceGrants.create(input) |
asignar un objeto a un usuario o grupo |
resourceGrants.remove(grantId) |
revocar una asignación de objeto |
p.connector(slug) — un conector
| método | función |
|---|---|
run(action, args, options?) |
la salida de la acción; lanza ConnectorCallError o ConnectorApprovalPendingError — consulta Errores |
call(action, args, options?) |
el resultado sin procesar de la llamada; 202 se resuelve con ok: false |
describe() · describe(action) |
el conector con esquemas de entrada y salida · una acción |
accounts() |
las cuentas con las que quien hace la llamada puede ejecutarlo, la predeterminada primero |
paginate(action, args, { next, maxPages? }) |
iterador asíncrono sobre la salida de cada página; lanza ConnectorPageLimitError con nextArgs cuando hay más de maxPages páginas (100 por defecto) — consulta Páginas |
uploadAttachment(content, input) |
p.connectors.uploadAttachment con connector establecido en este slug |
options: account, approvalContext, timeoutMs (90 000 por defecto), signal. Con el archivo de beeuni connectors types, los argumentos y la salida tienen tipos definidos.
p.connectors — conectores de herramientas
| método | función |
|---|---|
catalog() · tools() |
catálogo de Connector invocables · herramientas <connector>.<action> aplanadas |
search(query, options?) · describe(tool) |
buscar · inspeccionar una herramienta invocable |
call(tool, args?, options?) |
llamar a una herramienta <connector>.<action> a través de la pasarela del servidor. options.account indica con qué cuenta ejecutarla — consulta más abajo. |
accounts(slug) |
las cuentas con las que quien hace la llamada puede invocar slug, la predeterminada primero — con las que se compara options.account |
uploadAttachment(content, input) |
preparar bytes para input.connector; devuelve ref ({ $beeuni_attachment }) para incluirlo en los argumentos de una llamada posterior — consulta Adjuntar archivos |
list() · config(connectorId) |
conectores configurados · configuración de un conector |
create(input) |
añadir un conector |
auth.discover(input) |
previsualizar la autenticación a partir de una especificación OpenAPI, una colección Postman o un endpoint |
remove(connectorId) · sync() |
eliminar un conector · resincronizar conectores |
setName(connectorId, name) · setSensitive(connectorId, sensitive) |
renombrar · marcar como sensible (control de aprobación adicional) |
setAuthorizationStrategy(slug, strategy) |
@deprecated. Sigue llamando a la ruta; la ruta no realiza ninguna operación, responde {ok:true, deprecated:true} y no cambia nada. Ahora owner_type en cada conexión constituye toda la regla de acceso. |
setCredentialMode(connectorId, mode) · setCredential(connectorId, input) |
cambiar el origen · establecer el valor de la credencial |
policies.get(connectorId) · policies.set(connectorId, policies) |
leer · reemplazar sus políticas de herramientas |
connections.list() · connections.reconcile(input) |
listar · crear/actualizar cuentas conectadas |
connections.updateCredential(connectionId, input) |
rotar una credencial de conexión |
connections.revoke(connectionId) · connections.activate(connectionId) |
denegar · restablecer una conexión |
connections.setDefault(connectionId) |
establecerla como predeterminada para el ámbito de su propietario |
connections.rename(connectionId, label) |
cambiar solo la etiqueta; la cuenta sigue autorizada. Cada conexión incluye connected_as, la identidad con la que se autorizó. |
p.connectors.discover permite explorar el catálogo de conectores directos. Es experimental y está desactivado por defecto: actívalo por proyecto en Settings → Feature flags → “Connectors API Discover”. Easy Connect sigue siendo el mercado de conectores predeterminado.
| método | función |
|---|---|
discover.list(query?, cursor?) · discover.detail(id) |
buscar entradas OpenAPI/MCP/GraphQL/CLI · detalles de una entrada |
p.connectors.pipedream es la vía de compatibilidad de OAuth gestionado anterior; listApps
solo devuelve aplicaciones OAuth. Usa Easy Connect para nuevas integraciones gestionadas. Conecta directamente las aplicaciones que usan claves API.
| método | función |
|---|---|
pipedream.listApps(params?) · pipedream.connect(input) · pipedream.finalize(input) |
explorar el catálogo de aplicaciones · iniciar un flujo de conexión · finalizarlo |
Un conector define la herramienta, la aplicación del proveedor y las políticas. connections
almacena sus cuentas conectadas: un conector puede contener varias a la vez.
Una sesión puede fijar una para todas las llamadas con
connector_bindings: { alias: { connection_id } }, o una llamada individual puede indicar
una con call(tool, args, { account }). Las credenciales permanecen cifradas y
se resuelven en cada solicitud.
connections es la única fachada de autorización activa. Los nombres retirados
authorizations y profiles no forman parte de la interfaz actual del SDK.
Cuentas y control de acceso al realizar la llamada
Cada conexión tiene un owner_type: project (compartida: accesible para cualquiera
a quien se conceda acceso al conector, ya sea una persona o una cuenta de servicio) o member (privada:
accesible solo para su propietario, y solo en una sesión privada; nunca para una
cuenta de servicio). Una cuenta compartida puede restringirse a grupos y personas:
connections.list() devuelve sus permisos en shared_with, y
connectionSharedWithEveryone(connection) indica si todos los miembros del
proyecto pueden usarla. Una cuenta restringida sigue las reglas de las cuentas privadas para las
personas que especifica, y usable: false marca una cuenta que quien realiza la llamada solo puede ver para administrarla.
Concede o revoca acceso con createAssignment / revokeAssignment
(object: { type: 'connection', id }); consulta
Elegir quién puede usar una cuenta compartida.
p.connectors.accounts(slug) enumera todas las cuentas a las que puede acceder quien realiza la llamada,
con la predeterminada en primer lugar:
const accounts = await beeuni.project(projectId).connectors.accounts('stripe-read');
// [{ connection_id, label, owner_type, is_default }, ...]
await beeuni.project(projectId).connectors.call(
'stripe-read.get_balance',
{},
{ account: 'My Stripe' }, // a connection id, a label, or the words `me` / `project`
);
Una llamada que no indique ninguna cuenta se resuelve primero a la cuenta privada predeterminada
de quien la realiza y, después, a la cuenta compartida predeterminada del proyecto. Si una cuenta indicada
no se resuelve, la llamada se deniega con connector_not_connected; nunca
se sustituye silenciosamente, y la denegación enumera requested_account y
available_accounts. Cada llamada correcta devuelve la cuenta con la que se ejecutó:
result.account = { connection_id, label, owner_type }.
Ya no hay un control de acceso a conectores al crear una sesión. Antes se
rechazaba una sesión con 409 CONNECTOR_CONNECTION_REQUIRED cuando un conector obligatorio no tenía una
conexión utilizable; ese rechazo se ha eliminado (require_connectors no tiene efecto; consulta
p.sessions). El control se ha trasladado a la
llamada: una connector_not_connected denegada incluye connect_url, un enlace de
autorización alojado, siempre que se pueda generar para quien realiza la llamada. La solución
requiere un solo clic y se muestra mediante el botón de conexión de la transcripción.
p.policies — políticas del proyecto
| método | función |
|---|---|
list() · set(policies) |
las políticas del proyecto · sustituir el conjunto |
p.triggers — automatizaciones de cron, webhook, monitor y eventos
Un disparador inicia una acción del agente según una programación, un webhook entrante, un comando supervisado o un evento de aplicación en un conector. Consulta Disparadores para conocer la estrategia de sesión y las plantillas de carga útil.
| método | función |
|---|---|
list() |
todos los disparadores |
eventTypes({ connector }) |
los eventos de aplicación que pueden activar un disparador en un conector ({ provider, app, event_types }); 404 para un conector desconocido, 409 event_source_unavailable cuando su proveedor no tiene una fuente de eventos |
create(input) |
crear uno |
update(triggerId, input) |
editar un disparador |
remove(triggerId) |
eliminar un disparador |
fire(triggerId) |
ejecutarlo ahora |
setActivation(paused) |
pausar o reanudar todos los disparadores del proyecto |
create(input) acepta { name, type: 'cron' | 'webhook' | 'monitor' | 'event', prompt_template, slug?, agent?, model?, enabled?, session_mode?, session_id?, cron?, run_at?, timezone?, secret_env?, connector?, event?, event_source?, event_account?, event_config?, session_access? }. name and prompt_template son obligatorios.
cron/run_at son mutuamente excluyentes (type: 'cron'); secret_env (el
secreto HMAC del webhook) se aplica a type: 'webhook'.
Un disparador event necesita connector (el slug de un conector) y event (un identificador de tipo
de eventTypes). event_account es opcional: la etiqueta de una cuenta compartida de
ese conector; null o su omisión utiliza la cuenta compartida predeterminada del conector.
event_source es opcional: el identificador del adaptador de la fuente de eventos, como composio. null o su omisión utiliza el
proveedor del conector. El identificador de tipo pertenece a ese adaptador. La estructura de event_config viene determinada por el config_schema de ese tipo.
eventTypes y eventApps indican el adaptador como source; provider es un alias obsoleto.
Cada disparador enumerado incluye event: { connector, account, connected_as, type, config, source, provider, app, status: 'active' | 'needs_connection' | 'error' | 'pending', error, last_event_at } | null. Las plantillas de instrucciones leen el evento como
{{ event.data.<field> }} junto con event.id, event.type, event.app,
event.connector y event.occurred_at.
session_access controla quién puede abrir las sesiones que crea el disparador. Es
{ mode: 'private' | 'members' | 'project', memberIds: string[], groupIds: string[] } and defaults to private. Esta política es un estado de ejecución
local de la cuenta. No se incluye en el manifiesto portátil beeuni.yaml. Actualizar solo
session_access no crea ningún commit de Git. Una sesión fijada conserva sus propios ajustes
para compartir. Un administrador del proyecto siempre puede abrir las sesiones creadas por disparadores, incluidas
las que usan private o acceso para miembros seleccionados.
session_access es un ajuste de visibilidad por recurso que se añade al modelo de roles,
no un rol. Decide quién puede abrir las sesiones de un disparador. No concede ningún
permiso que la evaluación del rol deniegue. Consulta
Cuentas y acceso.
p.marketplace / p.registry — elementos instalados
Instala los archivos de un elemento del catálogo en la rama predeterminada del proyecto.
registry.* es un alias idéntico de marketplace.*.
| método | función |
|---|---|
marketplace.list() · marketplace.install(id) |
elementos instalados · instalar un elemento del catálogo |
marketplace.updates() · marketplace.update(name) · marketplace.updateAll() |
actualizaciones disponibles · actualizar uno · actualizar todos |
marketplace.remove(name) |
desinstalar un elemento |
p.files — archivos del repositorio (lectura)
Acceso de solo lectura al árbol de Git del proyecto. Para leer y escribir archivos dentro de una sesión en ejecución, usa las operaciones de archivos de la sesión; consulta Archivos en Módulos más abajo.
| método | función |
|---|---|
listDirectory({ ref?, path? }) |
un nivel de carpeta: { entries: [{ path, type, size? }], truncated }. Úsalo para construir un árbol; cada carpeta está completa hasta 5.000 entradas. |
list(options?) · read(path, ref?) |
todos los archivos de una ruta, de forma recursiva, con un límite de 1.000 (la respuesta incluye X-Beeuni-Truncated: 1 cuando se trunca) · el contenido de un archivo en una referencia de Git |
search(query, { content?, ref?, limit? }) |
buscar nombres de archivo en todo el repositorio, o contenido con content: true |
archive(options?) · history(path) |
descargar un archivo tar · el historial de Git de un archivo |
p.git — historial
| método | función |
|---|---|
commits() |
el registro de commits |
commit(sha) · commitDiff(sha) |
un commit · sus diferencias |
branches() · versionDiff(from, to) |
ramas · diferencias entre dos referencias |
p.changeRequests — ciclo de vida y fusión
Una solicitud de cambio (CR) permite fusionar el trabajo de una sesión en la rama predeterminada.
| método | función |
|---|---|
list() · get(crId) |
CR abiertas · una CR |
diff(crId) · mergePreview(crId) |
sus diferencias · previsualizar el resultado de la fusión |
open(input) · merge(crId, input?) |
abrir · fusionar una CR |
close(crId, input?) · reopen(crId, input?) |
cerrar sin fusionar · reabrir una cerrada |
requestChanges(crId, input) |
registrar comentarios, que opcionalmente se envían a la sesión de origen |
p.sessions — y el identificador de sesión
| método | función |
|---|---|
list() |
las sesiones del proyecto |
create(input?) |
crear una sesión |
session(sid) |
el manejador de sesión (igual que beeuni.session(id, sid)) |
El manejador de sesión es el núcleo del entorno de ejecución — consulta Sesiones.
create(input) acepta connector_bindings con claves basadas en el slug de conexión del conector.
Cada valor identifica un connection_id. También acepta secrets para
restringir los secretos originados en el backend. require_connectors está obsoleto y
no tiene efecto: el campo se sigue aceptando (nunca se rechaza un cliente antiguo por
enviarlo), pero nada lo lee — nunca se rechaza una sesión al crearla
por un conector sin una cuenta utilizable. Consulta Cuentas y el control en el momento de la llamada.
p.approvals — bandeja de aprobaciones de conectores
Acciones sujetas al control de conectores pendientes de una decisión — sustenta la
experiencia de aprobación de permisos (APPROVE / ASK / BLOCK).
| método | función |
|---|---|
list(options?) · sessionsNeedingInput(options?) |
aprobaciones pendientes · sesiones bloqueadas a la espera de una decisión |
resolve(executionId, decision, scope?) |
aprobar o denegar una — decision: 'approve' | 'deny', scope: 'once' | 'session' | 'session_all' |
p.gateway — observabilidad de LLM
Registros de solicitudes, agregados de costes/latencia, presupuestos y claves de API de la pasarela para el tráfico de modelos de este proyecto.
| método | función |
|---|---|
logs(opts?) · log(logId) |
entradas del registro de solicitudes · una entrada del registro |
overview(days?) · series(days?) · breakdown(days?) · sessions(days?) · errors(days?) |
agregados, coste por sesión y errores en un intervalo |
budgets() · setBudget(input) · deleteBudget(budgetId) |
leer · crear/editar · eliminar un presupuesto |
keys() · createKey(name) · revokeKey(keyId) |
listar · emitir · revocar una clave de API de la pasarela |
playground(prompt, models) |
ejecutar un prompt en hasta 6 modelos |
routing.get() · routing.set(policy) · routing.reset() |
leer · reemplazar · heredar la política de enrutamiento |
routing.preview(input) |
resolver una ruta sin invocar un modelo |
Una política de enrutamiento contiene un modelo predeterminado, un modelo de visión y una cadena
ordenada de alternativas; cada modelo se intenta como máximo una vez. fallbackOn es
transient o any-error.
La pasarela pasa al siguiente modelo alternativo solo cuando el modelo actual falla antes de devolver cualquier salida:
transient: un error de red, un tiempo de espera agotado, cualquier5xx, o402,403,429.any-error: cualquier fallo, incluido un400.
Un fallo después de que empiece la salida permanece en ese modelo. Una solicitud con tu propia clave de proveedor (BYOK) nunca recurre a un modelo facturado por Beeuni. Cada modelo alternativo recibe sus propios valores predeterminados de generación.
p.channels — Slack / correo electrónico / voz
Interfaces de conectores que permiten a un agente actuar como una aplicación de Slack, una dirección de correo electrónico o unirse a una llamada de voz en tiempo real.
| método | función |
|---|---|
slack.installation() · slack.mode() · slack.manifest() |
instalación actual · modo · manifiesto de la aplicación |
slack.connect(input) · slack.disconnect() |
conectar · desconectar |
slack.getFile(url) · slack.uploadFile(input) |
descargar · subir un archivo a través del proxy del servidor |
email.installation(connectorSlug?) · email.mode() |
instalación actual · modo |
email.connect(input) · email.disconnect(...) · email.updatePolicy(input) |
conectar · desconectar · actualizar la política de envío/respuesta |
voice.setBotName(name) |
cambiar el nombre del bot en una llamada en curso |
p.modelDefaults — preferencias de modelo predeterminado
Valores predeterminados de modelo a nivel de cuenta, agente y proyecto, resueltos por la pasarela.
| método | función |
|---|---|
get() · set(input) · clear(params) |
leer · establecer un valor predeterminado · borrar una anulación |
p.setDefaultAgent — agente predeterminado del proyecto
p.setDefaultAgent(agentName) comprueba que el agente esté declarado y habilitado,
y luego lo establece como default_agent en el beeuni.yaml del proyecto. Las sesiones nuevas
prefieren este agente salvo que un usuario elija otro.
p.updateFeatureFlag — indicadores de funcionalidades
p.updateFeatureFlag(feature, enabled) activa o desactiva un indicador de funcionalidad para el
proyecto. Pasa enabled: null para borrar la anulación y usar el
valor predeterminado de la plataforma. Llama al PATCH /v1/projects/:id/features canónico.
feature es uno de los FEATURE_FLAG_KEYS (exportados desde @beeuni/sdk, con el tipo
FeatureFlagKey). Quien realiza la llamada necesita el permiso project.settings.write del proyecto;
de lo contrario, la ruta responde con 403.
Todas las rutas controladas por indicadores rechazan las solicitudes del mismo modo mientras el indicador está desactivado: HTTP 403
con { error, code: "feature_disabled", feature }. Usa isFeatureDisabledError(error)
para bifurcar según este valor y featureDisabledKey(error) para leer la clave del indicador — nunca
hagas comparaciones con el texto del mensaje.
p.updateExperimentalFeature(feature, enabled) es el alias obsoleto.
Sigue llamando al alias de ruta obsoleto PATCH /v1/projects/:id/experimental
para que los consumidores fijados a una API desplegada más antigua sigan funcionando. Usa
p.updateFeatureFlag en el código nuevo.
p.sandbox — plantillas y compilaciones de instantáneas
Configuración de compilación de entornos aislados más allá de sandboxHealth/sandboxTemplates en el
manejador del proyecto: plantillas de Dockerfile/imagen/pool precalentado y sus compilaciones de instantáneas.
| método | función |
|---|---|
list() · snapshots() |
entornos aislados de este proyecto · instantáneas compiladas |
rebuildSnapshot(slug?) · fixWithAgent() |
recompilar una instantánea · pedir a un agente que corrija una compilación fallida |
createTemplate(input) · updateTemplate(...) · removeTemplate(...) · buildTemplate(...) |
añadir · editar · eliminar · compilar una plantilla |
setProvider(provider) |
solicitar un cambio de proveedor. null (o el valor predeterminado de la plataforma / el proveedor ya activo) se aplica inmediatamente; cambiar a otro proveedor habilitado inicia una transición duradera de preparar→verificar→activar — el proveedor actual sigue prestando servicio mientras se compila y verifica la imagen precalentada de destino, que después se activa. El valor devuelto es una unión etiquetada: kind:'project' (inmediato) o kind:'preparation' (consultar periódicamente getProjectSandboxProviderTransition() hasta activated/failed) |
Hooks de administración de la plataforma (@beeuni/sdk/react)
Estos hooks sirven a la consola de administración. La API solo responde a ellos para un administrador
de la plataforma. Cada mutación invalida las consultas ['admin', 'accounts'].
| Hook | Qué hace |
|---|---|
useAdminRole(userId, options?) |
leer el rol de quien realiza la llamada desde GET /user-roles → { isAdmin, role }. userId define la clave de caché. La ausencia de userId deshabilita la consulta. Vuelve a consultar al montar y al recibir el foco, por lo que un rol revocado deja de controlar el acceso en una sola navegación. |
useAdminGrantCredits() |
mutación { accountId, amount, description, isExpiring }: añadir crédito al monedero. POST /admin/api/accounts/:id/credits. Mueve dinero: confirmar primero en la interfaz. |
useAdminDebitCredits() |
mutación { accountId, amount, description }: retirar crédito del monedero. POST /admin/api/accounts/:id/credits/debit. Mueve dinero: confirmar primero en la interfaz. |
useAdminSetTier() |
mutación { accountId, tier }: establecer el nivel del plan. |
useAdminGrantTrial() |
mutación { accountId, tierKey, seats, durationDays, creditGrant?, note? }: conceder o reemplazar un periodo de prueba. La cuenta se comporta como tierKey hasta que termina el periodo. creditGrant también añade crédito al monedero. |
useAdminRevokeTrial() |
mutación { accountId }: finalizar ahora un periodo de prueba activo. Responde con 400 cuando no hay ninguno activo. |
Vía de escape
beeuni.runtime() devuelve el cliente REST tipado de runtime para el entorno
aislado activo.
En un cliente creado por createScopedBeeuni (@beeuni/sdk/server), lanza una excepción
— el entorno de ejecución “activo” global del proceso es el entorno aislado de otra solicitud en un
servidor multiinquilino, lo que supone una filtración entre inquilinos. Usa en su lugar
beeuni.session(pid, sid).runtime, limitado a la sesión (llama primero a ensureReady()), que
resuelve el entorno aislado propio de esa sesión.
Módulos
Los módulos independientes de frameworks que sustentan la fachada de el cliente y los hooks de React. Úsalos cuando necesites una operación sin la fachada, una función auxiliar pura o una capa de aislamiento exclusiva de Node. Cada módulo tiene un nivel de estabilidad para que sepas sobre qué construir.
| Nivel | Significado |
|---|---|
| Canónico | Importa desde la raíz @beeuni/sdk. Úsalo para todo el código nuevo. |
| Compatible | Una subruta dedicada (@beeuni/sdk/react, @beeuni/sdk/server). De primera clase, no obsoleta. |
| Alias obsoleto | Una subruta antigua que sigue funcionando. Reexporta código que la raíz ya exporta. Importa desde la raíz en su lugar. |
| Interno | Fuera de semver. No lo importes en el código del host. |
El punto de entrada raíz es el canónico. Todos los nombres independientes de frameworks que aparecen a continuación se pueden importar
directamente desde @beeuni/sdk:
import { files, getSessionHealth, getClient, authenticatedFetch, backendApi } from '@beeuni/sdk';
Módulos canónicos
| Módulo | Qué hace |
|---|---|
| Archivos | Operaciones con archivos del espacio de trabajo: listar, leer, buscar, escribir |
| Entorno de ejecución de sesión | Comprobación de estado y generadores de URL de vista previa/proxy |
| Cliente runtime | El cliente REST tipado de runtime y todos sus tipos |
| Autenticación | authenticatedFetch y funciones de acceso al token |
| REST de proyectos | Las funciones REST sin procesar que encapsula la fachada |
| Cliente API | backendApi, el cliente HTTP tipado de bajo nivel |
| Turnos | Agrupación de mensajes en turnos, cálculos de costes y estados — consulta Turnos |
| Transcripciones | formatTranscript, una exportación a Markdown del lado del cliente |
| Listas del editor | Las listas de agentes y modelos del editor de sesión: cuáles ofrecer y cuál se ejecuta |
Archivos
import { files } from '@beeuni/sdk';
const tree = await files.list('/workspace/src');
const { content } = await files.read('/workspace/README.md');
const hits = await files.findText('TODO');
await files.upload(file, '/workspace/uploads', file.name, {
onProgress: ({ loadedBytes, totalBytes }) => {
console.log(`${loadedBytes}/${totalBytes}`);
},
});
Las cargas de más de 64 KiB cruzan el límite del sandbox en bloques verificados. La función de devolución de llamada de progreso se ejecuta después de que cada bloque llegue al sistema de archivos de la sesión.
uploadNativeFile({ uri, name, type? }, targetPath, baseUrl) carga un archivo del
dispositivo desde React Native en una sola solicitud. El entorno de ejecución transmite los bytes desde
uri, por lo que nunca entran en el heap de JS. Usa la misma autenticación, plazo límite y
repetición de 401 que files.upload. No divide en bloques.
fetchProjectArchive, fetchCostExportCsv y las llamadas de versión del sandbox envían
mediante el mismo transporte. Un fallo lanza un ApiError con status.
files.write(path, blob) reemplaza el archivo en path y falla si path es una
carpeta. files.create(path) crea un archivo vacío y nunca sobrescribe: cuando ya
existe un archivo o una carpeta en path, lanza FileExistsError
(status 409, code 'FILE_EXISTS').
import { FileExistsError, files } from '@beeuni/sdk';
try {
await files.create('/workspace/notes.md');
} catch (error) {
if (error instanceof FileExistsError) console.log(`${error.path} already exists`);
else throw error;
}
files apunta al sandbox activo globalmente. Si tu host ejecuta más de una
sesión a la vez, llama a s.files en el identificador de sesión en su lugar. Siempre
apunta al sandbox propio de esa sesión. Consulta Sesiones.
Funciones auxiliares del entorno de ejecución de sesión
import { getSessionHealth, isRuntimeReady } from '@beeuni/sdk';
const result = await getSessionHealth();
if (result.ok && isRuntimeReady(result.health)) {
// the sandbox daemon is ready
}
getSessionHealth nunca lanza una excepción ante un estado que no sea 2xx. Devuelve
{ status, ok, health, body } y te permite decidir qué significa un estado. El
mismo módulo exporta las funciones auxiliares de URL que reescriben la salida localhost de un agente
como una URL de proxy accesible: detectLocalhostUrls, rewriteLocalhostUrl,
proxyLocalhostUrl, parseLocalhostUrl y buildWebProxyUrl.
Cliente runtime
import { getClient } from '@beeuni/sdk';
const client = getClient();
const { data } = await client.session.list({ limit: 100 });
getClient() devuelve el cliente de compatibilidad tipado de runtime para el sandbox activo,
con la autenticación ya inyectada. Prefiere beeuni.session(pid, sid).runtime, el
mismo cliente limitado a una sesión, al getClient() global cuando tu
host ejecute más de una sesión.
Funciones auxiliares de autenticación
import { authenticatedFetch, getAuthToken } from '@beeuni/sdk';
const res = await authenticatedFetch(`${runtimeUrl}/beeuni/health`);
const token = await getAuthToken();
El token procede de la función getToken que pasaste a createBeeuni.
La mayor parte del código de la aplicación no necesita este módulo: las capas de archivos, sesiones y fachada
ya gestionan la autenticación por ti.
Cliente API
import { backendApi } from '@beeuni/sdk';
const data = await backendApi.get('/some/endpoint');
await backendApi.post('/some/endpoint', { name: 'x' });
backendApi es el cliente HTTP tipado en el que se basa cada función REST. Úsalo
solo para un endpoint que aún no tenga un envoltorio tipado.
Listas de agentes y modelos del editor
Crea los selectores de agentes y modelos de un editor de sesión con las mismas reglas que usa la aplicación web de Beeuni. Todas las funciones son puras: obtén las entradas con el cliente y luego pásalas.
import {
composerSelectableAgents,
createModelVisibility,
flattenModels,
modelInDefaultView,
pickerProviderList,
projectConfigAgentsToRuntimeAgents,
resolveComposerAgent,
resolveComposerModel,
resolveModelDefault,
} from '@beeuni/sdk';
// Agents: the roster, the picker list, and the agent the send carries.
const roster = projectConfigAgentsToRuntimeAgents(detail.config);
const pickerAgents = composerSelectableAgents(roster, { enableProjects: false });
const agent = resolveComposerAgent({
agents: roster,
boundAgent: session?.agent,
defaultAgent: detail.config.default_agent,
selectedAgent: pick,
});
if (agent.disabled) {
// no accessible agent: refuse the send
}
// Models: gateway projects read /model-picker, native projects merge the
// catalog synthesis with the running sandbox's provider list.
const gatewayEnabled = detail.project.experimental?.llm_gateway === true;
const providers = pickerProviderList({
gatewayEnabled,
modelPicker,
runtimeProviders,
llmCatalogProviders,
secretNames,
});
const models = flattenModels(providers, { providerMode: gatewayEnabled ? 'gateway' : 'native' });
const isVisible = createModelVisibility({ catalogModels: models });
const defaultView = models.filter(
(m) => m.enabled !== false && modelInDefaultView(m, { search: '', isStoreVisible: isVisible, selected }),
);
const { model, explicit } = resolveComposerModel({
models,
picks: [sessionPick],
serverDefault: resolveModelDefault(modelDefaults, agent.selected ?? undefined),
providers,
});
resolveComposerModel devuelve explicit: undefined cuando el editor usa
su valor predeterminado. model es la clave que se muestra y se envía. El
id de cada modelo aplanado es la referencia que almacena una selección; modelRefToKey(ref, gatewayEnabled) convierte una
referencia almacenada (una fijación de sesión, una vinculación de canal, el model de un activador) de nuevo en una
clave.
Subrutas compatibles
| Subruta | Qué hace |
|---|---|
@beeuni/sdk/react |
Hooks de React — consulta Hooks de React |
@beeuni/sdk/server |
Configuración por solicitud para backends multiinquilino |
@beeuni/sdk/wire-message-id |
Solo el reloj de identificadores de mensajes del protocolo de runtime (un módulo, sin importaciones). La raíz exporta los mismos nombres |
Identificadores de mensajes del protocolo
El messageId de un prompt es su posición en la transcripción. runtime ordena
los mensajes por msg_ + un reloj de 48 bits (Date.now() * 0x1000, los 48 bits inferiores) +
14 caracteres base62, y el reloj se reinicia cada 2^36 ms (unos 2,2 años).
Nunca lo codifiques a mano.
import { mintWireMessageId } from '@beeuni/sdk';
// `after`: the ids already in this session's transcript.
const messageId = mintWireMessageId({ after: transcriptIds });
La generación se fecha dos minutos atrás y luego se eleva un tic por encima del identificador más reciente
en after que esté como máximo una hora por delante. Un llamador que conserva la posición más reciente
como un reloj en lugar de identificadores usa mintWireMessageIdAbove({ nowMs, newestKnownTime }), which returns { id, time }. newestWireIdClock(ids)
para encontrar ese reloj. Todas las comparaciones se realizan en el anillo, por lo que los identificadores a ambos lados de un
reinicio conservan su orden real.
El reloj de 48 bits se reinicia cada ~2,2 años, así que nunca compares dos relojes con >
o <=: un identificador generado justo después de un reinicio es numéricamente menor que uno generado
justo antes. Usa wireIdClockDelta(clock, reference), la distancia con signo
en el anillo (positiva cuando clock está por delante), y maxWireIdClock(clocks) para
el más reciente de varios:
import { maxWireIdClock, wireIdClockDelta } from '@beeuni/sdk/wire-message-id';
const floor = maxWireIdClock([transcriptNewest, deliveredNewest]);
const stale = floor !== null && wireIdClockDelta(clientClock, floor) <= 0n;
Aislamiento del lado del servidor
createBeeuni almacena su configuración, incluida la función de token, en una
variable global del proceso. Esto es adecuado para una pestaña del navegador, una CLI o un
servidor de un solo inquilino. No es seguro para un servidor Node que gestiona solicitudes
concurrentes de distintos usuarios, porque la última llamada a createBeeuni prevalece para
todas las solicitudes en curso. @beeuni/sdk/server lo resuelve con aislamiento por
solicitud:
import { createScopedBeeuni } from '@beeuni/sdk/server';
export async function handler(req: Request) {
const beeuni = createScopedBeeuni({ backendUrl, getToken: () => tokenFor(req) });
return beeuni.projects.list();
}
createScopedBeeuni y runWithBeeuni aíslan la configuración por solicitud con
AsyncLocalStorage de Node. Nunca importes @beeuni/sdk/server desde un paquete de navegador:
incorpora node:async_hooks de forma estática.
El runtime() de nivel superior de un cliente con ámbito limitado lanza una excepción (resolvería el
sandbox de otro inquilino). Accede al entorno de ejecución de una sesión específica mediante
beeuni.session(pid, sid).runtime después de await s.ensureReady().
Alias obsoletos
Unas veinte subrutas antiguas siguen funcionando: /files, /turns, /session, /auth,
/projects-client, /api-client, /config, /event-stream,
/opencode-client, /platform-client y más. Cada una reexporta código que el
punto de entrada raíz @beeuni/sdk ya exporta. Siguen funcionando para que ningún import breaks, but new code should import from the root. existente
Módulos internos
@beeuni/sdk/internal/* contiene los almacenes de zustand que el entorno de ejecución propio de apps/web usa
internamente: estado de sincronización de sesiones, seguimiento del entorno de ejecución activo y gestión de
reconexiones. Esta subruta queda explícitamente fuera de semver. No la importes en
el código del host; los hooks de React ya exponen el estado que
necesitas.
Turnos
Funciones simples que agrupan los mensajes de sesión en turnos y clasifican cada
parte de un mensaje. Úsalas para crear un renderizador de chat personalizado en lugar del
de referencia en apps/web. Sin React ni DOM: cada exportación es una función
simple o un tipo, y se puede llamar de forma segura desde cualquier host.
import { classifyPart, classifyTurn, toolInfo, toolViewModel } from '@beeuni/sdk';
Importa todas las funciones desde el punto de entrada raíz @beeuni/sdk. La
subruta @beeuni/sdk/turns sigue funcionando, pero es un alias obsoleto. El código
nuevo debe usar el punto de entrada raíz; consulta Distribución.
Clasificar una parte
classifyPart(part) normaliza uno de los 12 tipos de partes del formato de
transcripción de Beeuni (beeuni.transcript.v1, BEEUNI_TRANSCRIPT_SCHEMA) en un
ClassifiedPart: una unión discriminada por kind. Cada variante ya resuelve los
campos que necesita un renderizador: estado de la herramienta, salida JSON analizada y detección de imágenes.
import { classifyPart, type ClassifiedPart } from '@beeuni/sdk';
for (const part of message.parts) {
const classified: ClassifiedPart = classifyPart(part);
switch (classified.kind) {
case 'text':
render(classified.text);
break;
case 'tool':
render(classified.tool.title, classified.tool.status);
break;
}
}
kind |
estructura |
|---|---|
text |
{ id, text, synthetic } — omite las partes synthetic; marcan el prompt sintético del modo shell |
reasoning |
{ id, text } |
tool |
{ id, tool: ToolView } |
file |
{ id, filename?, mime, url, isImage, isPdf } |
subtask |
{ id, description, agent, prompt, model? } |
patch |
{ id, hash, files, fileCount } |
snapshot |
{ id, snapshot } |
agent |
{ id, name } |
retry |
{ id, attempt, message, createdAt } |
compaction |
{ id, auto, overflow, tailStartId? } |
step |
{ id, phase: 'start' | 'finish', snapshot?, reason?, cost?, tokens? } |
unknown |
{ raw } — un tipo de parte que esta versión del SDK no conoce |
Una parte recibida no reconocida se convierte en unknown en tiempo de ejecución en lugar de
lanzar una excepción. Esto permite que un cliente antiguo se comunique con un servidor más reciente.
Una parte de herramienta se clasifica en ToolView:
interface ToolView {
name: string;
title: string;
status: 'pending' | 'running' | 'done' | 'error';
input?: Record<string, unknown>;
output?: string;
error?: string;
outputParsed?: unknown; // JSON.parse(output) when it parses, capped at 256KB
outputText?: string; // the raw output text, always present
kind?: ToolKind; // toolKind(name): the action, whatever the harness calls the tool
files?: ToolFile[]; // the files a file tool read, wrote or changed: path, patch, additions/deletions
diff?: string; // a unified diff of the change
diagnostics?: Record<string, unknown[]>; // language-server diagnostics, keyed by file path
answers?: string[][]; // the answers to a `question`, one list per question
childSessionId?: string; // the child session a delegating call (`task`) runs
}
toToolView(part) crea uno directamente a partir de una parte de herramienta. Lee estos campos
en lugar del state.metadata propio de un harness: así, la misma tarjeta muestra un
edit de runtime (filePath, filediff) y un edit de pi (path, edits,
un patch unificado).
Algunas herramientas (web_search, image_search, llamadas a conectores) indican
state.status: 'completed' incluso cuando su cuerpo JSON contiene
success: false. classifyPart lo detecta y establece ToolView.status en
'error' también en ese caso.
classifyTurn(message) clasifica cada parte de un mensaje del asistente y
devuelve un ClassifiedTurn con tres campos:
parts— cada parte, clasificadaerror— demessage.info.error, si existeisEmpty— verdadero cuando el turno no tiene errores ni partes con contenido visible
Metadatos de herramientas
toolKind(name) es la única taxonomía de herramientas: asigna el nombre de herramienta de cualquier harness
(write de pi, oc-apply_patch de runtime, pty_spawn de un plugin) a un
ToolKind: read, edit, write, bash, web_search, task,
question, … o other. Las familias de narración, los modelos de vista, las categorías de toolInfo
y el grupo de herramientas de contexto derivan de ella. inputPath(input)
lee la ruta de una herramienta de archivos de filePath, file_path o path.
toolKind('oc-apply_patch'); // 'apply_patch'
toolKind('pty_spawn'); // 'pty'
inputPath({ path: 'app.py' }); // 'app.py'
Otras dos funciones de consulta describen una herramienta. No las confundas.
toolInfo(name)— sin iconos, devuelve{ label, category }.classifyPartla usa internamente.ToolCategoryes'shell' | 'files' | 'search' | 'edit' | 'web' | 'task' | 'other'.getToolInfo(name, input)— con iconos, devuelve{ icon, title, subtitle }para la interfaz de referencia de tarjetas de herramientas. El subtítulo procede de la entrada de la herramienta, por ejemplo, una ruta de archivo o una consulta de búsqueda.
toolInfo('bash'); // { label: 'Shell', category: 'shell' }
getToolInfo('write', { filePath: '/workspace/main.go' });
// { icon: 'file-pen', title: 'Write', subtitle: 'main.go /workspace' }
Ambas funciones reconocen prefijos de nombres de herramientas, por lo que las familias de herramientas de plugins de Beeuni
(agent_*, session_*, task_*, trigger_*, project_*, pty_*) se resuelven
sin actualizar el registro. Un nombre de herramienta desconocido nunca lanza una excepción: usa
humanizeToolName(name) con la categoría 'other' como alternativa.
Modelos de vista de herramientas
toolViewModel(classifiedTool) asigna una parte de herramienta clasificada a una estructura diseñada
para una familia de herramientas. Una interfaz puede entonces mostrarla de forma específica en lugar de como un
bloque JSON genérico.
const vm = toolViewModel(classifiedTool);
if (vm.kind === 'shell') {
render(vm.command, vm.stdout, vm.exitCode);
}
kind |
estructura | herramientas |
|---|---|---|
web-search |
{ query, results?, answer?, error? } |
web_search, image_search |
shell |
{ command, stdout?, exitCode? } |
bash |
file-read |
{ path, preview? } |
read |
file-write |
{ path, preview? } |
write |
file-edit |
{ path, diff?: DiffLine[] } |
edit, morph_edit |
search |
{ pattern, matches?: SearchMatch[] } |
grep, glob |
task |
{ description, agent? } |
task |
todo |
{ items: TodoItem[] } |
todowrite |
question |
{ questions: QuestionItem[], answers? } |
question, ask |
generic |
{ label, inputPretty?, outputPretty? } |
todo lo demás, siempre se puede mostrar de forma segura |
DiffLine es { type: 'added' | 'removed' | 'unchanged', text }. Los campos de texto
se limitan para que una salida de herramienta grande nunca impida el renderizado: 4000
caracteres para JSON con formato, 256 KB antes de ejecutar un diff.
Agrupar mensajes en turnos
Un turno empareja un mensaje del usuario con los mensajes del asistente que lo respondieron. Es la unidad que una interfaz de chat muestra como un intercambio.
import { groupMessagesIntoTurns, collectTurnParts, type TurnLike } from '@beeuni/sdk';
const turns: TurnLike[] = groupMessagesIntoTurns(messages);
for (const turn of turns) {
const parts = collectTurnParts(turn);
}
groupMessagesIntoTurns vincula cada mensaje del asistente con su mensaje de usuario
padre. Recurre al orden de los mensajes cuando falta el vínculo con el padre. También
asocia un mensaje huérfano del asistente —uno sin padre que precede a
todos los mensajes del usuario— al primer turno, no al último.
Funciones auxiliares relacionadas:
findLastTextPart(parts)— el texto de la respuesta final del turnoturnHasSteps(parts)— verdadero si existe una partetool,compaction,snapshotopatchisShellMode(turn)/getShellModePart(turn)— un turno formado por un prompt sintético que impulsa una llamada abash
Guardas de tipo
Acota el tipo de una parte por type:
import { isTextPart, isToolPart, getPartText } from '@beeuni/sdk';
if (isTextPart(part)) {
// part.type narrowed to 'text'
}
const text = getPartText(part); // works for 'text' and 'reasoning' parts
También disponibles: isReasoningPart, isFilePart, isAgentPart,
isCompactionPart, isSnapshotPart, isPatchPart, isStepPart
(step-start y step-finish).
Estado y errores
import { getWorkingState, getTurnStatus, formatDuration } from '@beeuni/sdk';
const status = getTurnStatus(parts, childMessages); // "Running commands..."
formatDuration(4300); // "4s" — durations under 1s return ''
getTurnStatus busca la última línea de estado en las partes de un turno. Cuando la última
parte es una delegación task en ejecución, pasa childMessages para que el estado muestre
la actividad real del subagente en lugar de una línea genérica «Delegando…».
import { getTurnError, getChildSessionError, unwrapError } from '@beeuni/sdk';
getTurnError(turn); // the first assistant error, unwrapped
getChildSessionError(childMessages); // newest error in a sub-agent's messages
unwrapError(rawError); // normalizes double-JSON and mixed error shapes
Totales de costes y tokens
import { getTurnCost, getSessionCost, formatCost, formatTokens } from '@beeuni/sdk';
const info = getTurnCost(partsWithMessage, modelPricingLookup);
const sessionCost = getSessionCost(messages, modelPricingLookup);
formatCost(0.0032); // "$0.003"
formatTokens(12345); // "12k"
Ambas funciones leen los totales de costes y tokens de las partes step-finish. Cuando una
parte indica cero, estiman el coste a partir de los recuentos de tokens usando un
ModelPricingLookup.
Los mensajes de suscripción de ChatGPT/Codex aportan $0.00, incluidos los mensajes
históricos con costes de ejecución distintos de cero. El uso de tokens y contexto sigue siendo visible.
Las sesiones mixtas conservan los cargos de los mensajes de API de pago. Los modelos de la API de OpenAI siguen
siendo facturables, incluidos los modelos de API cuyos nombres contienen codex.
Sesiones hijas y solicitudes pendientes
El árbol de conversaciones de una sesión de proyecto (la raíz y las conversaciones de subagentes
que generó) procede de su lista runtime_sessions. Estas
funciones auxiliares lo leen y dan preferencia a los nombres actuales frente a los anteriores a W4:
import { directSubsessions, projectSessionForRuntimeId, rootRuntimeSession, runtimeSessionsOf } from '@beeuni/sdk';
const root = rootRuntimeSession(projectSession); // the root conversation id
const children = directSubsessions(projectSession); // its subagent conversations
const owner = projectSessionForRuntimeId(projectSessions, childId); // the session a conversation belongs to
Una llamada a la herramienta task delega en una sesión hija. Estas funciones auxiliares conectan un
turno padre con los mensajes propios de esa sesión hija.
import { getChildSessionId, getChildSessionToolParts } from '@beeuni/sdk';
const childId = getChildSessionId(taskToolPart);
const steps = getChildSessionToolParts(childMessages);
Asocia una solicitud pendiente de permiso o de pregunta con su llamada a herramienta y encuentra qué partes de herramienta ocultar mientras una esté activa:
import { getPermissionForTool, getHiddenToolParts, isToolPartHidden } from '@beeuni/sdk';
const permission = getPermissionForTool(permissions, callID);
const hidden = getHiddenToolParts(activePermission, activeQuestion);
Formato y listas
import { getFilename, getDirectory, relativizePath, stripAnsi } from '@beeuni/sdk';
getFilename('/workspace/src/main.go'); // "main.go"
getDirectory('/workspace/src/main.go'); // "/workspace/src"
relativizePath('/workspace/src/main.go', '/workspace'); // "src/main.go"
Las funciones auxiliares de listas de sesiones operan sobre los mismos datos de sesión:
import { sortSessions, childMapByParent, allDescendantIds } from '@beeuni/sdk';
sessions.sort(sortSessions(Date.now())); // pins sessions updated in the last 60s
const childMap = childMapByParent(sessions);
const descendants = allDescendantIds(childMap, sessionId);
Estado de reintento: getRetryInfo(sessionStatus) devuelve { attempt, message, next, details? } when status.type === 'retry', with message limitado a 60
caracteres. details conserva un sobre estructurado de la pasarela LLM cuando existe:
el proveedor final, el código de la pasarela, el ID de solicitud, la sugerencia, el estado del servicio ascendente y
los fallos de candidatos ordenados. Cada fallo de candidato contiene attempt,
provider, routeModel, resolvedModel, stage, un status opcional, code
y message. Los reintentos heredados en texto plano devuelven details: undefined.
getRetryMessage(sessionStatus) devuelve el mensaje completo sin envoltorio. Cuando
runtime conserva solo ese mensaje, el compuesto de la pasarela sigue incluyendo el
ID de solicitud y el proveedor, el modelo resuelto, el estado HTTP, el código
y el mensaje limitado de cada candidato.
Tipos estructurales
Las funciones de agrupación y estado aceptan tipos estructurales mínimos —
PartLike, MessageInfoLike, TurnLike, ToolStateLike,
SessionStatusLike — en lugar de los tipos concretos de transcripción.
Tus propias estructuras de mensajes y partes se mantienen sin cambios siempre que coincidan con
los campos requeridos. classifyPart y classifyTurn son la excepción.
Se tipan con la unión Part de Beeuni (beeuni.transcript.v1), por lo que su
comprobación de exhaustividad detecta un nuevo tipo de parte durante la compilación.
Distribución
npm install @beeuni/sdk
El paquete se distribuye como ESM compilado con declaraciones completas de tipos de TypeScript.
react y @tanstack/react-query son dependencias pares opcionales. Si
usas @beeuni/sdk/react, instala ambas.
import { createBeeuni } from '@beeuni/sdk'; // framework-free core
import { useSession } from '@beeuni/sdk/react'; // optional React layer
import { createScopedBeeuni } from '@beeuni/sdk/server'; // Node and Bun servers
Puntos de entrada y estabilidad
El punto de entrada raíz, @beeuni/sdk, es el canónico. Exporta toda la
interfaz independiente de frameworks y se ejecuta en navegadores, Node 18+, Bun y entornos de ejecución
edge.
| Entrada | Nivel | Contrato |
|---|---|---|
@beeuni/sdk |
Canónico | Independiente de frameworks. Nunca importa React ni node:*. |
@beeuni/sdk/react |
Compatible | Hooks de React. La única entrada que importa React. |
@beeuni/sdk/server |
Compatible | Aislamiento de la configuración por solicitud para servidores Node y Bun, mediante node:async_hooks. Nunca lo incluyas en un bundle para navegador. |
Subrutas heredadas (/projects-client, /turns, /files y más) |
Obsoleto | Siguen funcionando. Cada una reexporta desde la raíz. Importa desde la raíz en su lugar. |
@beeuni/sdk/internal/* |
Interno | Solo lo usa la aplicación web de Beeuni. No es una API compatible. |
Bundles para CDN
El paquete también incluye dos bundles para navegador, compilados con tsup: un bundle ESM
(dist/beeuni.esm.min.js) y un global IIFE (dist/beeuni.global.js) que
define window.Beeuni.
<script src="https://unpkg.com/@beeuni/sdk/dist/beeuni.global.js"></script>
<script>
const beeuni = Beeuni.createBeeuni({
backendUrl: 'https://api.beeuni.ai/v1',
getToken: async () => KEY,
});
</script>
window.Beeuni expone el mismo punto de entrada raíz que la importación de npm:
Beeuni.createBeeuni, Beeuni.classifyTurn, Beeuni.ApiError.
Consulta también
- SDK — instalación y tu primera sesión.
- Sesiones — ciclo de vida, streaming y gestión de errores.
- Hooks de React — la capa reactiva construida sobre estos módulos.
Acceso del agente al repositorio
La configuración del agente acepta repository_access?: boolean (valor predeterminado: true).
Establece false para ejecutar nuevas sesiones sin el repositorio del proyecto ni acceso a la API del repositorio.
Los permisos de Git, secretos, conectores y herramientas siguen siendo independientes. Las sesiones existentes conservan su política guardada.
AgentConfigBlock.workspace está obsoleto. El SDK asigna los valores heredados branch/runtime al campo booleano.
Una escritura heredada de read requiere elegir explícitamente repository_access; no habilita el acceso de solo lectura al repositorio.
Acceso a proveedores y modelos
Lee beeuni.projects.modelAccess(projectId). Cambia un destino con beeuni.projects.setModelAccess(projectId, { target: 'provider' | 'model', id, enabled }).
Usa el ID de proveedor beeuni para Beeuni Managed Models, o un ID de proveedor del catálogo para BYOK, Codex y proveedores personalizados. Usa el ID completo del protocolo del gateway para un modelo. La desactivación del proveedor abarca los modelos futuros y conserva las preferencias de cada modelo y las credenciales guardadas.
El modelo predeterminado actual y su proveedor requieren un sustituto antes de desactivarlos (409 cannot_disable_default). Las solicitudes directas al gateway dirigidas a destinos desactivados fallan con model_disabled o provider_disabled. Las solicitudes al proveedor que ya están en curso finalizan normalmente. El indicador enforced de la respuesta es false cuando el proyecto usa runtime nativo en lugar del gateway.
Los consumidores de React usan useModelAccess(projectId) de @beeuni/sdk/react. Su mutación setEnabled(change) actualiza el catálogo de administración y el selector de sesiones.