Vai al contenuto
BeeuniBeeuni
Italiano
Esc
↑↓naviga↵apri⌘Janteprima
In questa pagina

Riferimento SDK

L'intera superficie API di @beeuni/sdk — metodi client, moduli, turni e distribuzione.

Questa pagina descrive l’intera superficie API di @beeuni/sdk: tutti i metodi del client, i moduli indipendenti dai framework, gli helper per i turni e le modalità di distribuzione del pacchetto. Usa SDK per iniziare e Sessioni per approfondire il ciclo di vita delle sessioni.

Il client

createBeeuni(config) restituisce un client. Ogni metodo è una chiamata tipizzata all’API della piattaforma. Gli handle project(id) e session(pid, sid) associano gli ID così non devi mai ripeterli.

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

Account — beeuni.accounts

metodo funzione
list() · get(accountId) account di cui fai parte · un account
create({ name }) · updateName(accountId, name) crea · rinomina un account
branding.get(accountId) · branding.update(accountId, { app_name }) · branding.uploadAsset(accountId, kind, file) · branding.removeAsset(accountId, kind) · branding.reset(accountId) branding dell’organizzazione (Enterprise): logo / icona / favicon e nome del prodotto personalizzati; kind è logo · icon · favicon, oppure logo_dark · icon_dark · favicon_dark per la variante con tema scuro
members(accountId) · invite(accountId, input) elenca i membri · invitane uno
updateMemberRole(accountId, userId, role) · removeMember(accountId, userId) assegna il ruolo nell’account · rimuovi un membro
invites(accountId) inviti in sospeso
cancelInvite(accountId, inviteId) · resendInvite(accountId, inviteId) annulla · reinvia un invito in sospeso
leave(accountId) lascia l’account

accounts.tokens genera chiavi API con ambito account (beeuni_pat_...). Vedi Autenticazione SDK per il modello completo dei token.

metodo funzione
tokens.list(accountId?, options?) elenca le chiavi API — quelle dell’intero account, o solo le tue con { mine: true }
tokens.create(input) generane una — { accountId?, name, expiresAt?, projectId? }
tokens.revoke(tokenId, accountId?) revocane una

accounts.audit è il registro di ricostruzione aziendale. Combina le richieste API autenticate con gli eventi semantici di sessioni, connettori, approvazioni e computer.

metodo funzione
audit.log(accountId, filters?) elenca gli eventi per progetto, sessione, attore, origine, esito, richiesta, correlazione, risorsa, azione o tempo
audit.export(accountId, filters?) esporta lo stesso flusso di eventi filtrato come CSV o JSONL
audit.webhooks.list/create/update/remove(...) gestisci i webhook SIEM firmati per il flusso centralizzato

Ogni evento include project_id, session_id, actor_type, source, outcome, request_id, trace_id e correlation_id quando l’azione li fornisce. L’API non memorizza corpi delle richieste, prompt, segreti, credenziali o argomenti non elaborati dei connettori nell’evento centralizzato. Gli eventi dei connettori possono includere un’anteprima limitata degli argomenti che oscura i campi riconducibili a credenziali e i dati opachi.

Assegnazioni di accesso

Beeuni ha un unico tipo di record di concessione: un’assegnazione. Associa un principal (user, group, service_account o pending) a un ruolo, in un ambito (account o un project), eventualmente limitato a un oggetto (agent, skill, secret, app o trigger) ed eventualmente contenente un expires_at. L’accesso di gruppo, l’accesso per risorsa e le associazioni a ruoli personalizzati sono tutte assegnazioni. Vedi Account e accesso per il modello.

La superficie REST canonica è:

Metodo + percorso Funzione
GET /v1/accounts/{accountId}/iam/assignments elenca le assegnazioni, filtrate per principal, ambito, oggetto o ruolo
POST /v1/accounts/{accountId}/iam/assignments crea un’assegnazione
DELETE /v1/accounts/{accountId}/iam/assignments/{assignmentId} revoca un’assegnazione
GET /v1/accounts/{accountId}/iam/permissions il catalogo delle autorizzazioni, come dati
GET /v1/accounts/{accountId}/iam/roles · …/roles/{roleId}/permissions ruoli · autorizzazioni di un ruolo

L’SDK le espone come listAssignments, createAssignment, revokeAssignment e listPermissions. Una riga del catalogo contiene action, scope_type, resource_type, delegable, description, area, level e implies — leggila invece di codificare le stringhe delle azioni direttamente nel codice.

L’assegnazione di un ruolo personalizzato richiede l’abilitazione rbac dell’account; in sua assenza, la route risponde 402 con code: "entitlement_required".

Inviti all’account — beeuni.accountInvites

Accessibili con il solo token di invito — la persona invitata potrebbe non essere ancora un membro.

metodo funzione
listMine() tutti gli inviti in sospeso e non scaduti indirizzati alla tua email, con il workspace e gli eventuali progetti a cui danno accesso
describe(inviteId) · accept(inviteId) · decline(inviteId) visualizza l’anteprima · accetta · rifiuta un invito

Progetti — beeuni.projects

metodo funzione
list() · listForAccount(accountId) i tuoi progetti · progetti in un account
get(id) · detail(id) riepilogo · dettagli completi
create(input) · createRepo(input) da un repo_url esistente · nuovo repository GitHub vuoto
provision(input) nuovo progetto su un nuovo repository gestito da Beeuni, inizializzato con un template di partenza — { name, account_id?, seed_starter?, starter_template?, marketplace_items?, source_item_id?, idempotency_key? }
update(id, input) · archive(id) aggiorna le impostazioni · archivia
llmCatalog(id) · modelPicker(id) catalogo dei modelli completo · compatto per un selettore
sandboxTemplates(id) · sandboxHealth(id) template di build della sandbox · stato della build
sessions(id) · createSession(id, input?) elenca le sessioni visibili · crea una sessione

provision crea un nuovo progetto; non avvia la sandbox di un progetto esistente. Avvia invece una sessione — vedi Sessioni.

Invia idempotency_key quando è possibile un nuovo tentativo — un ricaricamento, una seconda scheda, un timeout dopo il quale hai riprovato. provision genera un repository gestito completamente nuovo a ogni chiamata, quindi senza una chiave tutti questi casi creano progetti duplicati reali. Riutilizza una chiave per ogni tentativo di un’unica creazione logica e le ripetizioni restituiscono il progetto creato dal primo tentativo (201, stessi project_id, push_token: null). La chiave identifica il tentativo, non il payload — riutilizzarla con un name diverso restituisce il primo progetto e ignora il nuovo valore, quindi genera una nuova chiave per ogni creazione distinta. Creare un secondo progetto con lo stesso nome e senza chiave funziona comunque.

Una ripetizione che arriva mentre la prima chiamata sta ancora effettuando il provisioning riceve 409 con code: 'provision_in_flight' anziché un project_id che quella chiamata potrebbe ancora annullare. Riprova con la stessa chiave.

project(id).sessions.list({ scope: 'project' }) è un inventario del ciclo di vita per un chiamante con autorizzazioni di gestione del progetto. Aggiunge le sessioni accessibili non disponibili, warm e con eliminazione logica, con metadati sulla proprietà e sullo stato di esecuzione. Entrambi gli ambiti di elenco escludono tutte le sessioni che il chiamante non può aprire.

sessions.list e sessions.listPage accettano anche i filtri di gerarchia e attribuzione. Senza di essi, l’elenco rimane piatto e invariato.

opzione funzione
parent: 'root' Solo sessioni di primo livello. Ogni riga contiene child_count.
parent: '<sessionId>' Le sessioni figlie di quella sessione, dalla più recente.
startedBy: 'me' | 'others' | 'automated' Filtra per initiator, rispetto al chiamante.
q Ricerca senza distinzione tra maiuscole e minuscole su titolo, etichetta di avvio, slug del trigger e prefisso dell’ID di sessione, in tutte le sessioni che il chiamante può aprire. Con parent: 'root', una sessione radice che corrisponde tramite una figlia ha search_match: 'child'.

