Référence du SDK
L’ensemble de l’API @beeuni/sdk — méthodes du client, modules, tours et distribution.
Cette page présente l’ensemble de l’API @beeuni/sdk : toutes les méthodes du client, les
modules indépendants de tout framework, les utilitaires de tours et la distribution du paquet. Consultez
SDK pour commencer et Sessions pour approfondir
le cycle de vie des sessions.
Le client
createBeeuni(config) renvoie un client unique. Chaque méthode est un appel typé à
l’API de la plateforme. Les handles project(id) et session(pid, sid) associent les identifiants
pour vous éviter de les répéter.
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
Comptes — beeuni.accounts
| méthode | fonction |
|---|---|
list() · get(accountId) |
comptes auxquels vous appartenez · un compte |
create({ name }) · updateName(accountId, name) |
créer · renommer un compte |
branding.get(accountId) · branding.update(accountId, { app_name }) · branding.uploadAsset(accountId, kind, file) · branding.removeAsset(accountId, kind) · branding.reset(accountId) |
identité visuelle de l’organisation (Enterprise) : logo / icône / favicon et nom de produit personnalisés ; kind vaut logo · icon · favicon, ou logo_dark · icon_dark · favicon_dark pour la variante du thème sombre |
members(accountId) · invite(accountId, input) |
lister les membres · en inviter un |
updateMemberRole(accountId, userId, role) · removeMember(accountId, userId) |
attribuer le rôle dans le compte · retirer un membre |
invites(accountId) |
invitations en attente |
cancelInvite(accountId, inviteId) · resendInvite(accountId, inviteId) |
annuler · renvoyer une invitation en attente |
leave(accountId) |
quitter le compte |
accounts.tokens génère des clés API limitées au compte (beeuni_pat_...). Consultez
Authentification du SDK pour le modèle complet des jetons.
| méthode | fonction |
|---|---|
tokens.list(accountId?, options?) |
lister les clés API — celles de tout le compte, ou uniquement les vôtres avec { mine: true } |
tokens.create(input) |
en générer une — { accountId?, name, expiresAt?, projectId? } |
tokens.revoke(tokenId, accountId?) |
en révoquer une |
accounts.audit est le journal de reconstitution pour les entreprises. Il combine les requêtes
API authentifiées avec les événements sémantiques de session, de connecteur, d’approbation et d’ordinateur.
| méthode | fonction |
|---|---|
audit.log(accountId, filters?) |
lister les événements par projet, session, acteur, source, résultat, requête, corrélation, ressource, action ou date |
audit.export(accountId, filters?) |
exporter le même flux d’événements filtré au format CSV ou JSONL |
audit.webhooks.list/create/update/remove(...) |
gérer les webhooks SIEM signés pour le flux centralisé |
Chaque événement inclut project_id, session_id, actor_type, source, outcome,
request_id, trace_id et correlation_id lorsque l’action les fournit.
L’API ne stocke ni corps de requête, ni prompts, ni secrets, ni identifiants d’authentification, ni arguments bruts
de connecteur dans l’événement centralisé. Les événements de connecteur peuvent inclure un
aperçu limité des arguments qui masque les champs ressemblant à des identifiants d’authentification et les données opaques.
Attributions d’accès
Beeuni utilise un seul type d’enregistrement d’octroi : une attribution. Elle associe un principal (user,
group, service_account ou pending) à un rôle, dans un périmètre (account,
ou un project), éventuellement limité à un objet (agent, skill, secret,
app ou trigger) et éventuellement accompagné d’un expires_at. Les accès de groupe,
les accès par ressource et les associations à des rôles personnalisés sont tous des attributions. Consultez
Comptes et accès pour le modèle.
L’interface REST canonique est la suivante :
| Méthode + chemin | Fonction |
|---|---|
GET /v1/accounts/{accountId}/iam/assignments |
lister les attributions, filtrées par principal, périmètre, objet ou rôle |
POST /v1/accounts/{accountId}/iam/assignments |
créer une attribution |
DELETE /v1/accounts/{accountId}/iam/assignments/{assignmentId} |
révoquer une attribution |
GET /v1/accounts/{accountId}/iam/permissions |
le catalogue des permissions, sous forme de données |
GET /v1/accounts/{accountId}/iam/roles · …/roles/{roleId}/permissions |
rôles · permissions d’un rôle |
Le SDK les expose via listAssignments, createAssignment,
revokeAssignment et listPermissions. Une ligne du catalogue contient action,
scope_type, resource_type, delegable, description, area, level et
implies — consultez-la plutôt que de coder en dur les chaînes d’action.
L’attribution d’un rôle personnalisé nécessite le droit rbac du compte ; sans celui-ci, la route répond
402 avec code: "entitlement_required".
Invitations au compte — beeuni.accountInvites
Accessible avec le seul jeton d’invitation — la personne invitée peut ne pas encore être membre.
| méthode | fonction |
|---|---|
listMine() |
toutes les invitations en attente et non expirées adressées à votre e-mail, avec l’espace de travail et les projets auxquels elles donnent accès |
describe(inviteId) · accept(inviteId) · decline(inviteId) |
prévisualiser · accepter · refuser une invitation |
Projets — beeuni.projects
| méthode | fonction |
|---|---|
list() · listForAccount(accountId) |
vos projets · projets d’un compte |
get(id) · detail(id) |
résumé · détails complets |
create(input) · createRepo(input) |
à partir d’un repo_url existant · nouveau dépôt GitHub vide |
provision(input) |
nouveau projet sur un nouveau dépôt géré par Beeuni, initialisé avec un modèle de démarrage — { name, account_id?, seed_starter?, starter_template?, marketplace_items?, source_item_id?, idempotency_key? } |
update(id, input) · archive(id) |
mettre à jour les paramètres · archiver |
llmCatalog(id) · modelPicker(id) |
catalogue de modèles complet · compact pour un sélecteur |
sandboxTemplates(id) · sandboxHealth(id) |
modèles de build du sandbox · état du build |
sessions(id) · createSession(id, input?) |
lister les sessions visibles · créer une session |
provision crée un nouveau projet ; il ne démarre pas le
sandbox d’un projet existant. Démarrez plutôt une session — voir Sessions.
Envoyez idempotency_key lorsqu’une nouvelle tentative est possible — un rechargement, un deuxième onglet, un
délai d’attente dépassé suivi d’une nouvelle tentative. provision génère un tout nouveau dépôt géré à chaque appel ;
sans clé, ces appels créent donc tous de véritables projets en double. Réutilisez une même clé pour chaque
tentative d’une seule création logique : les appels répétés renvoient le projet créé par la première
tentative (201, mêmes project_id et push_token: null). La clé identifie la
tentative, pas la charge utile — la réutiliser avec un autre name renvoie le premier
projet et ignore la nouvelle valeur ; générez donc une nouvelle clé pour chaque création distincte.
Créer un deuxième projet avec le même nom et sans clé reste possible.
Un appel répété qui arrive alors que le premier appel est encore en cours de provisionnement reçoit 409 avec
code: 'provision_in_flight' plutôt qu’un project_id que cet appel pourrait encore
annuler. Réessayez avec la même clé.
project(id).sessions.list({ scope: 'project' }) est un inventaire du cycle de vie destiné à un
appelant disposant des permissions de gestionnaire de projet. Il ajoute les sessions accessibles indisponibles, préchauffées et supprimées de façon réversible, avec
des métadonnées de propriété et d’état d’exécution. Les deux périmètres de liste excluent toute session que
l’appelant ne peut pas ouvrir.
sessions.list et sessions.listPage acceptent également les filtres de hiérarchie et
d’attribution. Sans eux, la liste reste plate et inchangée.
| option | fonction |
|---|---|
parent: 'root' |
Sessions de premier niveau uniquement. Chaque ligne contient child_count. |
parent: '<sessionId>' |
Les sessions enfants de cette session, les plus récentes d’abord. |
startedBy: 'me' | 'others' | 'automated' |
Filtrer par initiator, relativement à l’appelant. |
q |
Recherche insensible à la casse sur le titre, le libellé de démarrage, le slug du déclencheur et le préfixe de l’identifiant de session, parmi toutes les sessions que l’appelant peut ouvrir. Avec parent: 'root', une racine correspondant via un enfant possède search_match: 'child'. |
Chaque ligne de session possède parent_session_id et initiator
({ type: 'member' | 'trigger' | 'channel' | 'api' | 'system', id, label }).
initiator indique qui a démarré l’ensemble de l’exécution ; un enfant reprend la valeur de son parent.
sessionParentId(session) lit parent_session_id, puis l’ancien
metadata.spawned_by_session. Un curseur n’est valide que pour l’ensemble de filtres qui
l’a émis.
GitHub — beeuni.github
Installation de l’application GitHub et association de dépôts au niveau du compte, et non du projet.
| méthode | fonction |
|---|---|
getInstallation(accountId) · listInstallations(accountId) |
installation de ce compte · installations accessibles à l’utilisateur |
saveInstallation(input) · deleteInstallation(accountId, installationId?) |
enregistrer · dissocier une installation |
listLinkableInstallations(input) |
installations que l’utilisateur GitHub autorisé peut associer ; chaque entrée contient linked_to_other_accounts, le nombre d’autres comptes Beeuni qui la détiennent — jamais leurs noms |
listRepositories(accountId, installationId?) · listRepositoryBranches(...) |
dépôts visibles par l’installation · branches et branche par défaut de GitHub |
linkRepository(input) |
Importer un dépôt en tant que projet à l’aide d’une installation GitHub autorisée. |
replaceProjectRepository({ project_id, repo_url, expected_repo_url, github_token }) |
remplacer le dépôt GitHub d’un projet existant. Utilisez soit github_token avec un accès Contents en lecture/écriture, soit installation_id avec un github_user_token temporaire pour vérifier l’accès administrateur à l’organisation et autoriser uniquement ce dépôt via la GitHub App. copy_shared_secrets_from_project_id avec copy_shared_secret_identifiers copie les secrets d’exécution partagés sélectionnés dans la même transaction. Un expected_repo_url obsolète renvoie 409. L’ancien dépôt reste sur GitHub. Les nouvelles sessions utilisent le dépôt de remplacement ; les sessions existantes conservent leur copie de travail. |
Cette liste ne contient que de véritables connexions de compte. « Beeuni managed » n’en fait pas partie — il s’agit du backend de l’instance ci-dessous.
Backend git de l’instance — beeuni.gitBackend
Un propriétaire unique pour tout le déploiement, accompagné d’un identifiant d’authentification, utilisé pour les dépôts
gérés par Beeuni. Ce n’est jamais une connexion de compte et il n’apparaît jamais dans
beeuni.github.listInstallations.
| méthode | fonction |
|---|---|
get() |
{ configured, kind: 'app' | 'pat' | null, owner } — lisible par tout utilisateur authentifié ; expose uniquement le nom de connexion du propriétaire déjà présent dans chaque repo_url géré |
Facturation — beeuni.billing
Consulte les crédits, l’abonnement, l’offre et l’historique des transactions. Utilisez le paiement et la gestion de facturation Beeuni pour les paiements et les achats de crédits.
| méthode | fonction |
|---|---|
accountState(accountId?) · accountStateMinimal(accountId?) |
état de facturation complet · minimal |
transactions(params?) · transactionsSummary(params?) |
historique · totaux récapitulatifs |
creditBreakdown(accountId?) · usageHistory(params?) |
solde de crédits par source · utilisation au fil du temps |
sessionCosts.list(options?) · sessionCosts.get(sessionId, options?) |
relevés paginés des coûts des sessions · registre détaillé d’une session |
tierConfigurations() |
niveaux de forfait disponibles |
checkout.createSession(input) · checkout.confirmSession(sessionId, accountId?) |
Obsolètes. Rejettent avec ENDPOINT_RETIRED. Supprimés dans la prochaine version majeure. |
subscription.createPortalSession(...) · subscription.cancel(...) · subscription.reactivate(...) |
ouvrir le portail client · résilier · réactiver |
subscription.cancelScheduledChange(...) · prorationPreview(...) |
résilier · prévisualiser un changement de forfait |
subscription.scheduleDowngrade(...) |
Obsolète. Rejette avec ENDPOINT_RETIRED. Changez de forfait dans le portail client. Supprimé dans la prochaine version majeure. |
credits.purchase(input) · credits.autoTopupSettings(...) · credits.configureAutoTopup(...) |
achat ponctuel · lire · configurer la recharge automatique |
sessionCosts.list() accepte accountId, projectId, limit et offset.
Chaque ligne combine le coût LLM finalisé et le coût de calcul facturé du sandbox.
sessionCosts.get() ajoute l’utilisation des modèles et le registre distinguant LLM et calcul.
La liste inclut un total de rapprochement pour les coûts sans session.
Partages de sandbox — beeuni.sandboxShares
Liens de partage publics pour un port exposé du sandbox. Leur portée est le sandbox, pas le projet.
| méthode | fonction |
|---|---|
list(sandboxId) |
liens de partage actifs |
create(input) |
en créer un — { sandboxId, port, ttl?, label? } |
revoke(sandboxId, token) |
en révoquer un |
Catalogue de la marketplace — beeuni.marketplace
Consultation du catalogue public, en lecture seule — distincte de project(id).marketplace,
qui installe un élément dans un projet.
| méthode | fonction |
|---|---|
items(options?) · item(id) · itemFile(id, path) |
parcourir · un élément · un fichier dans un élément |
marketplaces() · featured() |
toutes les marketplaces · marketplaces mises en avant |
sources.list() · sources.add(input) · sources.remove(id) |
lister · ajouter · supprimer une source |
Notifications — beeuni.notifications
Les notifications de l’appelant, pour tous les comptes et projets. Chaque personne connectée
dispose d’une boîte de réception, d’un enregistrement de préférences et d’abonnements Web Push pour
ses navigateurs. Chaque méthode nécessite l’identifiant d’authentification d’une personne : un compte de service
reçoit 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éthode | fonction |
|---|---|
list({ limit?, before? }, { signal? }) |
la page la plus récente : { notifications, unread_count, next_before }. limit va de 1 à 50 (20 par défaut). Passez next_before comme before pour la page suivante. Les entrées que l’appelant ne peut plus voir sont omises. Un échec n’appelle pas le gestionnaire d’erreurs de l’hôte. |
markRead({ ids }) · markRead({ all: true }) · markRead({ sessionId }) |
marquer comme lues 1 à 100 entrées, toutes les entrées ou toutes les entrées d’une session. Ne modifie que les entrées de l’appelant. Renvoie { updated, unread_count }. |
preferences() · updatePreferences({ kinds }) |
lire · modifier le choix des notifications push et des e-mails par type. Renvoie { kinds, email_available }. Un patch ne modifie que les types et les canaux qu’il nomme. |
webPushPublicKey() |
{ public_key } : le applicationServerKey pour pushManager.subscribe |
registerWebPushSubscription({ endpoint, keys }) |
envoyer les notifications push à ce navigateur. Nécessite une connexion dans le navigateur : un jeton personnel reçoit 403. Un point de terminaison sur un service push inconnu reçoit 400. |
unregisterWebPushSubscription(endpoint, { signal? }) |
arrêter les notifications push vers ce navigateur. Renvoie { deleted }. |
registerDeviceToken(input) · unregisterDeviceToken(token, { signal? }) |
enregistrer · supprimer le jeton push Expo d’une application native |
Types (InboxNotificationKind, répertoriés dans INBOX_NOTIFICATION_KINDS) :
| type | envoyé lorsque | push | e-mail (par défaut) |
|---|---|---|---|
turn_done |
un tour que vous avez lancé ou que vous suivez est terminé | activé | désactivé |
turn_error |
ce tour s’est terminé par une erreur | activé | activé, dans un récapitulatif |
question |
l’agent pose une question | activé | activé, dans un récapitulatif |
permission |
l’agent demande une autorisation | activé | désactivé |
shared |
quelqu’un a partagé une session avec vous | activé | activé, dans un récapitulatif |
automation_failed |
une automatisation que vous suivez a commencé à échouer | activé | activé, immédiatement |
automation_recovered |
cette automatisation fonctionne à nouveau | activé | désactivé |
DEFAULT_NOTIFICATION_PREFERENCES contient ces valeurs par défaut. L’entrée de la boîte de réception est
toujours créée ; les préférences ne déterminent que les notifications push et les e-mails. Un e-mail récapitulatif
liste les entrées encore non lues 15 minutes après leur arrivée, avec au maximum un récapitulatif
par heure. Masquez la colonne e-mail lorsque email_available vaut false.
Le url de chaque entrée ouvre son sujet. Son paramètre de requête ?notification=<id> permet à la
page de marquer l’entrée comme lue.
Le handle de session porte le suivi de l’appelant pour une session :
| méthode | fonction |
|---|---|
session(pid, sid).watch() |
{ watching } : l’appelant reçoit-il des notifications pour cette session |
session(pid, sid).setWatch(watching) |
false désactive les notifications de la session pour l’appelant, true rétablit son suivi. Envoyer un prompt à une session active son suivi, mais ne réactive jamais les notifications désactivées. |
session(pid, sid).presence({ tab_id, active, alerts? }, { keepalive? }) |
le bail de présence de cet onglet. alerts: true indique que l’onglet affiche ses propres notifications : lorsque notification_center est activé, le serveur n’envoie pas de notifications au téléphone ni via Web Push uniquement pendant qu’un onglet affichant des alertes est utilisé. Lorsqu’il est désactivé, alerts est ignoré et tout onglet présent bloque les notifications push au téléphone. keepalive permet à la requête de survivre à la fermeture d’une page. Par défaut : activé pour un signalement d’absence, désactivé pour un signalement de présence. useSession n’envoie keepalive qu’avec presencePageExit. |
Le handle de projet — beeuni.project(id)
Lie l’identifiant du projet ; toutes les sous-ressources en dépendent.
const p = beeuni.project(projectId);
await p.detail();
await p.update({ name });
await p.llmCatalog();
| méthode | description |
|---|---|
get · detail · update · archive |
lire · détails complets · mettre à jour · archiver |
llmCatalog · modelPicker · sandboxHealth |
lectures du modèle et des builds du sandbox |
onboardingComplete |
marquer l’intégration du projet comme terminée |
validateManifest(raw) |
valider un manifeste beeuni.yaml (ou l’ancien beeuni.toml) côté serveur |
gitToken() |
générer un nouveau jeton git push à portée limitée (409 pour un dépôt que vous fournissez) |
setAgentScope(agentName, scope) |
définir les secrets et connecteurs autorisés d’un agent dans le manifeste — la seconde liaison, pas un rôle |
p.tokens — clés API limitées au projet
Générées automatiquement à la création d’une session sous la forme BEEUNI_TOKEN ; peuvent aussi être générées manuellement.
| méthode | description |
|---|---|
list() |
clés API du projet |
create(input?) |
en générer une nouvelle |
revoke(tokenId) |
en révoquer une |
p.setupLinks — liens de configuration générés par l’agent
Un lien qu’une personne ouvre pour saisir un secret ou connecter une application, sans accès complet au projet.
| méthode | description |
|---|---|
requestSecret(input) · requestConnector(input) |
lien pour recueillir un secret · connecter une application |
p.apps — Apps (versions, machines, volumes)
Nécessite la fonctionnalité de projet apps. Guide : SDK → Apps.
| méthode | description |
|---|---|
list() · get(appId) · create(input) · update(appId, input) · remove(appId) |
inventaire et cycle de vie ; create accepte uses, update accepte aussi labels |
deployments.* · artifacts.* · access.* · rollback · start · stop |
déploiements, artefacts, politique d’accès, trafic et environnement d’exécution |
machines.list/start/stop/restart/destroy · scale(appId, count) · exec(appId, input) |
machines par groupe de processus ; exec nécessite project.app.admin |
volumes.list/create/update/destroy/snapshots/snapshot/restore/fork |
volumes persistants, instantanés quotidiens, restauration, duplication |
token(appId) |
un jeton de connexion de 15 minutes ; 409 app_capability_unsupported sans member_tokens |
p.secrets — secrets du projet
| méthode | description |
|---|---|
list() · upsert(input) |
lister les métadonnées · créer ou mettre à jour une valeur accessible uniquement en écriture et une politique de transmission |
setStrategy(identifier, strategy, options?) |
modifier l’exposition et sa liste d’hôtes |
broker(identifier, request) |
exécuter une requête HTTPS autorisée par la session et soumise à une politique |
remove(identifier) |
supprimer un secret |
setPersonal(name, value) · removePersonal(name) |
définir · supprimer une substitution par utilisateur |
setGitCredential(input) |
définir un identifiant d’authentification git |
runtime avec le consommateur sandbox correspond à l’exposition environment — celle par défaut,
et la seule politique qui place une valeur en clair dans la session. egress avec
le consommateur network correspond à l’exposition egress-enforced : la session détient une référence
et Beeuni substitue la valeur réelle en dehors du sandbox, pour les seuls hôtes HTTPS
énumérés dans la politique. L’exposition egress-enforced est expérimentale ; elle nécessite le
flag de fonctionnalité secrets_egress (Settings → Feature flags). Lorsque ce flag est désactivé,
setStrategy(identifier, 'egress', …) et upsert(...) avec une politique de sortie
renvoient 403 feature_disabled. Aucun consommateur broker n’a la moindre présence
dans la session. Voir
Secrets. La méthode broker(...) nécessite un
jeton limité à la session et une référence de session active.
p.access — attributions, invitations et demandes du projet
Chaque méthode ici lit ou écrit une attribution limitée à ce projet. Les rôles
du projet sont manager et member.
| méthode | description |
|---|---|
list() · invite(email, role) |
identités disposant d’un accès · inviter un utilisateur |
update(userId, role) · revoke(userId) |
attribuer un rôle de projet · révoquer l’attribution |
pendingInvites() · requests() |
invitations en cours · demandes d’accès en attente |
resendInvite(inviteId) · revokeInvite(inviteId) · approveRequest(id) · rejectRequest(id) |
renvoyer/révoquer une invitation · approuver/rejeter une demande |
groupGrants() · attachGroupGrant(...) · updateGroupGrant(...) · detachGroupGrant(...) |
les mêmes attributions, avec une identité group |
p.access.resourceGrants est la vue des attributions d’objet : elle limite une
identité à un seul objet du projet plutôt qu’à l’ensemble du projet. Beeuni
applique actuellement les attributions d’objet aux agents et aux compétences. Un agent est fermé par
défaut — un membre n’y accède que lorsqu’une attribution le désigne, lui ou l’un de ses
groupes. Une attribution d’objet ne porte aucune permission propre et restreint un
responsable de projet autant qu’un membre.
| méthode | description |
|---|---|
resourceGrants.list() |
attributions d’objet dans ce projet |
resourceGrants.create(input) |
attribuer un objet à un utilisateur ou à un groupe |
resourceGrants.remove(grantId) |
révoquer une attribution d’objet |
p.connector(slug) — un connecteur
| méthode | description |
|---|---|
run(action, args, options?) |
la sortie de l’action ; lève ConnectorCallError ou ConnectorApprovalPendingError — voir Erreurs |
call(action, args, options?) |
le résultat brut de l’appel ; 202 se résout avec ok: false |
describe() · describe(action) |
le connecteur avec les schémas d’entrée et de sortie · une action |
accounts() |
les comptes sous lesquels cet appelant peut l’exécuter, celui par défaut en premier |
paginate(action, args, { next, maxPages? }) |
itérateur asynchrone sur la sortie de chaque page ; lève ConnectorPageLimitError avec nextArgs lorsqu’il existe plus de maxPages pages (100 par défaut) — voir Pages |
uploadAttachment(content, input) |
p.connectors.uploadAttachment avec connector défini sur ce slug |
options : account, approvalContext, timeoutMs (90 000 par défaut), signal. Avec le fichier de beeuni connectors types, les arguments et la sortie sont typés.
p.connectors — connecteurs d’outils
| méthode | description |
|---|---|
catalog() · tools() |
catalogue Connector appelable · outils <connector>.<action> aplatis |
search(query, options?) · describe(tool) |
rechercher · inspecter un outil appelable |
call(tool, args?, options?) |
appeler un outil <connector>.<action> via la passerelle côté serveur. options.account indique le compte sous lequel l’exécuter — voir ci-dessous. |
accounts(slug) |
les comptes sous lesquels cet appelant peut appeler slug, celui par défaut en premier — les comptes auxquels options.account est comparé |
uploadAttachment(content, input) |
préparer des octets pour input.connector ; renvoie ref ({ $beeuni_attachment }) à placer dans les arguments d’un appel ultérieur — voir Joindre des fichiers |
list() · config(connectorId) |
connecteurs configurés · configuration d’un connecteur |
create(input) |
ajouter un connecteur |
auth.discover(input) |
prévisualiser l’authentification à partir d’une spécification OpenAPI, d’une collection Postman ou d’un point de terminaison |
remove(connectorId) · sync() |
supprimer un connecteur · resynchroniser les connecteurs |
setName(connectorId, name) · setSensitive(connectorId, sensitive) |
renommer · le marquer comme sensible (approbation supplémentaire requise) |
setAuthorizationStrategy(slug, strategy) |
@deprecated. Appelle toujours la route ; celle-ci est sans effet, répond {ok:true, deprecated:true} et ne change rien. owner_type sur chaque connexion constitue désormais l’intégralité de la règle d’accès. |
setCredentialMode(connectorId, mode) · setCredential(connectorId, input) |
changer de source · définir la valeur de l’identifiant d’authentification |
policies.get(connectorId) · policies.set(connectorId, policies) |
lire · remplacer ses politiques d’outils |
connections.list() · connections.reconcile(input) |
lister · créer/mettre à jour les comptes connectés |
connections.updateCredential(connectionId, input) |
renouveler un identifiant d’authentification de connexion |
connections.revoke(connectionId) · connections.activate(connectionId) |
bloquer · rétablir une connexion |
connections.setDefault(connectionId) |
en faire la connexion par défaut pour le périmètre de son propriétaire |
connections.rename(connectionId, label) |
modifier uniquement le libellé ; le compte reste autorisé. Chaque connexion porte connected_as, l’identité sous laquelle elle a été autorisée. |
p.connectors.discover permet de parcourir le catalogue des connecteurs directs. Cette fonctionnalité est expérimentale et désactivée par défaut — activez-la pour chaque projet sous Settings → Feature flags → “Connectors API Discover”. Easy Connect reste la place de marché de connecteurs par défaut.
| méthode | description |
|---|---|
discover.list(query?, cursor?) · discover.detail(id) |
rechercher des entrées OpenAPI/MCP/GraphQL/CLI · détails d’une entrée |
p.connectors.pipedream est la voie de compatibilité de l’ancien OAuth géré ; listApps
ne renvoie que les applications OAuth. Utilisez Easy Connect pour les nouvelles intégrations gérées. Connectez directement les applications à clé API.
| méthode | fonction |
|---|---|
pipedream.listApps(params?) · pipedream.connect(input) · pipedream.finalize(input) |
parcourir le catalogue d’applications · lancer un parcours de connexion · le finaliser |
Un connecteur définit l’outil, l’application du fournisseur et les politiques. connections
stocke ses comptes connectés — un connecteur peut en contenir plusieurs côte à côte.
Une session peut en fixer un pour chaque appel avec
connector_bindings: { alias: { connection_id } }, ou un appel individuel peut en désigner
un avec call(tool, args, { account }). Les identifiants restent chiffrés et
sont résolus à chaque requête.
connections est la seule façade d’autorisation active. Les anciens noms
authorizations et profiles ne font pas partie de l’interface actuelle du SDK.
Comptes et contrôle au moment de l’appel
Chaque connexion possède un owner_type : project (partagé — accessible à toute personne
à qui le connecteur est accordé, humain ou compte de service) ou member (privé —
accessible uniquement à son propriétaire, et seulement dans une session privée ; jamais à un
compte de service). L’accès à un compte partagé peut être restreint à des groupes et à des personnes :
connections.list() renvoie ses autorisations dans shared_with, et
connectionSharedWithEveryone(connection) indique si tous les membres du
projet peuvent l’utiliser. Un compte à accès restreint suit les règles des comptes privés pour les
personnes désignées, et usable: false signale un compte que l’appelant ne voit que pour le gérer.
Accordez ou révoquez l’accès avec createAssignment / revokeAssignment
(object: { type: 'connection', id }) — voir
Choisir qui peut utiliser un compte partagé.
p.connectors.accounts(slug) répertorie tous les comptes accessibles à cet appelant,
avec celui par défaut en premier :
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`
);
Un appel qui ne désigne aucun compte utilise d’abord le compte privé par défaut
de l’appelant, puis le compte partagé par défaut du projet. Un compte désigné
qui ne peut pas être résolu est refusé avec connector_not_connected — jamais
remplacé silencieusement — et le refus indique requested_account et
available_accounts. Chaque appel réussi indique le compte sous lequel il a été exécuté :
result.account = { connection_id, label, owner_type }.
Il n’y a plus de contrôle des connecteurs lors de la création d’une session. Une session était auparavant
refusée avec 409 CONNECTOR_CONNECTION_REQUIRED lorsqu’un connecteur requis n’avait aucune
connexion utilisable ; ce refus a été supprimé (require_connectors est inactif — voir
p.sessions). Le contrôle s’effectue désormais au moment de
l’appel : un connector_not_connected refusé contient connect_url, un lien
d’autorisation hébergé, dès qu’il est possible d’en générer un pour l’appelant — la résolution
se fait en un clic, via le bouton de connexion de la transcription.
p.policies — politiques du projet
| méthode | fonction |
|---|---|
list() · set(policies) |
les politiques du projet · remplacer l’ensemble |
p.triggers — automatisations cron, webhook, de surveillance et d’événements
Un déclencheur lance une action d’agent selon une planification, un webhook entrant, une commande surveillée ou un événement d’application sur un connecteur. Voir Déclencheurs pour la stratégie de session et les modèles de charge utile.
| méthode | fonction |
|---|---|
list() |
tous les déclencheurs |
eventTypes({ connector }) |
les événements d’application sur lesquels un connecteur peut se déclencher ({ provider, app, event_types }) ; 404 pour un connecteur inconnu, 409 event_source_unavailable lorsque son fournisseur n’a aucune source d’événements |
create(input) |
en créer un |
update(triggerId, input) |
modifier un déclencheur |
remove(triggerId) |
supprimer un déclencheur |
fire(triggerId) |
l’exécuter maintenant |
setActivation(paused) |
suspendre ou reprendre tous les déclencheurs du projet |
create(input) accepte { 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 sont obligatoires.
cron/run_at s’excluent mutuellement (type: 'cron') ; secret_env (le
secret HMAC du webhook) s’applique à type: 'webhook'.
Un déclencheur event nécessite connector (un slug de connecteur) et event (un identifiant de type
issu de eventTypes). event_account est facultatif : le libellé d’un compte partagé de
ce connecteur ; null ou son omission utilise le compte partagé par défaut du connecteur.
event_source est facultatif : l’identifiant de l’adaptateur de source d’événements, par exemple composio. null ou son omission utilise le
fournisseur du connecteur. L’identifiant de type appartient à cet adaptateur. La structure de event_config est définie par le config_schema de ce type.
eventTypes et eventApps indiquent l’adaptateur sous source ; provider est un alias obsolète.
Chaque déclencheur répertorié contient event: { connector, account, connected_as, type, config, source, provider, app, status: 'active' | 'needs_connection' | 'error' | 'pending', error, last_event_at } | null. Les modèles de prompt lisent l’événement via
{{ event.data.<field> }} ainsi que event.id, event.type, event.app,
event.connector et event.occurred_at.
session_access contrôle qui peut ouvrir les sessions créées par le déclencheur. Sa structure est
{ mode: 'private' | 'members' | 'project', memberIds: string[], groupIds: string[] } and defaults to private. Cette politique est un état d’exécution
local au compte. Elle n’entre pas dans le manifeste portable beeuni.yaml. La modification du seul
session_access ne crée aucun commit Git. Une session fixée conserve ses propres paramètres
de partage. Un gestionnaire de projet peut toujours ouvrir les sessions créées par les déclencheurs, y compris
celles qui utilisent private ou un accès réservé aux membres sélectionnés.
session_access est un paramètre de visibilité par ressource qui s’ajoute au modèle de rôles,
et non un rôle. Il détermine qui peut ouvrir les sessions d’un déclencheur donné. Il n’accorde aucune
permission refusée par la décision du rôle. Voir
Comptes et accès.
p.marketplace / p.registry — éléments installés
Installe les fichiers d’un élément du catalogue sur la branche par défaut du projet.
registry.* est un alias identique de marketplace.*.
| méthode | fonction |
|---|---|
marketplace.list() · marketplace.install(id) |
éléments installés · installer un élément du catalogue |
marketplace.updates() · marketplace.update(name) · marketplace.updateAll() |
mises à jour disponibles · en mettre un à jour · tous les mettre à jour |
marketplace.remove(name) |
désinstaller un élément |
p.files — fichiers du dépôt (lecture)
Accès en lecture seule à l’arborescence git du projet. Pour lire et écrire des fichiers dans une session en cours d’exécution, utilisez les opérations sur les fichiers de la session — voir Fichiers sous Modules ci-dessous.
| méthode | fonction |
|---|---|
listDirectory({ ref?, path? }) |
un niveau de dossier : { entries: [{ path, type, size? }], truncated }. Utilisez-le pour construire une arborescence ; chaque dossier est complet jusqu’à 5 000 entrées. |
list(options?) · read(path, ref?) |
tous les fichiers sous un chemin, récursivement, limités à 1 000 (la réponse contient X-Beeuni-Truncated: 1 en cas de troncature) · le contenu d’un fichier à une référence git |
search(query, { content?, ref?, limit? }) |
rechercher des noms de fichiers dans tout le dépôt, ou du contenu avec content: true |
archive(options?) · history(path) |
télécharger une archive tar · l’historique git d’un fichier |
p.git — historique
| méthode | fonction |
|---|---|
commits() |
le journal des commits |
commit(sha) · commitDiff(sha) |
un commit · son diff |
branches() · versionDiff(from, to) |
les branches · le diff entre deux références |
p.changeRequests — cycle de vie et fusion
Une demande de modification (CR) permet de fusionner le travail d’une session dans la branche par défaut.
| méthode | fonction |
|---|---|
list() · get(crId) |
les CR ouvertes · une CR |
diff(crId) · mergePreview(crId) |
son diff · prévisualiser le résultat de la fusion |
open(input) · merge(crId, input?) |
ouvrir · fusionner une CR |
close(crId, input?) · reopen(crId, input?) |
fermer sans fusionner · rouvrir une CR fermée |
requestChanges(crId, input) |
enregistrer des retours, éventuellement transmis à la session d’origine |
p.sessions — et le handle de session
| méthode | fonction |
|---|---|
list() |
les sessions du projet |
create(input?) |
créer une session |
session(sid) |
le handle de session (identique à beeuni.session(id, sid)) |
Le handle de session est au cœur du runtime — voir Sessions.
create(input) accepte connector_bindings indexé par slug de connexion de connecteur.
Chaque valeur désigne un connection_id. Il accepte aussi secrets pour
restreindre les secrets provenant du backend. require_connectors est obsolète et
sans effet : le champ reste accepté (un ancien client n’est jamais rejeté pour
l’avoir envoyé), mais rien ne le lit — une session n’est jamais refusée à sa création
pour un connecteur sans compte utilisable. Voir Comptes et contrôle au moment de
l’appel.
p.approvals — la boîte de réception des approbations de connecteurs
Actions soumises à un contrôle de connecteur en attente d’une décision — alimente
l’interface d’approbation des autorisations (APPROVE / ASK / BLOCK).
| méthode | fonction |
|---|---|
list(options?) · sessionsNeedingInput(options?) |
approbations en attente · sessions bloquées dans l’attente d’une décision |
resolve(executionId, decision, scope?) |
approuver ou refuser une action — decision: 'approve' | 'deny', scope: 'once' | 'session' | 'session_all' |
p.gateway — observabilité des LLM
Journaux de requêtes, agrégats de coût/latence, budgets et clés API de passerelle pour le trafic des modèles de ce projet.
| méthode | fonction |
|---|---|
logs(opts?) · log(logId) |
entrées du journal de requêtes · une entrée du journal |
overview(days?) · series(days?) · breakdown(days?) · sessions(days?) · errors(days?) |
agrégats, coût par session et erreurs sur une période |
budgets() · setBudget(input) · deleteBudget(budgetId) |
lire · créer/modifier · supprimer un budget |
keys() · createKey(name) · revokeKey(keyId) |
lister · générer · révoquer une clé API de passerelle |
playground(prompt, models) |
exécuter un prompt sur un maximum de 6 modèles |
routing.get() · routing.set(policy) · routing.reset() |
lire · remplacer · hériter de la politique de routage |
routing.preview(input) |
résoudre une route sans invoquer de modèle |
Une politique de routage contient un modèle par défaut, un modèle de vision et une chaîne
ordonnée de modèles de repli, chaque modèle étant essayé au plus une fois ; fallbackOn vaut
transient ou any-error.
La passerelle ne passe au modèle de repli suivant que si le modèle actuel a échoué avant de renvoyer la moindre sortie :
transient: une erreur réseau, un délai d’attente dépassé, tout5xx, ou402,403,429.any-error: tout échec, y compris un400.
Un échec après le début de la sortie reste associé à ce modèle. Une requête utilisant votre propre clé fournisseur (BYOK) ne bascule jamais vers un modèle facturé par Beeuni. Chaque modèle de repli utilise ses propres paramètres de génération par défaut.
p.channels — Slack / e-mail / voix
Interfaces de connecteurs permettant à un agent d’agir comme une application Slack, une adresse e-mail, ou de rejoindre un appel vocal en temps réel.
| méthode | fonction |
|---|---|
slack.installation() · slack.mode() · slack.manifest() |
installation actuelle · mode · manifeste de l’application |
slack.connect(input) · slack.disconnect() |
connecter · déconnecter |
slack.getFile(url) · slack.uploadFile(input) |
télécharger · téléverser un fichier via le proxy serveur |
email.installation(connectorSlug?) · email.mode() |
installation actuelle · mode |
email.connect(input) · email.disconnect(...) · email.updatePolicy(input) |
connecter · déconnecter · mettre à jour la politique d’envoi/de réponse |
voice.setBotName(name) |
renommer le bot pendant un appel en cours |
p.modelDefaults — préférences de modèle par défaut
Modèles par défaut définis au niveau du compte, de l’agent et du projet, résolus par la passerelle.
| méthode | fonction |
|---|---|
get() · set(input) · clear(params) |
lire · définir une valeur par défaut · supprimer une surcharge |
p.setDefaultAgent — agent par défaut du projet
p.setDefaultAgent(agentName) vérifie que l’agent est déclaré et activé,
puis le définit comme default_agent dans le beeuni.yaml du projet. Les nouvelles sessions
privilégient cet agent, sauf si un utilisateur en choisit un autre.
p.updateFeatureFlag — indicateurs de fonctionnalités
p.updateFeatureFlag(feature, enabled) active ou désactive un indicateur de fonctionnalité pour le
projet. Passez enabled: null pour supprimer la surcharge et revenir à la
valeur par défaut de la plateforme. Il appelle le PATCH /v1/projects/:id/features canonique.
feature est l’un des FEATURE_FLAG_KEYS (exportés depuis @beeuni/sdk, typé comme
FeatureFlagKey). L’appelant doit disposer de l’autorisation project.settings.write du projet ;
sinon, la route répond 403.
Toutes les routes contrôlées par un indicateur rejettent les requêtes de la même manière lorsque celui-ci est désactivé : HTTP 403
avec { error, code: "feature_disabled", feature }. Utilisez isFeatureDisabledError(error)
pour adapter le traitement et featureDisabledKey(error) pour lire la clé de l’indicateur — ne vous
basez jamais sur le texte du message.
p.updateExperimentalFeature(feature, enabled) est l’alias obsolète. Il
continue d’appeler l’alias de route obsolète PATCH /v1/projects/:id/experimental
pour que les consommateurs liés à une ancienne API déployée continuent de fonctionner. Utilisez
p.updateFeatureFlag dans le nouveau code.
p.sandbox — modèles et builds de snapshots
Configuration de build des sandbox au-delà de sandboxHealth/sandboxTemplates sur le
handle du projet : modèles Dockerfile/image/pool préchauffé et leurs builds de snapshots.
| méthode | fonction |
|---|---|
list() · snapshots() |
sandbox de ce projet · snapshots construits |
rebuildSnapshot(slug?) · fixWithAgent() |
reconstruire un snapshot · demander à un agent de corriger un build défaillant |
createTemplate(input) · updateTemplate(...) · removeTemplate(...) · buildTemplate(...) |
ajouter · modifier · supprimer · construire un modèle |
setProvider(provider) |
demander un changement de fournisseur. null (ou le fournisseur par défaut de la plateforme / le fournisseur déjà actif) s’applique immédiatement ; passer à un autre fournisseur activé lance une transition durable préparation→vérification→activation — le fournisseur actuel continue de servir pendant que l’image préchauffée cible est construite et vérifiée, puis activée. La valeur renvoyée est une union discriminée : kind:'project' (immédiat) ou kind:'preparation' (interroger getProjectSandboxProviderTransition() jusqu’à activated/failed) |
Hooks d’administration de la plateforme (@beeuni/sdk/react)
Ces hooks servent la console d’administration. L’API n’y répond que pour un administrateur
de la plateforme. Chaque mutation invalide les requêtes ['admin', 'accounts'].
| Hook | Fonction |
|---|---|
useAdminRole(userId, options?) |
lire le rôle de l’appelant depuis GET /user-roles → { isAdmin, role }. userId sert de clé de cache. L’absence de userId désactive la requête. Recharge au montage et à la prise de focus, afin qu’un rôle révoqué cesse de conditionner l’accès en une navigation. |
useAdminGrantCredits() |
mutation { accountId, amount, description, isExpiring } : ajouter du crédit au portefeuille. POST /admin/api/accounts/:id/credits. Déplace de l’argent : confirmer d’abord dans l’interface. |
useAdminDebitCredits() |
mutation { accountId, amount, description } : retirer du crédit du portefeuille. POST /admin/api/accounts/:id/credits/debit. Déplace de l’argent : confirmer d’abord dans l’interface. |
useAdminSetTier() |
mutation { accountId, tier } : définir le niveau de l’offre. |
useAdminGrantTrial() |
mutation { accountId, tierKey, seats, durationDays, creditGrant?, note? } : accorder ou remplacer un essai. Le compte se comporte comme tierKey jusqu’à la fin de la période. creditGrant ajoute aussi du crédit au portefeuille. |
useAdminRevokeTrial() |
mutation { accountId } : mettre fin immédiatement à un essai actif. Répond 400 si aucun essai n’est actif. |
Accès direct
beeuni.runtime() renvoie le client REST runtime typé pour la sandbox
active.
Sur un client créé par createScopedBeeuni (@beeuni/sdk/server), il lève une exception
— le runtime « actif » global au processus est la sandbox d’une autre requête dans un
serveur multi-tenant, ce qui entraîne une fuite entre tenants. Utilisez plutôt
beeuni.session(pid, sid).runtime, limité à la session (appelez d’abord ensureReady()), qui
résout la sandbox propre à cette session.
Modules
Les modules indépendants de tout framework derrière la façade du client et les hooks React. Utilisez-les lorsque vous avez besoin d’une opération sans la façade, d’une fonction utilitaire pure ou d’une couche d’isolation réservée à Node. Chaque module indique un niveau de stabilité pour vous aider à choisir sur quoi vous appuyer.
| Niveau | Signification |
|---|---|
| Canonique | Importez depuis la racine @beeuni/sdk. À utiliser pour tout nouveau code. |
| Pris en charge | Un sous-chemin dédié (@beeuni/sdk/react, @beeuni/sdk/server). Pleinement pris en charge, non obsolète. |
| Alias obsolète | Un ancien sous-chemin qui fonctionne encore. Il réexporte du code déjà exporté par la racine. Importez plutôt depuis la racine. |
| Interne | Hors semver. Ne l’importez pas dans le code hôte. |
Le point d’entrée racine est canonique. Chaque nom indépendant de tout framework ci-dessous peut être importé
directement depuis @beeuni/sdk :
import { files, getSessionHealth, getClient, authenticatedFetch, backendApi } from '@beeuni/sdk';
Modules canoniques
| Module | Fonction |
|---|---|
| Fichiers | Opérations sur les fichiers de l’espace de travail : lister, lire, rechercher, écrire |
| Runtime de session | Sonde d’état et générateurs d’URL d’aperçu/proxy |
| Client runtime | Le client REST runtime typé et l’ensemble de ses types |
| Authentification | authenticatedFetch et accesseurs de jetons |
| REST des projets | Les fonctions REST brutes encapsulées par la façade |
| Client API | backendApi, le client HTTP typé de bas niveau |
| Tours | Regroupement des messages en tours, calcul des coûts et des statuts — voir Tours |
| Transcriptions | formatTranscript, un export Markdown côté client |
| Listes de l’éditeur | Les listes d’agents et de modèles de l’éditeur de session : lesquels proposer, lesquels exécuter |
Fichiers
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}`);
},
});
Les téléversements de plus de 64 Kio franchissent la frontière du sandbox par blocs vérifiés. Le callback de progression s’exécute après l’arrivée de chaque bloc dans le système de fichiers de la session.
uploadNativeFile({ uri, name, type? }, targetPath, baseUrl) téléverse un fichier de l’appareil
depuis React Native en une seule requête. Le runtime diffuse les octets depuis
uri, de sorte qu’ils n’entrent jamais dans le tas JS. Il utilise la même authentification, la même échéance et la même
réexécution 401 que files.upload. Il ne découpe pas le fichier en blocs.
fetchProjectArchive, fetchCostExportCsv et les appels de version du sandbox passent
par le même transport. Un échec lève une exception ApiError avec status.
files.write(path, blob) remplace le fichier à path et échoue si path est un
dossier. files.create(path) crée un fichier vide sans jamais écraser : lorsqu’un
fichier ou dossier existe déjà à path, il lève 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 cible le sandbox actif globalement. Si votre hôte exécute plusieurs
sessions à la fois, appelez plutôt s.files sur le handle de session. Il cible toujours
le sandbox propre à cette session. Voir Sessions.
Utilitaires du runtime de session
import { getSessionHealth, isRuntimeReady } from '@beeuni/sdk';
const result = await getSessionHealth();
if (result.ok && isRuntimeReady(result.health)) {
// the sandbox daemon is ready
}
getSessionHealth ne lève jamais d’exception pour un statut non-2xx. Il renvoie
{ status, ok, health, body } et vous laisse décider de la signification du statut. Le
même module exporte les utilitaires d’URL qui réécrivent la sortie localhost d’un agent
en une URL proxy accessible : detectLocalhostUrls, rewriteLocalhostUrl,
proxyLocalhostUrl, parseLocalhostUrl et buildWebProxyUrl.
Client runtime
import { getClient } from '@beeuni/sdk';
const client = getClient();
const { data } = await client.session.list({ limit: 100 });
getClient() renvoie le client de compatibilité runtime typé pour le sandbox actif,
avec l’authentification déjà injectée. Préférez beeuni.session(pid, sid).runtime, le
même client limité à une session, au client global getClient() lorsque votre
hôte exécute plusieurs sessions.
Utilitaires d’authentification
import { authenticatedFetch, getAuthToken } from '@beeuni/sdk';
const res = await authenticatedFetch(`${runtimeUrl}/beeuni/health`);
const token = await getAuthToken();
Le jeton provient de la fonction getToken que vous avez passée à createBeeuni.
La plupart du code applicatif n’a pas besoin de ce module : les couches de fichiers, de session et de façade
assurent déjà l’authentification pour vous.
Client API
import { backendApi } from '@beeuni/sdk';
const data = await backendApi.get('/some/endpoint');
await backendApi.post('/some/endpoint', { name: 'x' });
backendApi est le client HTTP typé sur lequel repose chaque fonction REST. Utilisez-le
uniquement pour un endpoint qui n’a pas encore de wrapper typé.
Listes d’agents et de modèles de l’éditeur
Construisez les sélecteurs d’agent et de modèle d’un éditeur de session avec les mêmes règles que l’application web Beeuni. Chaque fonction est pure : récupérez les entrées avec le client, puis passez-les à la fonction.
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 renvoie explicit: undefined lorsque l’éditeur utilise
sa valeur par défaut. model est la clé à afficher et à envoyer. Le
id de chaque modèle aplati est la référence stockée par une sélection ; modelRefToKey(ref, gatewayEnabled) reconvertit une
référence stockée (un épinglage de session, une liaison de canal, le model d’un déclencheur) en
clé.
Sous-chemins pris en charge
| Sous-chemin | Fonction |
|---|---|
@beeuni/sdk/react |
Hooks React — voir Hooks React |
@beeuni/sdk/server |
Configuration limitée à une requête pour les backends multilocataires |
@beeuni/sdk/wire-message-id |
L’horloge des identifiants de messages du protocole runtime seule (un module, aucun import). La racine exporte les mêmes noms |
Identifiants de messages du protocole
Le messageId d’un prompt est sa position dans la transcription. runtime ordonne
les messages selon msg_ + une horloge de 48 bits (Date.now() * 0x1000, les 48 bits de poids faible) +
14 caractères base62, et l’horloge revient à zéro toutes les 2^36 ms (environ 2,2 ans).
Ne l’encodez jamais manuellement.
import { mintWireMessageId } from '@beeuni/sdk';
// `after`: the ids already in this session's transcript.
const messageId = mintWireMessageId({ after: transcriptIds });
La création est antidatée de deux minutes, puis avancée d’un tick au-delà de l’identifiant le plus récent
dans after qui n’est pas en avance de plus d’une heure. Un appelant qui conserve la position la plus récente
sous forme d’horloge plutôt que d’identifiants utilise mintWireMessageIdAbove({ nowMs, newestKnownTime }), which returns { id, time }. newestWireIdClock(ids)
pour trouver cette horloge. Chaque comparaison s’effectue sur l’anneau, de sorte que les identifiants de part et d’autre d’un
retour à zéro conservent leur ordre réel.
L’horloge de 48 bits revient à zéro tous les ~2,2 ans ; ne comparez donc jamais deux horloges avec >
ou <= : un identifiant créé juste après un retour à zéro est numériquement inférieur à un identifiant créé
juste avant. Utilisez wireIdClockDelta(clock, reference), la distance signée
sur l’anneau (positive lorsque clock est en avance), et maxWireIdClock(clocks) pour
le plus récent parmi plusieurs :
import { maxWireIdClock, wireIdClockDelta } from '@beeuni/sdk/wire-message-id';
const floor = maxWireIdClock([transcriptNewest, deliveredNewest]);
const stale = floor !== null && wireIdClockDelta(clientClock, floor) <= 0n;
Isolation côté serveur
createBeeuni stocke sa configuration, y compris la fonction de jeton, dans une
variable unique à l’échelle du processus. Cela convient à un onglet de navigateur, à une CLI ou à un
serveur monolocataire. Ce n’est pas sûr pour un serveur Node qui traite des requêtes simultanées
pour différents utilisateurs, car le dernier appel à createBeeuni prévaut pour
toutes les requêtes en cours. @beeuni/sdk/server corrige cela grâce à une isolation par
requête :
import { createScopedBeeuni } from '@beeuni/sdk/server';
export async function handler(req: Request) {
const beeuni = createScopedBeeuni({ backendUrl, getToken: () => tokenFor(req) });
return beeuni.projects.list();
}
createScopedBeeuni et runWithBeeuni isolent la configuration par requête avec
AsyncLocalStorage de Node. N’importez jamais @beeuni/sdk/server dans un bundle
pour navigateur : il importe statiquement node:async_hooks.
Le runtime() de premier niveau d’un client à portée limitée lève une exception (il résoudrait le
sandbox d’un autre locataire). Accédez au runtime d’une session précise via
beeuni.session(pid, sid).runtime après await s.ensureReady().
Alias obsolètes
Une vingtaine d’anciens sous-chemins fonctionnent encore : /files, /turns, /session, /auth,
/projects-client, /api-client, /config, /event-stream,
/opencode-client, /platform-client, entre autres. Chacun réexporte du code que le
point d’entrée racine @beeuni/sdk exporte déjà. Ils continuent de fonctionner afin qu’aucun élément existant
import breaks, but new code should import from the root.
Modules internes
@beeuni/sdk/internal/* contient les stores zustand utilisés en interne par le runtime propre à apps/web
— état de synchronisation des sessions, suivi du runtime actif et gestion des
reconnexions. Ce sous-chemin est explicitement hors semver. Ne l’importez pas dans
le code hôte ; les hooks React exposent déjà l’état dont vous
avez besoin.
Tours
Des fonctions simples qui regroupent les messages de session en tours et classent chaque
partie de message. Utilisez-les pour construire un moteur de rendu de chat personnalisé plutôt que celui de
référence dans apps/web. Ni React ni DOM : chaque export est une simple
fonction ou un type, utilisable sans risque depuis n’importe quel hôte.
import { classifyPart, classifyTurn, toolInfo, toolViewModel } from '@beeuni/sdk';
Importez chaque fonction depuis le point d’entrée racine @beeuni/sdk. Le
sous-chemin @beeuni/sdk/turns fonctionne encore, mais c’est un alias obsolète. Le nouveau
code doit utiliser le point d’entrée racine — voir Distribution.
Classer une partie
classifyPart(part) normalise l’un des 12 types de parties du format de transcription
Beeuni (beeuni.transcript.v1, BEEUNI_TRANSCRIPT_SCHEMA) en un
ClassifiedPart — une union discriminée par kind. Chaque variante résout déjà les
champs nécessaires au rendu : état de l’outil, sortie JSON analysée, détection d’images.
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 |
structure |
|---|---|
text |
{ id, text, synthetic } — ignorer les parties synthetic ; elles marquent le prompt synthétique du mode 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 type de partie inconnu de cette version du SDK |
Une partie reçue non reconnue devient unknown à l’exécution au lieu de
lever une exception. Cela permet à un ancien client de communiquer avec un serveur plus récent.
Une partie d’outil est classée dans 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) en construit un directement à partir d’une partie d’outil. Lisez ces champs
plutôt que le state.metadata propre à un harness : la même carte affiche alors un
edit runtime (filePath, filediff) et un edit pi (path, edits,
un patch unifié).
Certains outils (web_search, image_search, appels de connecteurs) signalent
state.status: 'completed' même lorsque leur corps JSON contient
success: false. classifyPart le détecte et définit aussi ToolView.status sur
'error' dans ce cas.
classifyTurn(message) classe chaque partie d’un message de l’assistant et
renvoie un ClassifiedTurn avec trois champs :
parts— chaque partie, classéeerror— issu demessage.info.error, le cas échéantisEmpty— vrai lorsque le tour ne comporte aucune erreur ni aucune partie au contenu visible
Métadonnées des outils
toolKind(name) est la taxonomie unique des outils : elle associe le nom d’outil de n’importe quel harness
(write de pi, oc-apply_patch d’runtime, pty_spawn d’un plugin) à un
ToolKind — read, edit, write, bash, web_search, task,
question, … ou other. Les familles de narration, les modèles de vue, les catégories
toolInfo et le groupe d’outils de contexte en dérivent tous. inputPath(input)
lit le chemin d’un outil de fichier depuis filePath, file_path ou path.
toolKind('oc-apply_patch'); // 'apply_patch'
toolKind('pty_spawn'); // 'pty'
inputPath({ path: 'app.py' }); // 'app.py'
Deux autres fonctions de recherche décrivent toutes deux un outil. Ne les confondez pas.
toolInfo(name)— sans icône, renvoie{ label, category }.classifyPartl’utilise en interne.ToolCategoryest'shell' | 'files' | 'search' | 'edit' | 'web' | 'task' | 'other'.getToolInfo(name, input)— avec prise en charge des icônes, renvoie{ icon, title, subtitle }pour l’interface de référence des cartes d’outils. Le sous-titre provient de l’entrée de l’outil, par exemple un chemin de fichier ou une requête de recherche.
toolInfo('bash'); // { label: 'Shell', category: 'shell' }
getToolInfo('write', { filePath: '/workspace/main.go' });
// { icon: 'file-pen', title: 'Write', subtitle: 'main.go /workspace' }
Les deux fonctions reconnaissent les préfixes des noms d’outils ; les familles d’outils des plugins Beeuni
(agent_*, session_*, task_*, trigger_*, project_*, pty_*) sont donc résolues
sans mise à jour du registre. Un nom d’outil inconnu ne lève jamais d’exception — il se rabat
sur humanizeToolName(name) avec la catégorie 'other'.
Modèles de vue des outils
toolViewModel(classifiedTool) associe une partie d’outil classée à une structure conçue
pour une famille d’outils. Une interface peut alors lui appliquer un rendu spécifique plutôt que de l’afficher comme un
bloc JSON générique.
const vm = toolViewModel(classifiedTool);
if (vm.kind === 'shell') {
render(vm.command, vm.stdout, vm.exitCode);
}
kind |
structure | outils |
|---|---|---|
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? } |
tout le reste, toujours affichable sans risque |
DiffLine est { type: 'added' | 'removed' | 'unchanged', text }. Les champs de type chaîne
sont plafonnés pour qu’une sortie d’outil volumineuse ne perturbe jamais le rendu : 4000
caractères pour le JSON mis en forme, 256 Ko avant l’exécution d’un diff.
Regrouper les messages en tours
Un tour associe un message utilisateur aux messages de l’assistant qui y ont répondu. C’est l’unité qu’une interface de chat affiche comme un échange.
import { groupMessagesIntoTurns, collectTurnParts, type TurnLike } from '@beeuni/sdk';
const turns: TurnLike[] = groupMessagesIntoTurns(messages);
for (const turn of turns) {
const parts = collectTurnParts(turn);
}
groupMessagesIntoTurns relie chaque message de l’assistant à son message utilisateur
parent. Il se rabat sur l’ordre des messages lorsqu’un lien parent manque. Il
rattache aussi un message de l’assistant orphelin — sans parent et précédant
tous les messages utilisateur — au premier tour, et non au dernier.
Fonctions utilitaires associées :
findLastTextPart(parts)— le texte de la réponse finale du tourturnHasSteps(parts)— vrai si une partietool,compaction,snapshotoupatchexisteisShellMode(turn)/getShellModePart(turn)— un tour constitué d’un prompt synthétique déclenchant un appelbash
Gardes de type
Affinez le type d’une partie par 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
Également disponibles : isReasoningPart, isFilePart, isAgentPart,
isCompactionPart, isSnapshotPart, isPatchPart, isStepPart
(step-start et step-finish).
État et erreurs
import { getWorkingState, getTurnStatus, formatDuration } from '@beeuni/sdk';
const status = getTurnStatus(parts, childMessages); // "Running commands..."
formatDuration(4300); // "4s" — durations under 1s return ''
getTurnStatus parcourt les parties d’un tour pour trouver la dernière ligne d’état. Lorsque la dernière
partie est une délégation task en cours, passez childMessages pour que l’état affiche
l’activité réelle du sous-agent plutôt qu’une ligne générique « Délégation en cours… ».
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
Totaux des coûts et des 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"
Les deux fonctions lisent les totaux des coûts et des tokens depuis les parties step-finish. Lorsqu’une
partie indique zéro, elles estiment le coût à partir du nombre de tokens à l’aide d’un
ModelPricingLookup.
Les messages liés à un abonnement ChatGPT/Codex contribuent à hauteur de $0.00, y compris les messages
historiques dont les coûts d’exécution sont non nuls. L’utilisation des tokens et du contexte reste visible.
Les sessions mixtes conservent les frais des messages d’API payants. Les modèles de l’API OpenAI restent
facturables, y compris ceux dont le nom contient codex.
Sessions enfants et demandes en attente
L’arbre de conversation d’une session de projet (la racine et les conversations des sous-agents
qu’elle a créées) provient de sa liste runtime_sessions. Ces
fonctions utilitaires le lisent, en privilégiant les noms actuels plutôt que ceux d’avant 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
Un appel d’outil task délègue à une session enfant. Ces fonctions utilitaires relient un
tour parent aux messages propres à cet enfant.
import { getChildSessionId, getChildSessionToolParts } from '@beeuni/sdk';
const childId = getChildSessionId(taskToolPart);
const steps = getChildSessionToolParts(childMessages);
Associez une demande d’autorisation ou une question en attente à son appel d’outil et déterminez quelles parties d’outil masquer tant qu’une demande est active :
import { getPermissionForTool, getHiddenToolParts, isToolPartHidden } from '@beeuni/sdk';
const permission = getPermissionForTool(permissions, callID);
const hidden = getHiddenToolParts(activePermission, activeQuestion);
Mise en forme et listes
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"
Les fonctions utilitaires de liste de sessions opèrent sur les mêmes données de session :
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);
État de nouvelle tentative : getRetryInfo(sessionStatus) renvoie { attempt, message, next, details? } when status.type === 'retry', with message limité à 60
caractères. details préserve une enveloppe structurée de passerelle LLM lorsqu’elle est présente :
le fournisseur final, le code de passerelle, l’identifiant de requête, la suggestion, l’état en amont et
les échecs des candidats dans l’ordre. Chaque échec de candidat contient attempt,
provider, routeModel, resolvedModel, stage, éventuellement status, code
et message. Les anciennes nouvelles tentatives en texte brut renvoient details: undefined.
getRetryMessage(sessionStatus) renvoie le message complet extrait de son enveloppe. Lorsque
runtime ne conserve que ce message, le composite de passerelle inclut toujours
l’identifiant de requête ainsi que le fournisseur, le modèle résolu, le statut HTTP, le code
et le message de longueur limitée de chaque candidat.
Types structurels
Les fonctions de regroupement et de statut acceptent des types structurels minimaux —
PartLike, MessageInfoLike, TurnLike, ToolStateLike,
SessionStatusLike — plutôt que les types concrets de transcription.
Vos propres structures de messages et de parties sont transmises sans modification tant qu’elles correspondent
aux champs requis. classifyPart et classifyTurn font exception.
Leur typage repose sur l’union Beeuni Part (beeuni.transcript.v1), de sorte que leur
vérification d’exhaustivité détecte tout nouveau type de partie lors de la compilation.
Distribution
npm install @beeuni/sdk
Le package est distribué en ESM compilé avec des déclarations de types TypeScript complètes.
react et @tanstack/react-query sont des dépendances homologues facultatives. Si vous
utilisez @beeuni/sdk/react, installez les deux.
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
Points d’entrée et stabilité
Le point d’entrée racine, @beeuni/sdk, est canonique. Il exporte toute
l’interface indépendante des frameworks et fonctionne dans les navigateurs, Node 18+, Bun et les environnements
d’exécution edge.
| Point d’entrée | Niveau | Contrat |
|---|---|---|
@beeuni/sdk |
Canonique | Indépendant des frameworks. N’importe jamais React ni node:*. |
@beeuni/sdk/react |
Pris en charge | Hooks React. Le seul point d’entrée qui importe React. |
@beeuni/sdk/server |
Pris en charge | Isolation de la configuration par requête pour les serveurs Node et Bun, via node:async_hooks. Ne jamais l’inclure dans un bundle destiné au navigateur. |
Anciens sous-chemins (/projects-client, /turns, /files, et d’autres) |
Obsolètes | Fonctionnent toujours. Chacun réexporte depuis la racine. Importez plutôt depuis la racine. |
@beeuni/sdk/internal/* |
Interne | Utilisé uniquement par l’application web Beeuni. Ce n’est pas une API prise en charge. |
Bundles CDN
Le package fournit également deux bundles pour navigateur, générés par tsup : un bundle ESM
(dist/beeuni.esm.min.js) et un bundle global IIFE (dist/beeuni.global.js) qui
définit 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 expose le même point d’entrée racine que l’import npm :
Beeuni.createBeeuni, Beeuni.classifyTurn, Beeuni.ApiError.
Voir aussi
- SDK — installation et première session.
- Sessions — cycle de vie, streaming et gestion des erreurs.
- Hooks React — la couche réactive construite sur ces modules.
Accès de l’agent au dépôt
La configuration de l’agent accepte repository_access?: boolean (par défaut true).
Définissez false pour exécuter de nouvelles sessions sans accès au dépôt du projet ni à l’API du dépôt.
Les autorisations Git, de secrets, de connecteurs et d’outils restent distinctes. Les sessions existantes conservent leur politique enregistrée.
AgentConfigBlock.workspace est obsolète. Le SDK convertit les anciennes valeurs branch/runtime vers le champ booléen.
Une écriture avec l’ancienne valeur read nécessite un choix explicite repository_access ; elle n’active pas l’accès au dépôt en lecture seule.
Accès aux fournisseurs et aux modèles
Consultez beeuni.projects.modelAccess(projectId). Modifiez une cible avec beeuni.projects.setModelAccess(projectId, { target: 'provider' | 'model', id, enabled }).
Utilisez l’identifiant de fournisseur beeuni pour Beeuni Managed Models, ou un identifiant de fournisseur du catalogue pour BYOK, Codex et les fournisseurs personnalisés. Utilisez l’identifiant complet du modèle dans le protocole de la passerelle. La désactivation d’un fournisseur s’applique aux futurs modèles et préserve les préférences individuelles des modèles ainsi que les identifiants enregistrés.
Le modèle par défaut actuel et son fournisseur nécessitent un remplacement avant leur désactivation (409 cannot_disable_default). Les requêtes directes à la passerelle visant des cibles désactivées échouent avec model_disabled ou provider_disabled. Les requêtes en amont déjà en cours se terminent normalement. L’indicateur enforced de la réponse est faux lorsque le projet utilise runtime natif plutôt que la passerelle.
Les utilisateurs de React utilisent useModelAccess(projectId) depuis @beeuni/sdk/react. Sa mutation setEnabled(change) actualise le catalogue de gestion et le sélecteur de session.