Ogni riga di sessione ha parent_session_id e initiator ({ type: 'member' | 'trigger' | 'channel' | 'api' | 'system', id, label }). initiator indica chi ha avviato l’intera esecuzione; una sessione figlia copia quello della sessione padre. sessionParentId(session) legge parent_session_id, poi il precedente metadata.spawned_by_session. Un cursore è valido solo per l’insieme di filtri che lo ha generato.

GitHub — beeuni.github

Installazione della GitHub App e collegamento dei repository con ambito account, non con ambito progetto.

metodo funzione
getInstallation(accountId) · listInstallations(accountId) installazione di questo account · installazioni accessibili all’utente
saveInstallation(input) · deleteInstallation(accountId, installationId?) registra · scollega un’installazione
listLinkableInstallations(input) installazioni che l’utente GitHub autorizzato può collegare; ogni voce contiene linked_to_other_accounts, il numero di altri account Beeuni che la possiedono — mai i loro nomi
listRepositories(accountId, installationId?) · listRepositoryBranches(...) repository visibili all’installazione · branch e branch predefinito di GitHub
linkRepository(input) Importa un repository come progetto usando un’installazione GitHub autorizzata.
replaceProjectRepository({ project_id, repo_url, expected_repo_url, github_token }) sostituisce il repository GitHub di un progetto esistente. Usa github_token con accesso Contents in lettura/scrittura, oppure installation_id più github_user_token temporaneo per verificare l’accesso come amministratore dell’organizzazione e concedere l’accesso solo a questo repository tramite la GitHub App. copy_shared_secrets_from_project_id più copy_shared_secret_identifiers copia i segreti runtime condivisi selezionati nella stessa transazione. Un expected_repo_url obsoleto restituisce 409. Il vecchio repository rimane su GitHub. Le nuove sessioni usano il repository sostitutivo; quelle esistenti mantengono il proprio checkout.

Questo elenco contiene solo connessioni reali degli account. “Beeuni managed” non è una di queste — è il backend dell’istanza descritto di seguito.

Backend git dell’istanza — beeuni.gitBackend

Un unico proprietario con credenziale per l’intero deployment, usato per i repository gestiti da Beeuni. Non è mai una connessione di account e non compare mai in beeuni.github.listInstallations.

metodo funzione
get() { configured, kind: 'app' | 'pat' | null, owner } — leggibile da qualsiasi utente autenticato; espone solo il login del proprietario già presente in ogni repo_url gestito

Fatturazione — beeuni.billing

Legge crediti, abbonamento, piano e cronologia delle transazioni. Usa il pagamento e la gestione della fatturazione Beeuni per i pagamenti e gli acquisti di crediti.

metodo funzione
accountState(accountId?) · accountStateMinimal(accountId?) stato di fatturazione completo · minimo
transactions(params?) · transactionsSummary(params?) cronologia · totali riepilogativi
creditBreakdown(accountId?) · usageHistory(params?) saldo crediti per fonte · utilizzo nel tempo
sessionCosts.list(options?) · sessionCosts.get(sessionId, options?) record paginati dei costi delle sessioni · registro dettagliato di una sessione
tierConfigurations() livelli di piano disponibili
checkout.createSession(input) · checkout.confirmSession(sessionId, accountId?) Deprecati. Rifiutano con ENDPOINT_RETIRED. Rimossi nella prossima versione principale.
subscription.createPortalSession(...) · subscription.cancel(...) · subscription.reactivate(...) apre il portale clienti · annulla · riattiva
subscription.cancelScheduledChange(...) · prorationPreview(...) annulla · mostra un’anteprima del cambio di piano
subscription.scheduleDowngrade(...) Deprecato. Rifiuta con ENDPOINT_RETIRED. Cambia il piano nel portale clienti. Rimosso nella prossima versione principale.
credits.purchase(input) · credits.autoTopupSettings(...) · credits.configureAutoTopup(...) acquisto una tantum · legge · configura la ricarica automatica

sessionCosts.list() accetta accountId, projectId, limit e offset. Ogni riga combina il costo LLM definitivo e il costo di calcolo della sandbox fatturato. sessionCosts.get() aggiunge l’utilizzo dei modelli e il registro con distinzione tra LLM e calcolo. L’elenco include un totale di riconciliazione per i costi senza sessione.

Condivisioni della sandbox — beeuni.sandboxShares

Link di condivisione pubblici per una porta esposta della sandbox. Limitati alla sandbox, non al progetto.

metodo funzione
list(sandboxId) link di condivisione attivi
create(input) ne crea uno — { sandboxId, port, ttl?, label? }
revoke(sandboxId, token) ne revoca uno

Catalogo del marketplace — beeuni.marketplace

Consultazione del catalogo pubblico, in sola lettura — distinta da project(id).marketplace, che installa un elemento in un progetto.

metodo funzione
items(options?) · item(id) · itemFile(id, path) consulta · un elemento · un file all’interno di un elemento
marketplaces() · featured() tutti i marketplace · quelli in evidenza
sources.list() · sources.add(input) · sources.remove(id) elenca · aggiunge · rimuove una fonte

Notifiche — beeuni.notifications

Le notifiche del chiamante, per tutti gli account e i progetti. Ogni persona che ha effettuato l’accesso ha una casella di posta, un record di preferenze e sottoscrizioni Web Push per i propri browser. Ogni metodo richiede la credenziale di una persona: un account di servizio riceve 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 } } });
metodo funzione
list({ limit?, before? }, { signal? }) la pagina più recente: { notifications, unread_count, next_before }. limit va da 1 a 50 (valore predefinito 20). Passa next_before come before per la pagina successiva. Le righe non più visibili al chiamante vengono escluse. Un errore non richiama il gestore degli errori dell’host.
markRead({ ids }) · markRead({ all: true }) · markRead({ sessionId }) segna come lette da 1 a 100 righe, tutte le righe o tutte le righe di una sessione. Modifica solo le righe del chiamante. Restituisce { updated, unread_count }.
preferences() · updatePreferences({ kinds }) legge · modifica la scelta di push ed email per tipo. Restituisce { kinds, email_available }. Una patch modifica solo i tipi e i canali che specifica.
webPushPublicKey() { public_key }: il applicationServerKey per pushManager.subscribe
registerWebPushSubscription({ endpoint, keys }) invia notifiche push a questo browser. Richiede l’accesso da browser: un token personale riceve 403. Un endpoint su un servizio push sconosciuto riceve 400.
unregisterWebPushSubscription(endpoint, { signal? }) interrompe le notifiche push a questo browser. Restituisce { deleted }.
registerDeviceToken(input) · unregisterDeviceToken(token, { signal? }) registra · rimuove il token push Expo di un’app nativa

Tipi (InboxNotificationKind, elencati in INBOX_NOTIFICATION_KINDS):

tipo inviata quando push email (predefinito)
turn_done un turno che hai avviato con un prompt o che segui è terminato attivo disattivata
turn_error quel turno è terminato con un errore attivo attiva, in un riepilogo
question l’agente pone una domanda attivo attiva, in un riepilogo
permission l’agente chiede un’autorizzazione attivo disattivata
shared qualcuno ha condiviso una sessione con te attivo attiva, in un riepilogo
automation_failed un’automazione che segui ha iniziato a fallire attivo attiva, immediata
automation_recovered quell’automazione funziona di nuovo attivo disattivata

DEFAULT_NOTIFICATION_PREFERENCES contiene questi valori predefiniti. La riga nella casella di posta viene sempre scritta; le preferenze determinano solo push ed email. Un’email di riepilogo elenca le righe ancora non lette 15 minuti dopo il loro arrivo, con al massimo un riepilogo all’ora. Nascondi la colonna email quando email_available è false.

Il url di ogni riga ne apre l’oggetto. Il suo parametro di query ?notification=<id> consente alla pagina di segnare la riga come letta.

L’handle della sessione contiene lo stato con cui il chiamante segue una sessione:

metodo funzione
session(pid, sid).watch() { watching }: indica se il chiamante riceve notifiche su questa sessione
session(pid, sid).setWatch(watching) false silenzia la sessione per il chiamante, true torna a seguirla. Inviare un prompt a una sessione fa sì che venga seguita, ma non annulla mai il silenziamento.
session(pid, sid).presence({ tab_id, active, alerts? }, { keepalive? }) lease di presenza di questa scheda. alerts: true indica che la scheda mostra le proprie notifiche: con notification_center attivo, il server omette le notifiche al telefono e Web Push solo mentre è in uso una scheda che mostra avvisi. Se è disattivato, alerts viene ignorato e qualsiasi scheda presente blocca le notifiche push al telefono. keepalive consente alla richiesta di proseguire dopo la chiusura di una pagina. Valore predefinito: attivo per una segnalazione di assenza, disattivato per una di presenza. useSession invia keepalive solo con presencePageExit.

L’handle del progetto — beeuni.project(id)

Associa l’ID del progetto; tutte le sottorisorse dipendono da esso.

const p = beeuni.project(projectId);
await p.detail();
await p.update({ name });
await p.llmCatalog();
metodo funzione
get · detail · update · archive lettura · dettagli completi · aggiornamento · archiviazione
llmCatalog · modelPicker · sandboxHealth lettura di modelli e build della sandbox
onboardingComplete contrassegna l’onboarding del progetto come completato
validateManifest(raw) convalida lato server un manifest beeuni.yaml (o il precedente beeuni.toml)
gitToken() genera un nuovo token git push con ambito limitato (409 per un repository proprio)
setAgentScope(agentName, scope) imposta nel manifest i segreti e i connettori consentiti a un agente — la seconda associazione, non un ruolo

p.tokens — chiavi API con ambito di progetto

Generate automaticamente alla creazione della sessione come BEEUNI_TOKEN; possono anche essere generate manualmente.

metodo funzione
list() chiavi API del progetto
create(input?) genera una nuova chiave
revoke(tokenId) revoca una chiave

Un link che una persona apre per inserire un segreto o collegare un’app, senza accesso completo al progetto.

metodo funzione
requestSecret(input) · requestConnector(input) link per raccogliere un segreto · collegare un’app

p.apps — Apps (release, macchine, volumi)

Richiede la funzionalità di progetto apps. Guida: SDK → Apps.

metodo funzione
list() · get(appId) · create(input) · update(appId, input) · remove(appId) inventario e ciclo di vita; create accetta uses, update accetta anche labels
deployments.* · artifacts.* · access.* · rollback · start · stop distribuzioni, artefatti, policy di accesso, traffico e runtime
machines.list/start/stop/restart/destroy · scale(appId, count) · exec(appId, input) macchine per gruppo di processi; exec richiede project.app.admin
volumes.list/create/update/destroy/snapshots/snapshot/restore/fork volumi persistenti, snapshot giornalieri, ripristino, fork
token(appId) un token di accesso valido per 15 minuti; 409 app_capability_unsupported senza member_tokens

p.secrets — segreti del progetto

metodo funzione
list() · upsert(input) elenca i metadati · crea o aggiorna un valore di sola scrittura e la policy di distribuzione
setStrategy(identifier, strategy, options?) modifica l’esposizione e il relativo elenco di host
broker(identifier, request) esegue una richiesta HTTPS autorizzata dalla sessione e vincolata alla policy
remove(identifier) elimina un segreto
setPersonal(name, value) · removePersonal(name) imposta · rimuove una sostituzione per utente
setGitCredential(input) imposta una credenziale di autenticazione git

runtime con consumer sandbox è l’esposizione environment — quella predefinita, e l’unica policy che inserisce un valore in chiaro nella sessione. egress con consumer network è l’esposizione egress-enforced: la sessione contiene un handle e Beeuni sostituisce il valore reale fuori dalla sandbox, per gli esatti host HTTPS elencati dalla policy. L’esposizione egress-enforced è sperimentale; richiede il flag di funzionalità secrets_egress (Settings → Feature flags). Con il flag disattivato, setStrategy(identifier, 'egress', …) e upsert(...) con una policy egress restituiscono 403 feature_disabled. Nessun consumer broker è presente nella sessione. Vedi Segreti. Il metodo broker(...) richiede un token con ambito di sessione e un handle di sessione attivo.

p.access — assegnazioni, inviti e richieste del progetto

Ogni metodo qui legge o scrive un’assegnazione con ambito limitato a questo progetto. I ruoli del progetto sono manager e member.

metodo funzione
list() · invite(email, role) soggetti con accesso · invita un utente
update(userId, role) · revoke(userId) assegna un ruolo nel progetto · revoca l’assegnazione
pendingInvites() · requests() inviti in sospeso · richieste di accesso in attesa
resendInvite(inviteId) · revokeInvite(inviteId) · approveRequest(id) · rejectRequest(id) reinvia/revoca un invito · approva/rifiuta una richiesta
groupGrants() · attachGroupGrant(...) · updateGroupGrant(...) · detachGroupGrant(...) le stesse assegnazioni, con un soggetto group

p.access.resourceGrants è la vista assegnazione di oggetti: limita un soggetto a un solo oggetto nel progetto anziché all’intero progetto. Beeuni applica attualmente le assegnazioni di oggetti ad agenti e skill. Un agente è chiuso per impostazione predefinita — un membro vi accede solo quando un’assegnazione indica lui o uno dei suoi gruppi. Un’assegnazione di oggetti non conferisce autorizzazioni proprie e limita un responsabile di progetto tanto quanto un membro.

metodo funzione
resourceGrants.list() assegnazioni di oggetti in questo progetto
resourceGrants.create(input) assegna un oggetto a un utente o a un gruppo
resourceGrants.remove(grantId) revoca un’assegnazione di oggetti

p.connector(slug) — un connettore

metodo funzione
run(action, args, options?) l’output dell’azione; genera ConnectorCallError o ConnectorApprovalPendingError — vedi Errori
call(action, args, options?) il risultato grezzo della chiamata; 202 si risolve con ok: false
describe() · describe(action) il connettore con schemi di input e output · un’azione
accounts() gli account con cui il chiamante può eseguirlo, quello predefinito per primo
paginate(action, args, { next, maxPages? }) iteratore asincrono sull’output di ogni pagina; genera ConnectorPageLimitError con nextArgs quando esistono più di maxPages pagine (valore predefinito 100) — vedi Pagine
uploadAttachment(content, input) p.connectors.uploadAttachment con connector impostato su questo slug

options: account, approvalContext, timeoutMs (valore predefinito 90 000), signal. Con il file di beeuni connectors types, gli argomenti e l’output sono tipizzati.

p.connectors — connettori di strumenti

metodo funzione
catalog() · tools() catalogo Connector invocabile · strumenti <connector>.<action> appiattiti
search(query, options?) · describe(tool) trova · ispeziona uno strumento invocabile
call(tool, args?, options?) chiama uno strumento <connector>.<action> tramite il gateway lato server. options.account indica l’account con cui eseguirlo — vedi sotto.
accounts(slug) gli account con cui il chiamante può chiamare slug, quello predefinito per primo — ciò con cui options.account verifica la corrispondenza
uploadAttachment(content, input) prepara i byte per input.connector; restituisce ref ({ $beeuni_attachment }) da inserire negli argomenti di una chiamata successiva — vedi Allegare file
list() · config(connectorId) connettori configurati · configurazione di un connettore
create(input) aggiunge un connettore
auth.discover(input) mostra un’anteprima dell’autenticazione da una specifica OpenAPI, una raccolta Postman o un endpoint
remove(connectorId) · sync() elimina un connettore · risincronizza i connettori
setName(connectorId, name) · setSensitive(connectorId, sensitive) rinomina · contrassegna come sensibile (ulteriore controllo di approvazione)
setAuthorizationStrategy(slug, strategy) @deprecated. Chiama ancora la route; la route non esegue operazioni, risponde {ok:true, deprecated:true} e non modifica nulla. owner_type su ogni connessione costituisce ora l’intera regola di accesso.
setCredentialMode(connectorId, mode) · setCredential(connectorId, input) cambia origine · imposta il valore della credenziale
policies.get(connectorId) · policies.set(connectorId, policies) legge · sostituisce le relative policy degli strumenti
connections.list() · connections.reconcile(input) elenca · crea/aggiorna gli account collegati
connections.updateCredential(connectionId, input) ruota una credenziale di connessione
connections.revoke(connectionId) · connections.activate(connectionId) nega · ripristina una connessione
connections.setDefault(connectionId) la imposta come predefinita per l’ambito del suo proprietario
connections.rename(connectionId, label) modifica solo l’etichetta; l’account resta autorizzato. Ogni connessione contiene connected_as, l’identità con cui è stata autorizzata.

p.connectors.discover esplora il catalogo dei connettori diretti. È sperimentale e disattivato per impostazione predefinita — abilitalo per ciascun progetto in Settings → Feature flags → “Connectors API Discover”. Easy Connect resta il marketplace predefinito dei connettori.

metodo funzione
discover.list(query?, cursor?) · discover.detail(id) cerca voci OpenAPI/MCP/GraphQL/CLI · dettagli di una voce

p.connectors.pipedream è il percorso di compatibilità OAuth gestito precedente; listApps restituisce solo le app OAuth. Usa Easy Connect per le nuove integrazioni gestite. Collega direttamente le app con chiave API.

metodo cosa
pipedream.listApps(params?) · pipedream.connect(input) · pipedream.finalize(input) esplora il catalogo delle app · avvia un flusso di collegamento · finalizzalo

Un connettore definisce lo strumento, l’app del provider e i criteri. connections memorizza i suoi account collegati: un connettore può contenerne diversi affiancati. Una sessione può fissarne uno per ogni chiamata con connector_bindings: { alias: { connection_id } }, oppure una singola chiamata può specificarne uno con call(tool, args, { account }). Le credenziali restano crittografate e vengono risolte per richiesta.

connections è l’unica facciata di autorizzazione attiva. I nomi ritirati authorizations e profiles non fanno parte della superficie dell’SDK attuale.

Account e controllo al momento della chiamata

Ogni connessione ha un owner_type: project (condiviso — raggiungibile da chiunque abbia accesso al connettore, persona o account di servizio) oppure member (privato — raggiungibile solo dal relativo proprietario e solo in una sessione privata; mai da un account di servizio). Un account condiviso può essere limitato a gruppi e persone: connections.list() restituisce le autorizzazioni in shared_with e connectionSharedWithEveryone(connection) indica se tutti gli utenti del progetto possono usarlo. Un account limitato segue le regole private per le persone indicate e usable: false contrassegna quello che il chiamante vede solo per amministrarlo. Concedi o revoca l’accesso con createAssignment / revokeAssignment (object: { type: 'connection', id }) — vedi Chi può usare un account condiviso. p.connectors.accounts(slug) elenca ogni account raggiungibile da questo chiamante, con quello predefinito per primo:

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 chiamata che non specifica alcun account risolve prima l’account privato predefinito del chiamante, poi l’account condiviso predefinito del progetto. Un account specificato che non viene risolto è negato con connector_not_connected — non viene mai sostituito automaticamente — e il rifiuto elenca requested_account e available_accounts. Ogni chiamata riuscita indica con quale account è stata eseguita: result.account = { connection_id, label, owner_type }.

Non esiste più un controllo del connettore al momento della creazione della sessione. In precedenza una sessione veniva rifiutata con 409 CONNECTOR_CONNECTION_REQUIRED quando un connettore richiesto non aveva una connessione utilizzabile; quel rifiuto è stato rimosso (require_connectors è inattivo — vedi p.sessions). Il controllo è stato spostato sulla chiamata: un connector_not_connected negato include connect_url, un link di autorizzazione ospitato, ogni volta che è possibile generarlo per il chiamante — l’intero rimedio richiede un solo clic ed è esposto dal pulsante di collegamento della trascrizione.

p.policies — criteri del progetto

metodo cosa
list() · set(policies) i criteri del progetto · sostituisci l’insieme

p.triggers — automazioni cron, webhook, monitor ed eventi

Un trigger avvia un’azione dell’agente in base a una pianificazione, a un webhook in ingresso, a un comando monitorato o a un evento dell’app su un connettore. Vedi Trigger per la strategia della sessione e la modellazione del payload.

metodo cosa
list() tutti i trigger
eventTypes({ connector }) gli eventi dell’app che un connettore può attivare ({ provider, app, event_types }); 404 per un connettore sconosciuto, 409 event_source_unavailable quando il relativo provider non ha alcuna sorgente di eventi
create(input) creane uno
update(triggerId, input) modifica un trigger
remove(triggerId) elimina un trigger
fire(triggerId) eseguilo ora
setActivation(paused) metti in pausa o riprendi ogni trigger del progetto

create(input) accetta { 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 sono obbligatori. cron/run_at sono mutuamente esclusivi (type: 'cron'); secret_env (il segreto HMAC del webhook) si applica a type: 'webhook'.

Un trigger event richiede connector (uno slug del connettore) e event (un ID del tipo da eventTypes). event_account è opzionale: l’etichetta di un account condiviso di quel connettore; null o l’omissione usa l’account condiviso predefinito del connettore. event_source è opzionale: l’ID dell’adattatore della sorgente di eventi, ad esempio composio. null o l’omissione usa il provider del connettore. L’ID del tipo appartiene a quell’adattatore. event_config segue la struttura definita da config_schema del tipo. eventTypes e eventApps riportano l’adattatore come source; provider è un alias deprecato. Ogni trigger elencato contiene event: { connector, account, connected_as, type, config, source, provider, app, status: 'active' | 'needs_connection' | 'error' | 'pending', error, last_event_at } | null. I modelli di prompt leggono l’evento come {{ event.data.<field> }} più event.id, event.type, event.app, event.connector e event.occurred_at.

session_access controlla chi può aprire le sessioni create dal trigger. È { mode: 'private' | 'members' | 'project', memberIds: string[], groupIds: string[] } and defaults to private. Questo criterio è uno stato di runtime locale all’account. Non entra nel manifest portabile beeuni.yaml. L’aggiornamento del solo session_access non crea alcun commit Git. Una sessione fissata mantiene le proprie impostazioni di condivisione. Un responsabile del progetto può sempre aprire le sessioni create dai trigger, comprese quelle che usano private o l’accesso a membri selezionati.

session_access è un’impostazione di visibilità per risorsa che si aggiunge al modello dei ruoli, non un ruolo. Decide chi può aprire le sessioni di un trigger. Non concede alcuna autorizzazione negata dal verdetto del ruolo. Vedi Account e accesso.

p.marketplace / p.registry — elementi installati

Installa i file di un elemento del catalogo nel branch predefinito del progetto. registry.* è un alias identico di marketplace.*.

metodo cosa
marketplace.list() · marketplace.install(id) elementi installati · installa un elemento del catalogo
marketplace.updates() · marketplace.update(name) · marketplace.updateAll() aggiornamenti disponibili · aggiorna uno · aggiorna tutti
marketplace.remove(name) disinstalla un elemento

p.files — file del repository (lettura)

Accesso in sola lettura all’albero git del progetto. Per leggere e scrivere file all’interno di una sessione in esecuzione, usa le operazioni sui file della sessione — vedi File nella sezione Moduli.

metodo cosa
listDirectory({ ref?, path? }) un livello di cartella: { entries: [{ path, type, size? }], truncated }. Usalo per creare un albero; ogni cartella è completa fino a 5.000 elementi.
list(options?) · read(path, ref?) ogni file sotto un percorso, ricorsivamente, fino a 1.000 (la risposta contiene X-Beeuni-Truncated: 1 quando viene troncata) · il contenuto di un file a un riferimento git
search(query, { content?, ref?, limit? }) cerca i nomi dei file nell’intero repository o i contenuti con content: true
archive(options?) · history(path) scarica un tarball · la cronologia git di un file

p.git — cronologia

metodo cosa
commits() il log dei commit
commit(sha) · commitDiff(sha) un commit · il relativo diff
branches() · versionDiff(from, to) branch · diff tra due riferimenti

p.changeRequests — ciclo di vita e merge

Una richiesta di modifica (CR) è il modo in cui il lavoro di una sessione viene unito al branch predefinito.

metodo cosa
list() · get(crId) CR aperte · una CR
diff(crId) · mergePreview(crId) il relativo diff · visualizza in anteprima il risultato del merge
open(input) · merge(crId, input?) apri · unisci una CR
close(crId, input?) · reopen(crId, input?) chiudi senza eseguire il merge · riapri una CR chiusa
requestChanges(crId, input) registra il feedback, facoltativamente inviato alla sessione di origine

p.sessions — e l’handle della sessione

metodo funzione
list() le sessioni del progetto
create(input?) creare una sessione
session(sid) l’handle della sessione (come beeuni.session(id, sid))

L’handle della sessione è il cuore del runtime — vedi Sessioni.

create(input) accetta connector_bindings con lo slug della connessione del connettore come chiave. Ogni valore identifica un connection_id. Accetta anche secrets per limitare i segreti provenienti dal backend. require_connectors è deprecato e inattivo: il campo è ancora accettato (un vecchio client non viene mai rifiutato perché lo invia), ma nulla lo legge — una sessione non viene mai rifiutata al momento della creazione per un connettore senza un account utilizzabile. Vedi Account e controllo al momento della chiamata.

p.approvals — la casella delle approvazioni dei connettori

Azioni soggette al controllo dei connettori in attesa di una decisione — supporta la UX di approvazione delle autorizzazioni (APPROVE / ASK / BLOCK).

metodo funzione
list(options?) · sessionsNeedingInput(options?) approvazioni in sospeso · sessioni bloccate in attesa di una decisione
resolve(executionId, decision, scope?) approvare o negare una richiesta — decision: 'approve' | 'deny', scope: 'once' | 'session' | 'session_all'

p.gateway — osservabilità degli LLM

Log delle richieste, aggregazioni di costi/latenza, budget e chiavi API del gateway per il traffico verso i modelli di questo progetto.

metodo funzione
logs(opts?) · log(logId) voci del log delle richieste · una voce del log
overview(days?) · series(days?) · breakdown(days?) · sessions(days?) · errors(days?) aggregazioni, costo per sessione ed errori in un intervallo
budgets() · setBudget(input) · deleteBudget(budgetId) leggere · creare/modificare · rimuovere un budget
keys() · createKey(name) · revokeKey(keyId) elencare · generare · revocare una chiave API del gateway
playground(prompt, models) eseguire un prompt su un massimo di 6 modelli
routing.get() · routing.set(policy) · routing.reset() leggere · sostituire · ereditare la politica di instradamento
routing.preview(input) risolvere una route senza invocare un modello

Una politica di instradamento contiene un modello predefinito, un modello per la visione e una catena ordinata di fallback; ogni modello viene tentato al massimo una volta; fallbackOn è transient o any-error.

Il gateway passa al modello di fallback successivo solo quando il modello corrente ha fallito prima di restituire qualsiasi output:

  • transient: un errore di rete, un timeout, qualsiasi 5xx oppure 402, 403, 429.
  • any-error: ogni errore, incluso un 400.

Un errore dopo l’inizio dell’output resta associato a quel modello. Una richiesta con la propria chiave del provider (BYOK) non passa mai a un modello fatturato da Beeuni. Ogni modello di fallback riceve i propri valori predefiniti di generazione.

p.channels — Slack / email / voce

Interfacce dei connettori che consentono a un agente di agire come app Slack, come indirizzo email o di partecipare a una chiamata vocale in tempo reale.

metodo funzione
slack.installation() · slack.mode() · slack.manifest() installazione corrente · modalità · manifest dell’app
slack.connect(input) · slack.disconnect() connettere · disconnettere
slack.getFile(url) · slack.uploadFile(input) scaricare · caricare un file tramite il proxy del server
email.installation(connectorSlug?) · email.mode() installazione corrente · modalità
email.connect(input) · email.disconnect(...) · email.updatePolicy(input) connettere · disconnettere · aggiornare la politica di invio/risposta
voice.setBotName(name) rinominare il bot durante una chiamata in corso

p.modelDefaults — preferenze del modello predefinito

Valori predefiniti dei modelli a livello di account, agente e progetto, risolti dal gateway.

metodo funzione
get() · set(input) · clear(params) leggere · impostare un valore predefinito · cancellare una sovrascrittura

p.setDefaultAgent — agente predefinito del progetto

p.setDefaultAgent(agentName) verifica che l’agente sia dichiarato e abilitato, poi lo imposta come default_agent nel beeuni.yaml del progetto. Le nuove sessioni preferiscono questo agente, a meno che un utente non ne scelga un altro.

p.updateFeatureFlag — flag di funzionalità

p.updateFeatureFlag(feature, enabled) attiva o disattiva un flag di funzionalità per il progetto. Passa enabled: null per cancellare la sovrascrittura e tornare al valore predefinito della piattaforma. Chiama il PATCH /v1/projects/:id/features canonico.

feature è uno dei FEATURE_FLAG_KEYS (esportati da @beeuni/sdk, con tipo FeatureFlagKey). Il chiamante deve avere l’autorizzazione project.settings.write del progetto; altrimenti la route risponde con 403.

Ogni route controllata da un flag rifiuta le richieste allo stesso modo quando il flag è disattivato: HTTP 403 con { error, code: "feature_disabled", feature }. Usa isFeatureDisabledError(error) per gestire il caso e featureDisabledKey(error) per leggere la chiave del flag — non basarti mai sul testo del messaggio.

p.updateExperimentalFeature(feature, enabled) è l’alias deprecato. Continua a chiamare l’alias deprecato della route PATCH /v1/projects/:id/experimental così i consumer vincolati a una versione precedente dell’API distribuita continuano a funzionare. Usa p.updateFeatureFlag nel nuovo codice.

p.sandbox — template e build degli snapshot

Configurazione delle build delle sandbox oltre a sandboxHealth/sandboxTemplates sull’handle del progetto: template Dockerfile/immagine/warm pool e relative build degli snapshot.

metodo funzione
list() · snapshots() sandbox di questo progetto · snapshot compilati
rebuildSnapshot(slug?) · fixWithAgent() ricompilare uno snapshot · chiedere a un agente di correggere una build non funzionante
createTemplate(input) · updateTemplate(...) · removeTemplate(...) · buildTemplate(...) aggiungere · modificare · eliminare · compilare un template
setProvider(provider) richiedere un cambio di provider. null (oppure il valore predefinito della piattaforma / il provider già attivo) si applica immediatamente; il passaggio a un altro provider abilitato avvia una transizione persistente di preparazione→verifica→attivazione — il provider corrente continua a servire le richieste mentre l’immagine pronta all’uso di destinazione viene compilata e verificata, poi attivata. Il valore restituito è un’unione discriminata: kind:'project' (immediata) oppure kind:'preparation' (interrogare periodicamente getProjectSandboxProviderTransition() fino a activated/failed)

Hook di amministrazione della piattaforma (@beeuni/sdk/react)

Questi hook servono la console di amministrazione. L’API risponde solo agli amministratori della piattaforma. Ogni mutazione invalida le query ['admin', 'accounts'].

Hook Funzione
useAdminRole(userId, options?) leggere il ruolo del chiamante da GET /user-roles → { isAdmin, role }. userId funge da chiave della cache. L’assenza di userId disabilita la query. Recupera nuovamente i dati al montaggio e al focus, così un ruolo revocato cessa di concedere accesso entro una navigazione.
useAdminGrantCredits() mutazione { accountId, amount, description, isExpiring }: aggiungere credito al portafoglio. POST /admin/api/accounts/:id/credits. Sposta denaro: confermare prima nell’UI.
useAdminDebitCredits() mutazione { accountId, amount, description }: rimuovere credito dal portafoglio. POST /admin/api/accounts/:id/credits/debit. Sposta denaro: confermare prima nell’UI.
useAdminSetTier() mutazione { accountId, tier }: impostare il livello del piano.
useAdminGrantTrial() mutazione { accountId, tierKey, seats, durationDays, creditGrant?, note? }: concedere o sostituire un periodo di prova. L’account si comporta come tierKey fino al termine del periodo. creditGrant aggiunge anche credito al portafoglio.
useAdminRevokeTrial() mutazione { accountId }: terminare subito un periodo di prova attivo. Risponde con 400 quando non ce n’è uno attivo.

Via di uscita

beeuni.runtime() restituisce il client REST runtime tipizzato per la sandbox attiva. Su un client creato da createScopedBeeuni (@beeuni/sdk/server), genera un’eccezione — il runtime “attivo” globale del processo è la sandbox di un’altra richiesta in un server multi-tenant, una fuga di dati tra tenant. Usa invece beeuni.session(pid, sid).runtime con ambito di sessione (chiama prima ensureReady()), che risolve la sandbox della sessione stessa.

Moduli

I moduli indipendenti dal framework alla base della facciata del client e degli hook React. Usali quando ti serve una singola operazione senza la facciata, un helper puro o un livello di isolamento solo per Node. Ogni modulo indica un livello di stabilità, così sai su cosa basarti.

Livello Significato
Canonico Importa dalla radice @beeuni/sdk. Usalo per tutto il nuovo codice.
Supportato Un sottopercorso dedicato (@beeuni/sdk/react, @beeuni/sdk/server). Pienamente supportato, non deprecato.
Alias deprecato Un vecchio sottopercorso ancora funzionante. Riesporta codice già esportato dalla radice. Importa invece dalla radice.
Interno Fuori da semver. Non importarlo nel codice host.

Il punto di ingresso radice è canonico. Ogni nome indipendente dai framework elencato sotto è importabile direttamente da @beeuni/sdk:

import { files, getSessionHealth, getClient, authenticatedFetch, backendApi } from '@beeuni/sdk';

Moduli canonici

Modulo Cosa fa
File Operazioni sui file del workspace: elenco, lettura, ricerca, scrittura
Runtime di sessione Verifica dello stato e generatori di URL di anteprima/proxy
Client runtime Il client REST runtime tipizzato e l’intero insieme dei suoi tipi
Autenticazione authenticatedFetch e funzioni di accesso ai token
REST dei progetti Le funzioni REST di base incapsulate dalla facciata
Client API backendApi, il client HTTP tipizzato di basso livello
Turni Raggruppamento dei messaggi in turni, calcolo dei costi e degli stati — vedi Turni
Trascrizioni formatTranscript, un’esportazione Markdown lato client
Elenchi del compositore Gli elenchi di agenti e modelli del compositore di sessione: quali proporre, quali vengono eseguiti

File

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}`);
  },
});

I caricamenti superiori a 64 KiB attraversano il confine della sandbox in blocchi verificati. La callback di avanzamento viene eseguita dopo che ogni blocco raggiunge il filesystem della sessione.

uploadNativeFile({ uri, name, type? }, targetPath, baseUrl) carica un file del dispositivo da React Native in un’unica richiesta. Il runtime trasmette i byte in streaming da uri, quindi non entrano mai nell’heap JS. Usa la stessa autenticazione, scadenza e ripetizione 401 di files.upload. Non suddivide in blocchi.

fetchProjectArchive, fetchCostExportCsv e le chiamate alla versione della sandbox inviano tramite lo stesso trasporto. Un errore genera un’eccezione ApiError con status.

files.write(path, blob) sostituisce il file in path e fallisce se path è una cartella. files.create(path) crea un file vuoto e non sovrascrive mai: quando un file o una cartella esiste già in path, genera 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 opera sulla sandbox attiva a livello globale. Se il tuo host esegue più di una sessione alla volta, chiama invece s.files sull’handle della sessione. Opera sempre sulla sandbox di quella sessione. Vedi Sessioni.

Funzioni ausiliarie del runtime di sessione

import { getSessionHealth, isRuntimeReady } from '@beeuni/sdk';

const result = await getSessionHealth();
if (result.ok && isRuntimeReady(result.health)) {
  // the sandbox daemon is ready
}

getSessionHealth non genera mai eccezioni per uno stato non 2xx. Restituisce { status, ok, health, body } e ti lascia decidere cosa significa uno stato. Lo stesso modulo esporta le funzioni ausiliarie per gli URL che riscrivono l’output localhost di un agente in un URL proxy raggiungibile: detectLocalhostUrls, rewriteLocalhostUrl, proxyLocalhostUrl, parseLocalhostUrl e buildWebProxyUrl.

Client runtime

import { getClient } from '@beeuni/sdk';

const client = getClient();
const { data } = await client.session.list({ limit: 100 });

getClient() restituisce il client di compatibilità runtime tipizzato per la sandbox attiva, con l’autenticazione già inserita. Preferisci beeuni.session(pid, sid).runtime, lo stesso client limitato a una sessione, al globale getClient() quando il tuo host esegue più di una sessione.

Funzioni ausiliarie di autenticazione

import { authenticatedFetch, getAuthToken } from '@beeuni/sdk';

const res = await authenticatedFetch(`${runtimeUrl}/beeuni/health`);
const token = await getAuthToken();

Il token proviene dalla funzione getToken che hai passato a createBeeuni. La maggior parte del codice dell’app non ha bisogno di questo modulo: i livelli dei file, delle sessioni e della facciata eseguono già l’autenticazione per te.

Client API

import { backendApi } from '@beeuni/sdk';

const data = await backendApi.get('/some/endpoint');
await backendApi.post('/some/endpoint', { name: 'x' });

backendApi è il client HTTP tipizzato su cui si basa ogni funzione REST. Usalo solo per un endpoint che non ha ancora un wrapper tipizzato.

Elenchi di agenti e modelli del compositore

Crea i selettori di agenti e modelli di un compositore di sessione con le stesse regole usate dall’app web Beeuni. Ogni funzione è pura: recupera gli input con il client, poi passali alla funzione.

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 restituisce explicit: undefined quando il compositore usa l’impostazione predefinita. model è la chiave da visualizzare e inviare. Il id di ogni modello appiattito è il riferimento memorizzato da una selezione; modelRefToKey(ref, gatewayEnabled) riconverte un riferimento memorizzato (un elemento fissato alla sessione, un’associazione di canale, il model di un trigger) in una chiave.

Sottopercorsi supportati

Sottopercorso Cosa fa
@beeuni/sdk/react Hook React — vedi Hook React
@beeuni/sdk/server Configurazione limitata alla richiesta per backend multi-tenant
@beeuni/sdk/wire-message-id Solo l’orologio degli ID dei messaggi del protocollo runtime (un modulo, nessuna importazione). La radice esporta gli stessi nomi

ID dei messaggi del protocollo

Il messageId di un prompt è la sua posizione nella trascrizione. runtime ordina i messaggi per msg_ + un orologio a 48 bit (Date.now() * 0x1000, i 48 bit meno significativi) + 14 caratteri base62, e l’orologio riparte da zero ogni 2^36 ms (circa 2,2 anni). Non codificarlo mai a mano.

import { mintWireMessageId } from '@beeuni/sdk';

// `after`: the ids already in this session's transcript.
const messageId = mintWireMessageId({ after: transcriptIds });

La generazione viene retrodatata di due minuti, poi portata un tick oltre l’ID più recente in after che sia al massimo un’ora avanti. Un chiamante che conserva la posizione più recente come orologio anziché come ID usa mintWireMessageIdAbove({ nowMs, newestKnownTime }), which returns { id, time }. newestWireIdClock(ids) per trovare quell’orologio. Ogni confronto avviene sull’anello, quindi gli ID ai due lati di un ritorno a zero mantengono il loro ordine effettivo.

L’orologio a 48 bit riparte da zero ogni ~2,2 anni, quindi non confrontare mai due orologi con > o <=: un ID generato subito dopo un ritorno a zero è numericamente inferiore a uno generato subito prima. Usa wireIdClockDelta(clock, reference), la distanza con segno sull’anello (positiva quando clock è avanti), e maxWireIdClock(clocks) per il più recente tra diversi valori:

import { maxWireIdClock, wireIdClockDelta } from '@beeuni/sdk/wire-message-id';

const floor = maxWireIdClock([transcriptNewest, deliveredNewest]);
const stale = floor !== null && wireIdClockDelta(clientClock, floor) <= 0n;

Isolamento lato server

createBeeuni memorizza la propria configurazione, inclusa la funzione del token, in una variabile globale del processo. Va bene per una scheda del browser, una CLI o un server single-tenant. Non è sicuro per un server Node che gestisce richieste simultanee per utenti diversi, perché l’ultima chiamata a createBeeuni prevale per ogni richiesta in corso. @beeuni/sdk/server risolve il problema con l’isolamento per richiesta:

import { createScopedBeeuni } from '@beeuni/sdk/server';

export async function handler(req: Request) {
  const beeuni = createScopedBeeuni({ backendUrl, getToken: () => tokenFor(req) });
  return beeuni.projects.list();
}

createScopedBeeuni e runWithBeeuni isolano la configurazione per richiesta con AsyncLocalStorage di Node. Non importare mai @beeuni/sdk/server da un bundle per il browser: include staticamente node:async_hooks.

Il runtime() di primo livello di un client con ambito limitato genera un’eccezione (risolverebbe la sandbox di un altro tenant). Accedi al runtime di una sessione specifica tramite beeuni.session(pid, sid).runtime dopo await s.ensureReady().

Alias deprecati

Circa venti vecchi sottopercorsi funzionano ancora: /files, /turns, /session, /auth, /projects-client, /api-client, /config, /event-stream, /opencode-client, /platform-client e altri. Ognuno riesporta codice già esportato dal punto di ingresso radice @beeuni/sdk. Restano funzionanti affinché nessun elemento esistente import breaks, but new code should import from the root.

Moduli interni

@beeuni/sdk/internal/* contiene gli store zustand che il runtime di apps/web usa internamente: stato di sincronizzazione della sessione, monitoraggio del runtime attivo e gestione delle riconnessioni. Questo sottopercorso è esplicitamente fuori da semver. Non importarlo nel codice host; gli Hook React espongono già lo stato di cui hai bisogno.

Turni

Funzioni semplici che raggruppano i messaggi di sessione in turni e classificano ogni parte di messaggio. Usale per creare un renderer di chat personalizzato anziché quello di riferimento in apps/web. Niente React, niente DOM: ogni esportazione è una semplice funzione o un tipo, richiamabile in sicurezza da qualsiasi host.

import { classifyPart, classifyTurn, toolInfo, toolViewModel } from '@beeuni/sdk';

Importa ogni funzione dal punto di ingresso radice @beeuni/sdk. Il sottopercorso @beeuni/sdk/turns funziona ancora, ma è un alias deprecato. Il nuovo codice deve usare il punto di ingresso radice — vedi Distribuzione.

Classificare una parte

classifyPart(part) normalizza uno dei 12 tipi di parte del formato di trascrizione Beeuni (beeuni.transcript.v1, BEEUNI_TRANSCRIPT_SCHEMA) in un ClassifiedPart — un’unione indicizzata da kind. Ogni variante risolve già i campi necessari a un renderer: stato dello strumento, output JSON analizzato, rilevamento delle immagini.

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 forma
text { id, text, synthetic } — ignora le parti synthetic; indicano il prompt sintetico della modalità 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 di parte che questa versione dell’SDK non conosce

Una parte wire non riconosciuta viene degradata a unknown in fase di runtime invece di lanciare un’eccezione. Questo consente a un client meno recente di comunicare con un server più recente.

Una parte di strumento viene classificata in 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) ne crea una direttamente da una parte di strumento. Leggi questi campi invece del personale state.metadata dell’harness: la stessa scheda restituisce quindi un edit di runtime (filePath, filediff) e un edit di pi (path, edits, un patch unificato).

Alcuni strumenti (web_search, image_search, chiamate ai connector) segnalano state.status: 'completed' anche quando il loro corpo JSON contiene success: false. classifyPart lo rileva e imposta ToolView.status su 'error' anche in questo caso.

classifyTurn(message) classifica ogni parte di un messaggio dell’assistente e restituisce un ClassifiedTurn con tre campi:

  • parts — ogni parte, classificata
  • error — da message.info.error, se presente
  • isEmpty — true quando il turno non contiene errori né parti con contenuto visibile

Metadati degli strumenti

toolKind(name) è l’unica tassonomia degli strumenti: associa il nome dello strumento di qualsiasi harness (write di pi, oc-apply_patch di runtime, pty_spawn di un plugin) a un ToolKind — read, edit, write, bash, web_search, task, question, … oppure other. Le famiglie di narrazione, i view model, le categorie toolInfo e il gruppo degli strumenti di contesto derivano tutti da essa. inputPath(input) legge il percorso di uno strumento file da filePath, file_path o path.

toolKind('oc-apply_patch'); // 'apply_patch'
toolKind('pty_spawn');      // 'pty'
inputPath({ path: 'app.py' }); // 'app.py'

Altre due lookup descrivono entrambe uno strumento. Non confonderle.

  • toolInfo(name) — senza icona, restituisce { label, category }. classifyPart la usa internamente. ToolCategory è 'shell' | 'files' | 'search' | 'edit' | 'web' | 'task' | 'other'.
  • getToolInfo(name, input) — consapevole dell’icona, restituisce { icon, title, subtitle } per l’interfaccia di riferimento delle schede degli strumenti. Il sottotitolo deriva dall’input dello strumento, ad esempio un percorso file o una query di ricerca.
toolInfo('bash'); // { label: 'Shell', category: 'shell' }
getToolInfo('write', { filePath: '/workspace/main.go' });
// { icon: 'file-pen', title: 'Write', subtitle: 'main.go /workspace' }

Entrambe le funzioni verificano i prefissi dei nomi degli strumenti, quindi le famiglie di strumenti plugin di Beeuni (agent_*, session_*, task_*, trigger_*, project_*, pty_*) vengono risolte senza aggiornare il registro. Un nome di strumento sconosciuto non genera mai un’eccezione: ricade su humanizeToolName(name) con categoria 'other'.

View model degli strumenti

toolViewModel(classifiedTool) associa una parte di strumento classificata a una forma costruita per una famiglia di strumenti. L’interfaccia può quindi visualizzarla in modo specifico anziché come un generico blob JSON.

const vm = toolViewModel(classifiedTool);
if (vm.kind === 'shell') {
  render(vm.command, vm.stdout, vm.exitCode);
}
kind forma strumenti
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? } tutto il resto, sempre sicuro da visualizzare

DiffLine è { type: 'added' | 'removed' | 'unchanged', text }. I campi stringa sono limitati, così un singolo output di strumento molto grande non interrompe il rendering: 4000 caratteri per il JSON formattato, 256 KB prima dell’esecuzione di un diff.

Raggruppare i messaggi in turni

Un turno associa un messaggio dell’utente ai messaggi dell’assistente che vi hanno risposto. È l’unità che un’interfaccia chat visualizza come un unico scambio.

import { groupMessagesIntoTurns, collectTurnParts, type TurnLike } from '@beeuni/sdk';

const turns: TurnLike[] = groupMessagesIntoTurns(messages);
for (const turn of turns) {
  const parts = collectTurnParts(turn);
}

groupMessagesIntoTurns collega ogni messaggio dell’assistente al relativo messaggio dell’utente. Se manca un collegamento al genitore, usa l’ordine dei messaggi. Collega inoltre un messaggio dell’assistente orfano — uno senza genitore che precede ogni messaggio dell’utente — al primo turno, non all’ultimo.

Helper correlati:

  • findLastTextPart(parts) — il testo della risposta finale del turno
  • turnHasSteps(parts) — true se esiste una parte tool, compaction, snapshot o patch
  • isShellMode(turn) / getShellModePart(turn) — un turno costituito da un prompt sintetico che esegue una chiamata bash

Type guard

Riduci il tipo di una parte tramite 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

Sono disponibili anche: isReasoningPart, isFilePart, isAgentPart, isCompactionPart, isSnapshotPart, isPatchPart, isStepPart (step-start e step-finish).

Stato ed errori

import { getWorkingState, getTurnStatus, formatDuration } from '@beeuni/sdk';

const status = getTurnStatus(parts, childMessages); // "Running commands..."
formatDuration(4300); // "4s" — durations under 1s return ''

getTurnStatus analizza le parti di un turno alla ricerca dell’ultima riga di stato. Quando l’ultima parte è una delega task in esecuzione, passa childMessages affinché lo stato mostri l’attività effettiva del sottoagente anziché una riga generica “Delegating…”.

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

Totali di costi e token

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"

Entrambe le funzioni leggono i totali di costi e token dalle parti step-finish. Quando una parte segnala zero, stimano il costo dai conteggi dei token usando un ModelPricingLookup.

I messaggi degli abbonamenti ChatGPT/Codex contribuiscono $0.00, inclusi i messaggi storici con costi runtime diversi da zero. L’utilizzo di token e contesto resta visibile. Le sessioni miste conservano gli addebiti per i messaggi API a pagamento. I modelli API OpenAI restano fatturabili, inclusi i modelli API i cui nomi contengono codex.

Sessioni figlie e richieste in sospeso

L’albero delle conversazioni di una sessione di progetto (la radice e le conversazioni degli sottoagenti che ha creato) proviene dal suo elenco runtime_sessions. Questi helper lo leggono, preferendo i nomi attuali a quelli precedenti 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 chiamata allo strumento task delega a una sessione figlia. Questi helper collegano un turno padre ai messaggi propri di quella sessione figlia.

import { getChildSessionId, getChildSessionToolParts } from '@beeuni/sdk';

const childId = getChildSessionId(taskToolPart);
const steps = getChildSessionToolParts(childMessages);

Abbina una richiesta di autorizzazione o domanda in sospeso alla relativa chiamata dello strumento e individua quali parti dello strumento nascondere mentre è attiva:

import { getPermissionForTool, getHiddenToolParts, isToolPartHidden } from '@beeuni/sdk';

const permission = getPermissionForTool(permissions, callID);
const hidden = getHiddenToolParts(activePermission, activeQuestion);

Formattazione ed elenchi

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"

Gli helper degli elenchi di sessioni operano sugli stessi dati di sessione:

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);

Stato del nuovo tentativo: getRetryInfo(sessionStatus) restituisce { attempt, message, next, details? } when status.type === 'retry', with message limitato a 60 caratteri. details conserva, quando presente, un envelope strutturato del gateway LLM: il provider finale, il codice del gateway, l’ID della richiesta, il suggerimento, lo stato upstream e gli errori candidati ordinati. Ogni errore candidato contiene attempt, provider, routeModel, resolvedModel, stage, status opzionale, code, e message. I nuovi tentativi in testo semplice legacy restituiscono details: undefined. getRetryMessage(sessionStatus) restituisce il messaggio completo senza envelope. Quando runtime conserva solo quel messaggio, il composito del gateway include comunque l’ID della richiesta e il provider, il modello risolto, lo stato HTTP, il codice e il messaggio limitato di ciascun candidato.

Tipi strutturali

Le funzioni di raggruppamento e stato accettano tipi strutturali minimi — PartLike, MessageInfoLike, TurnLike, ToolStateLike, SessionStatusLike — invece dei tipi concreti delle trascrizioni. Le forme del tuo messaggio e delle tue parti passano senza modifiche, purché corrispondano ai campi richiesti. classifyPart e classifyTurn fanno eccezione. Sono tipizzati rispetto all’unione Beeuni Part (beeuni.transcript.v1), quindi il loro controllo di esaustività rileva un nuovo tipo di parte in fase di compilazione.

Distribuzione

npm install @beeuni/sdk

Il pacchetto viene distribuito come ESM compilato con dichiarazioni di tipo TypeScript complete. react e @tanstack/react-query sono dipendenze peer facoltative. Se usi @beeuni/sdk/react, installale entrambe.

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

Punti di ingresso e stabilità

Il punto di ingresso principale, @beeuni/sdk, è quello canonico. Esporta l’intera superficie indipendente dai framework ed è eseguibile nei browser, in Node 18+, Bun e negli ambienti edge.

Punto di ingresso Livello Contratto
@beeuni/sdk Canonico Indipendente dai framework. Non importa mai React o node:*.
@beeuni/sdk/react Supportato Hook React. L’unico punto di ingresso che importa React.
@beeuni/sdk/server Supportato Isolamento della configurazione per richiesta per i server Node e Bun, tramite node:async_hooks. Non includerlo mai in un bundle per browser.
Sottopercorsi legacy (/projects-client, /turns, /files e altri) Deprecati Funzionano ancora. Ognuno riesporta dal punto di ingresso principale. Importa invece dal punto di ingresso principale.
@beeuni/sdk/internal/* Interno Usato solo dall’app web Beeuni. Non è un’API supportata.

Bundle CDN

Il pacchetto include anche due bundle per browser, compilati da tsup: un bundle ESM (dist/beeuni.esm.min.js) e un globale IIFE (dist/beeuni.global.js) che definisce 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 espone lo stesso punto di ingresso principale dell’import npm: Beeuni.createBeeuni, Beeuni.classifyTurn, Beeuni.ApiError.

Vedi anche

  • SDK — installazione e prima sessione.
  • Sessioni — ciclo di vita, streaming e gestione degli errori.
  • Hook React — il livello reattivo basato su questi moduli.

Accesso al repository dell’agente

La configurazione dell’agente accetta repository_access?: boolean (predefinito true). Imposta false per eseguire nuove sessioni senza il repository del progetto o l’accesso all’API del repository. Le autorizzazioni Git, per i segreti, per i connettori e per gli strumenti restano separate. Le sessioni esistenti conservano i criteri salvati. AgentConfigBlock.workspace è deprecato. L’SDK mappa branch/runtime legacy al campo booleano. Una scrittura legacy di read richiede una scelta esplicita di repository_access; non abilita l’accesso in sola lettura al repository.

Accesso a provider e modelli

Leggi beeuni.projects.modelAccess(projectId). Modifica un singolo target con beeuni.projects.setModelAccess(projectId, { target: 'provider' | 'model', id, enabled }).

Usa l’ID provider beeuni per i modelli gestiti da Beeuni, oppure l’ID di un provider del catalogo per BYOK, Codex e i provider personalizzati. Usa l’ID wire completo del gateway per un modello. La disabilitazione di un provider si applica ai modelli futuri e conserva le preferenze dei singoli modelli e le credenziali salvate.

Il modello predefinito corrente e il relativo provider richiedono una sostituzione prima della disabilitazione (409 cannot_disable_default). Le richieste dirette al gateway verso target disabilitati non vanno a buon fine con model_disabled o provider_disabled. Le richieste upstream già in corso terminano normalmente. Il flag enforced della risposta è false quando il progetto usa runtime nativo invece del gateway.

I consumer React usano useModelAccess(projectId) da @beeuni/sdk/react. La sua mutazione setEnabled(change) aggiorna il catalogo di gestione e il selettore delle sessioni.

Questa pagina ti è stata utile?