Referência do SDK
Toda a superfície da API do @beeuni/sdk — métodos do cliente, módulos, turns e distribuição.
Esta página apresenta toda a superfície da API @beeuni/sdk: cada método do cliente, os módulos independentes de framework, os auxiliares de turns e como o pacote é distribuído. Use SDK para começar e Sessions para conhecer em detalhes o ciclo de vida das sessões.
O cliente
createBeeuni(config) retorna um cliente. Cada método é uma chamada tipada à API da plataforma. Os handles project(id) e session(pid, sid) vinculam IDs para que você nunca precise repeti-los.
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
Contas — beeuni.accounts
| método | descrição |
|---|---|
list() · get(accountId) |
contas às quais você pertence · uma conta |
create({ name }) · updateName(accountId, name) |
criar · renomear uma conta |
branding.get(accountId) · branding.update(accountId, { app_name }) · branding.uploadAsset(accountId, kind, file) · branding.removeAsset(accountId, kind) · branding.reset(accountId) |
identidade visual da organização (Enterprise): usar logo / ícone / favicon próprios e nome do produto; kind é logo · icon · favicon, ou logo_dark · icon_dark · favicon_dark para a variante de esquema escuro |
members(accountId) · invite(accountId, input) |
listar membros · convidar um membro |
updateMemberRole(accountId, userId, role) · removeMember(accountId, userId) |
atribuir a função na conta · remover um membro |
invites(accountId) |
convites pendentes |
cancelInvite(accountId, inviteId) · resendInvite(accountId, inviteId) |
cancelar · reenviar um convite pendente |
leave(accountId) |
sair da conta |
accounts.tokens cria chaves de API vinculadas à conta (beeuni_pat_...). Consulte SDK auth para conhecer o modelo completo de tokens.
| método | descrição |
|---|---|
tokens.list(accountId?, options?) |
listar chaves de API — de toda a conta ou apenas as suas com { mine: true } |
tokens.create(input) |
criar uma — { accountId?, name, expiresAt?, projectId? } |
tokens.revoke(tokenId, accountId?) |
revogar uma |
accounts.audit é o registro de reconstrução empresarial. Ele combina solicitações de API autenticadas com eventos semânticos de sessão, conector, aprovação e computador.
| método | descrição |
|---|---|
audit.log(accountId, filters?) |
listar eventos por projeto, sessão, ator, origem, resultado, solicitação, correlação, recurso, ação ou horário |
audit.export(accountId, filters?) |
exportar o mesmo fluxo de eventos filtrado como CSV ou JSONL |
audit.webhooks.list/create/update/remove(...) |
gerenciar webhooks SIEM assinados para o fluxo centralizado |
Cada evento inclui project_id, session_id, actor_type, source, outcome, request_id, trace_id e correlation_id quando a ação os fornece. A API não armazena corpos de solicitações, prompts, segredos, credenciais ou argumentos brutos de conectores no evento centralizado. Os eventos de conectores podem incluir uma prévia limitada dos argumentos que remove campos semelhantes a credenciais e dados opacos.
Atribuições de acesso
O Beeuni tem um único registro de concessão: uma atribuição. Ela vincula um principal (user, group, service_account ou pending) a uma função, em um escopo (account ou um project), opcionalmente restringido a um objeto (agent, skill, secret, app ou trigger) e opcionalmente contendo um expires_at. O acesso de grupos, o acesso por recurso e os vínculos de funções personalizadas são todos atribuições. Consulte Accounts & access para conhecer o modelo.
A superfície REST canônica é:
| Método + caminho | Ação |
|---|---|
GET /v1/accounts/{accountId}/iam/assignments |
listar atribuições, filtradas por principal, escopo, objeto ou função |
POST /v1/accounts/{accountId}/iam/assignments |
criar uma atribuição |
DELETE /v1/accounts/{accountId}/iam/assignments/{assignmentId} |
revogar uma atribuição |
GET /v1/accounts/{accountId}/iam/permissions |
catálogo de permissões, como dados |
GET /v1/accounts/{accountId}/iam/roles · …/roles/{roleId}/permissions |
funções · permissões de uma função |
O SDK as expõe como listAssignments, createAssignment, revokeAssignment e listPermissions. Uma linha do catálogo contém action, scope_type, resource_type, delegable, description, area, level e implies — leia esses dados em vez de codificar strings de ação manualmente.
A atribuição de uma função personalizada exige a permissão rbac da conta; sem ela, a rota responde 402 com code: "entitlement_required".
Convites de conta — beeuni.accountInvites
Acessados apenas pelo token do convite — o convidado ainda pode não ser membro.
| método | descrição |
|---|---|
listMine() |
todos os convites pendentes e não expirados direcionados ao seu e-mail, com o workspace e todos os projetos que eles concedem |
describe(inviteId) · accept(inviteId) · decline(inviteId) |
visualizar · aceitar · recusar um convite |
Projetos — beeuni.projects
| método | descrição |
|---|---|
list() · listForAccount(accountId) |
seus projetos · projetos em uma conta |
get(id) · detail(id) |
resumo · detalhes completos |
create(input) · createRepo(input) |
a partir de um repo_url existente · novo repositório GitHub vazio |
provision(input) |
novo projeto em um novo repositório gerenciado pelo Beeuni, inicializado com um template inicial — { name, account_id?, seed_starter?, starter_template?, marketplace_items?, source_item_id?, idempotency_key? } |
update(id, input) · archive(id) |
atualizar configurações · arquivar |
llmCatalog(id) · modelPicker(id) |
catálogo completo · compacto de modelos para um seletor |
sandboxTemplates(id) · sandboxHealth(id) |
templates de build do sandbox · integridade do build |
sessions(id) · createSession(id, input?) |
listar sessões visíveis · criar uma sessão |
provision cria um novo projeto; não inicia o sandbox de um projeto existente. Em vez disso, inicie uma sessão — consulte Sessions.
Envie idempotency_key quando for possível tentar novamente — uma recarga, uma segunda aba ou um timeout após uma nova tentativa. provision cria um novo repositório gerenciado a cada chamada; portanto, sem uma chave, todas essas chamadas criam projetos duplicados reais. Reutilize uma chave em todas as tentativas de uma única criação lógica, e as repetições retornarão o projeto criado pela primeira tentativa (201, mesmo project_id, push_token: null). A chave identifica a tentativa, não o payload — reutilizá-la com um name diferente retorna o primeiro projeto e ignora o novo valor; portanto, crie uma chave nova para cada criação distinta. Criar um segundo projeto com o mesmo nome e sem chave continua funcionando.
Uma repetição que chega enquanto a primeira chamada ainda está provisionando recebe 409 com code: 'provision_in_flight', em vez de um project_id; essa chamada ainda pode sofrer rollback. Tente novamente com a mesma chave.
project(id).sessions.list({ scope: 'project' }) é um inventário do ciclo de vida para um chamador com permissões de gerenciamento de projetos. Ele adiciona sessões acessíveis indisponíveis, aquecidas e excluídas logicamente, com metadados de propriedade e estado de execução. Ambos os escopos de listagem omitem todas as sessões que o chamador não pode abrir.
sessions.list e sessions.listPage também aceitam os filtros de hierarquia e atribuição. Sem eles, a lista permanece simples e inalterada.
| opção | descrição |
|---|---|
parent: 'root' |
Somente sessões de nível superior. Cada linha contém child_count. |
parent: '<sessionId>' |
Filhos dessa sessão, do mais recente para o mais antigo. |
startedBy: 'me' | 'others' | 'automated' |
Filtrar por initiator, em relação ao chamador. |
q |
Pesquisa que não diferencia maiúsculas de minúsculas em título, rótulo inicial, slug do gatilho e prefixo do ID da sessão, em todas as sessões que o chamador pode abrir. Com parent: 'root', uma raiz que correspondeu por meio de um filho tem search_match: 'child'. |
Cada linha de sessão contém parent_session_id e initiator ({ type: 'member' | 'trigger' | 'channel' | 'api' | 'system', id, label }). initiator informa quem iniciou toda a execução; um filho copia o valor do pai. sessionParentId(session) lê parent_session_id e, depois, o legado metadata.spawned_by_session. Um cursor só é válido para o conjunto de filtros que o emitiu.
GitHub — beeuni.github
Instalação do GitHub App e vinculação de repositórios no escopo da conta, não do projeto.
| método | função |
|---|---|
getInstallation(accountId) · listInstallations(accountId) |
instalação desta conta · instalações acessíveis ao usuário |
saveInstallation(input) · deleteInstallation(accountId, installationId?) |
registrar · desvincular uma instalação |
listLinkableInstallations(input) |
instalações que o usuário autorizado do GitHub pode vincular; cada entrada contém linked_to_other_accounts, uma contagem de outras contas Beeuni que a possuem — nunca seus nomes |
listRepositories(accountId, installationId?) · listRepositoryBranches(...) |
repositórios que a instalação pode ver · branches e a branch padrão do GitHub |
linkRepository(input) |
Importar um repositório como projeto usando uma instalação autorizada do GitHub. |
replaceProjectRepository({ project_id, repo_url, expected_repo_url, github_token }) |
substituir o repositório GitHub de um projeto existente. Use github_token com acesso de leitura/gravação em Contents, ou installation_id mais github_user_token temporário para verificar o acesso de administrador da organização e conceder acesso somente a este repositório pelo GitHub App. copy_shared_secrets_from_project_id mais copy_shared_secret_identifiers copia os segredos compartilhados de runtime selecionados na mesma transação. Um expected_repo_url desatualizado retorna 409. O repositório antigo permanece no GitHub. Novas sessões usam o repositório substituto; sessões existentes mantêm seu checkout. |
Esta lista contém apenas conexões reais de contas. “Beeuni managed” não é uma delas — é o backend da instância abaixo.
Backend git da instância — beeuni.gitBackend
Um único proprietário e uma credencial para toda a implantação, usados para repositórios
gerenciados pelo Beeuni. Nunca é uma conexão de conta e nunca aparece em
beeuni.github.listInstallations.
| método | função |
|---|---|
get() |
{ configured, kind: 'app' | 'pat' | null, owner } — legível por qualquer usuário autenticado; expõe apenas o login do proprietário que cada repo_url gerenciado já contém |
Faturamento — beeuni.billing
Consulta créditos, assinatura, plano e histórico de transações. Use o pagamento e a gestão de cobrança do Beeuni para pagamentos e compras de créditos.
| método | função |
|---|---|
accountState(accountId?) · accountStateMinimal(accountId?) |
estado de faturamento completo · mínimo |
transactions(params?) · transactionsSummary(params?) |
histórico · totais resumidos |
creditBreakdown(accountId?) · usageHistory(params?) |
saldo de créditos por origem · uso ao longo do tempo |
sessionCosts.list(options?) · sessionCosts.get(sessionId, options?) |
registros paginados de custos de sessões · um registro detalhado de uma sessão |
tierConfigurations() |
níveis de plano disponíveis |
checkout.createSession(input) · checkout.confirmSession(sessionId, accountId?) |
Obsoletos. Rejeitam com ENDPOINT_RETIRED. Removidos na próxima versão principal. |
subscription.createPortalSession(...) · subscription.cancel(...) · subscription.reactivate(...) |
abrir o portal do cliente · cancelar · reativar |
subscription.cancelScheduledChange(...) · prorationPreview(...) |
cancelar · visualizar uma alteração de plano |
subscription.scheduleDowngrade(...) |
Obsoleto. Rejeita com ENDPOINT_RETIRED. Altere o plano no portal do cliente. Removido na próxima versão principal. |
credits.purchase(input) · credits.autoTopupSettings(...) · credits.configureAutoTopup(...) |
compra avulsa · consultar · configurar recarga automática |
sessionCosts.list() aceita accountId, projectId, limit e offset.
Cada linha combina o custo finalizado de LLM e o custo faturado de computação do sandbox.
sessionCosts.get() adiciona o uso de modelos e o registro discriminado de LLM/computação.
A lista inclui um total de conciliação para custos sem sessão.
Compartilhamentos de sandbox — beeuni.sandboxShares
Links públicos de compartilhamento para uma porta exposta do sandbox. Com escopo de sandbox, não de projeto.
| método | função |
|---|---|
list(sandboxId) |
links de compartilhamento ativos |
create(input) |
criar um — { sandboxId, port, ttl?, label? } |
revoke(sandboxId, token) |
revogar um |
Catálogo do marketplace — beeuni.marketplace
Navegação no catálogo público, somente leitura — diferente de project(id).marketplace,
que instala um item em um projeto.
| método | função |
|---|---|
items(options?) · item(id) · itemFile(id, path) |
navegar · um item · um arquivo dentro de um item |
marketplaces() · featured() |
todos os marketplaces · marketplaces em destaque |
sources.list() · sources.add(input) · sources.remove(id) |
listar · adicionar · remover uma origem |
Notificações — beeuni.notifications
As notificações de quem faz a chamada, em todas as contas e projetos. Cada pessoa conectada
tem uma caixa de entrada, um registro de preferências e inscrições Web Push para
seus navegadores. Todos os métodos precisam da credencial de uma pessoa: uma conta de serviço
recebe 403.
const page = await beeuni.notifications.list({ limit: 20 });
await beeuni.notifications.markRead({ ids: [page.notifications[0].id] });
await beeuni.notifications.updatePreferences({ kinds: { turn_done: { push: false } } });
| método | função |
|---|---|
list({ limit?, before? }, { signal? }) |
a página mais recente: { notifications, unread_count, next_before }. limit vai de 1 a 50 (padrão 20). Passe next_before como before para a próxima página. Linhas que quem faz a chamada não pode mais ver são omitidas. Uma falha não chama o manipulador de erros do host. |
markRead({ ids }) · markRead({ all: true }) · markRead({ sessionId }) |
marcar como lidas de 1 a 100 linhas, todas as linhas ou todas as linhas de uma sessão. Altera apenas as linhas de quem faz a chamada. Retorna { updated, unread_count }. |
preferences() · updatePreferences({ kinds }) |
consultar · alterar a opção de push e e-mail por tipo. Retorna { kinds, email_available }. Um patch altera apenas os tipos e canais que especifica. |
webPushPublicKey() |
{ public_key }: o applicationServerKey para pushManager.subscribe |
registerWebPushSubscription({ endpoint, keys }) |
enviar push para este navegador. Exige login no navegador: um token pessoal recebe 403. Um endpoint em um serviço push desconhecido recebe 400. |
unregisterWebPushSubscription(endpoint, { signal? }) |
parar o push para este navegador. Retorna { deleted }. |
registerDeviceToken(input) · unregisterDeviceToken(token, { signal? }) |
registrar · remover o token push Expo de um aplicativo nativo |
Tipos (InboxNotificationKind, listados em INBOX_NOTIFICATION_KINDS):
| tipo | enviado quando | push | e-mail (padrão) |
|---|---|---|---|
turn_done |
um turno que você solicitou ou acompanha terminou | ativado | desativado |
turn_error |
esse turno terminou com um erro | ativado | ativado, em um resumo |
question |
o agente faz uma pergunta | ativado | ativado, em um resumo |
permission |
o agente solicita permissão | ativado | desativado |
shared |
alguém compartilhou uma sessão com você | ativado | ativado, em um resumo |
automation_failed |
uma automação que você acompanha começou a falhar | ativado | ativado, imediatamente |
automation_recovered |
essa automação volta a funcionar | ativado | desativado |
DEFAULT_NOTIFICATION_PREFERENCES contém esses padrões. A linha da caixa de entrada é
sempre gravada; as preferências determinam apenas push e e-mail. Um e-mail de resumo
lista as linhas ainda não lidas 15 minutos após sua chegada, com no máximo um resumo
por hora. Oculte a coluna de e-mail quando email_available for false.
O url de cada linha abre seu assunto. Seu parâmetro de consulta ?notification=<id> permite que a
página marque a linha como lida.
O handle da sessão contém o acompanhamento de uma sessão por quem faz a chamada:
| método | função |
|---|---|
session(pid, sid).watch() |
{ watching }: se quem faz a chamada recebe notificações sobre esta sessão |
session(pid, sid).setWatch(watching) |
false silencia a sessão para quem faz a chamada, true volta a acompanhá-la. Enviar um prompt a uma sessão passa a acompanhá-la, mas nunca desfaz o silenciamento. |
session(pid, sid).presence({ tab_id, active, alerts? }, { keepalive? }) |
concessão de presença desta aba. alerts: true indica que a aba mostra suas próprias notificações: com notification_center ativado, o servidor omite o push para celular e o Web Push apenas enquanto uma aba que exibe alertas está em uso. Com ele desativado, alerts é ignorado e qualquer aba presente impede o push para celular. keepalive permite que a solicitação continue após o fechamento de uma página. Padrão: ativado para um relatório de ausência, desativado para um de presença. useSession envia keepalive apenas com presencePageExit. |
O handle do projeto — beeuni.project(id)
Vincula o ID do projeto; todos os sub-recursos dependem dele.
const p = beeuni.project(projectId);
await p.detail();
await p.update({ name });
await p.llmCatalog();
| método | descrição |
|---|---|
get · detail · update · archive |
ler · detalhes completos · atualizar · arquivar |
llmCatalog · modelPicker · sandboxHealth |
leituras do modelo e da compilação no sandbox |
onboardingComplete |
marcar a integração inicial do projeto como concluída |
validateManifest(raw) |
validar no servidor um manifesto beeuni.yaml (ou beeuni.toml legado) |
gitToken() |
gerar um novo token de push do git com escopo (409 para um repositório próprio) |
setAgentScope(agentName, scope) |
definir os segredos e conectores permitidos para um agente no manifesto — a segunda vinculação, não uma função |
p.tokens — chaves de API com escopo de projeto
Geradas automaticamente na criação da sessão como BEEUNI_TOKEN; também podem ser geradas manualmente.
| método | descrição |
|---|---|
list() |
chaves de API do projeto |
create(input?) |
gerar uma nova |
revoke(tokenId) |
revogar uma |
p.setupLinks — links de configuração gerados pelo agente
Um link que uma pessoa abre para inserir um segredo ou conectar um aplicativo, sem acesso completo ao projeto.
| método | descrição |
|---|---|
requestSecret(input) · requestConnector(input) |
link para coletar um segredo · conectar um aplicativo |
p.apps — Aplicativos (releases, máquinas, volumes)
Por trás do recurso de projeto apps. Guia: SDK → Aplicativos.
| método | descrição |
|---|---|
list() · get(appId) · create(input) · update(appId, input) · remove(appId) |
inventário e ciclo de vida; create aceita uses, update também aceita labels |
deployments.* · artifacts.* · access.* · rollback · start · stop |
implantações, artefatos, a política de acesso, tráfego e runtime |
machines.list/start/stop/restart/destroy · scale(appId, count) · exec(appId, input) |
máquinas por grupo de processos; exec precisa de project.app.admin |
volumes.list/create/update/destroy/snapshots/snapshot/restore/fork |
volumes persistentes, snapshots diários, restauração, bifurcação |
token(appId) |
um token de login válido por 15 minutos; 409 app_capability_unsupported sem member_tokens |
p.secrets — segredos do projeto
| método | descrição |
|---|---|
list() · upsert(input) |
listar metadados · criar ou atualizar um valor somente para escrita e a política de entrega |
setStrategy(identifier, strategy, options?) |
alterar a exposição e sua lista de hosts |
broker(identifier, request) |
executar uma solicitação HTTPS autorizada pela sessão e vinculada à política |
remove(identifier) |
excluir um segredo |
setPersonal(name, value) · removePersonal(name) |
definir · remover uma substituição por usuário |
setGitCredential(input) |
definir uma credencial de autenticação do git |
runtime com o consumidor sandbox é uma exposição de ambiente — o padrão e a única política que coloca um valor em texto simples na sessão. egress com o consumidor network é uma exposição imposta na saída: a sessão mantém um identificador e o Beeuni substitui o valor real fora do sandbox, para os hosts HTTPS exatos listados pela política. A exposição imposta na saída é experimental; ela precisa do sinalizador de recurso secrets_egress (Configurações → Sinalizadores de recursos). Com o sinalizador desativado, setStrategy(identifier, 'egress', …) e upsert(...) com uma política de saída retornam 403 feature_disabled. Todo consumidor broker não tem presença alguma na sessão. Consulte Segredos. O método broker(...) exige um token com escopo de sessão e um identificador de sessão ativo.
p.access — atribuições, convites e solicitações do projeto
Cada método aqui lê ou grava uma atribuição com escopo para este projeto. As funções do projeto são manager e member.
| método | descrição |
|---|---|
list() · invite(email, role) |
identidades com acesso · convidar um usuário |
update(userId, role) · revoke(userId) |
atribuir uma função de projeto · revogar a atribuição |
pendingInvites() · requests() |
convites pendentes · solicitações de acesso pendentes |
resendInvite(inviteId) · revokeInvite(inviteId) · approveRequest(id) · rejectRequest(id) |
reenviar/revogar um convite · aprovar/rejeitar uma solicitação |
groupGrants() · attachGroupGrant(...) · updateGroupGrant(...) · detachGroupGrant(...) |
as mesmas atribuições, com uma identidade group |
p.access.resourceGrants é a visualização de atribuição de objeto: ela restringe uma identidade a um objeto no projeto, em vez de ao projeto inteiro. Atualmente, o Beeuni impõe atribuições de objeto a agentes e habilidades. Um agente é fechado por padrão — um membro só chega até ele quando uma atribuição o nomeia ou nomeia um de seus grupos. Uma atribuição de objeto não tem permissões próprias e restringe um gerente de projeto tanto quanto um membro.
| método | descrição |
|---|---|
resourceGrants.list() |
atribuições de objeto neste projeto |
resourceGrants.create(input) |
atribuir um objeto a um usuário ou grupo |
resourceGrants.remove(grantId) |
revogar uma atribuição de objeto |
p.connector(slug) — um conector
| método | descrição |
|---|---|
run(action, args, options?) |
a saída da ação; gera ConnectorCallError ou ConnectorApprovalPendingError — consulte Erros |
call(action, args, options?) |
o resultado bruto da chamada; 202 resolve com ok: false |
describe() · describe(action) |
o conector com esquemas de entrada e saída · uma ação |
accounts() |
as contas que este chamador pode usar para executá-lo, a primeira por padrão |
paginate(action, args, { next, maxPages? }) |
iterador assíncrono sobre a saída de cada página; gera ConnectorPageLimitError com nextArgs quando existem mais de maxPages páginas (100 por padrão) — consulte Páginas |
uploadAttachment(content, input) |
p.connectors.uploadAttachment com connector definido como este slug |
options: account, approvalContext, timeoutMs (90.000 por padrão), signal. Com o arquivo de beeuni connectors types, os argumentos e a saída são tipados.
p.connectors — conectores de ferramentas
| método | descrição |
|---|---|
catalog() · tools() |
catálogo de Connectors chamáveis · ferramentas <connector>.<action> niveladas |
search(query, options?) · describe(tool) |
localizar · inspecionar uma ferramenta chamável |
call(tool, args?, options?) |
chamar uma ferramenta <connector>.<action> pelo gateway no servidor. options.account indica qual conta usar — veja abaixo. |
accounts(slug) |
as contas que este chamador pode usar para chamar slug, a primeira por padrão — aquilo com que options.account faz correspondência |
uploadAttachment(content, input) |
preparar bytes para input.connector; retorna ref ({ $beeuni_attachment }) para inserir nos argumentos de uma chamada posterior — consulte Anexar arquivos |
list() · config(connectorId) |
conectores configurados · configuração de um conector |
create(input) |
adicionar um conector |
auth.discover(input) |
visualizar a autenticação de uma especificação OpenAPI, coleção do Postman ou endpoint |
remove(connectorId) · sync() |
excluir um conector · ressincronizar conectores |
setName(connectorId, name) · setSensitive(connectorId, sensitive) |
renomear · marcá-lo como sensível (exige aprovação adicional) |
setAuthorizationStrategy(slug, strategy) |
@deprecated. Ainda chama a rota; a rota não faz nada e responde {ok:true, deprecated:true}. owner_type em cada conexão é agora toda a regra de acesso. |
setCredentialMode(connectorId, mode) · setCredential(connectorId, input) |
trocar a origem · definir o valor da credencial |
policies.get(connectorId) · policies.set(connectorId, policies) |
ler · substituir as políticas de ferramentas |
connections.list() · connections.reconcile(input) |
listar · criar/atualizar contas conectadas |
connections.updateCredential(connectionId, input) |
alternar a credencial de uma conexão |
connections.revoke(connectionId) · connections.activate(connectionId) |
negar · restaurar uma conexão |
connections.setDefault(connectionId) |
torná-la padrão para o escopo de proprietário |
connections.rename(connectionId, label) |
alterar apenas o rótulo; a conta continua autorizada. Cada conexão contém connected_as, a identidade com a qual foi autorizada. |
p.connectors.discover navega pelo catálogo de conectores diretos. É experimental e fica desativado por padrão — ative-o por projeto em Configurações → Sinalizadores de recursos → “Connectors API Discover”. O Easy Connect continua sendo o marketplace de conectores padrão.
| método | descrição |
|---|---|
discover.list(query?, cursor?) · discover.detail(id) |
pesquisar entradas OpenAPI/MCP/GraphQL/CLI · detalhes de uma entrada |
p.connectors.pipedream é o caminho de compatibilidade do OAuth gerenciado anterior; listApps
retorna apenas apps OAuth. Use Easy Connect para novas integrações gerenciadas. Conecte apps com chave de API diretamente.
| método | função |
|---|---|
pipedream.listApps(params?) · pipedream.connect(input) · pipedream.finalize(input) |
navegar pelo catálogo de apps · iniciar um fluxo de conexão · finalizá-lo |
Um conector define a ferramenta, o app do provedor e as políticas. connections
armazena suas contas conectadas — um conector pode manter várias lado a lado.
Uma sessão pode fixar uma para todas as chamadas com
connector_bindings: { alias: { connection_id } }, ou uma chamada individual pode indicar
uma com call(tool, args, { account }). As credenciais permanecem criptografadas e
são resolvidas a cada solicitação.
connections é a única fachada de autorização ativa. Os nomes descontinuados
authorizations e profiles não fazem parte da interface atual do SDK.
Contas e a verificação no momento da chamada
Cada conexão tem um owner_type: project (compartilhada — acessível por qualquer pessoa
à qual o conector tenha sido concedido, seja uma pessoa ou uma conta de serviço) ou member (privada —
acessível apenas pelo próprio proprietário, e somente em uma sessão privada; nunca por uma
conta de serviço). Uma conta compartilhada pode ser restrita a grupos e pessoas:
connections.list() retorna suas concessões em shared_with, e
connectionSharedWithEveryone(connection) informa se todos no
projeto podem usá-la. Uma conta restrita segue as regras de contas privadas para as
pessoas que especifica, e usable: false marca uma conta que o chamador vê apenas para gerenciá-la.
Conceda ou revogue com createAssignment / revokeAssignment
(object: { type: 'connection', id }) — veja
Escolha quem pode usar uma conta compartilhada.
p.connectors.accounts(slug) lista todas as contas que este chamador pode acessar,
com a padrão primeiro:
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`
);
Uma chamada que não indica uma conta é resolvida primeiro para a conta privada padrão
do próprio chamador e, depois, para a conta compartilhada padrão do projeto. Uma conta indicada
que não é resolvida é negada com connector_not_connected — nunca
substituída silenciosamente — e a negação lista requested_account e
available_accounts. Toda chamada bem-sucedida informa com qual conta foi executada:
result.account = { connection_id, label, owner_type }.
Não há mais uma verificação de conector no momento da criação da sessão. Antes, uma sessão era
recusada com 409 CONNECTOR_CONNECTION_REQUIRED quando um conector obrigatório não tinha uma
conexão utilizável; essa recusa foi removida (require_connectors é inerte — veja
p.sessions). A verificação passou para a
chamada: um connector_not_connected negado inclui connect_url, um link de
autorização hospedado, sempre que for possível gerar um para o chamador — toda a
solução exige um clique, disponibilizado pelo botão de conexão da transcrição.
p.policies — políticas do projeto
| método | função |
|---|---|
list() · set(policies) |
políticas do projeto · substituir o conjunto |
p.triggers — automações de cron, webhook, monitoramento e eventos
Um gatilho inicia uma ação do agente em um agendamento, um webhook recebido, um comando monitorado ou um evento de app em um conector. Veja Gatilhos para a estratégia de sessão e a criação de templates de payload.
| método | função |
|---|---|
list() |
todos os gatilhos |
eventTypes({ connector }) |
eventos de app que podem acionar um conector ({ provider, app, event_types }); 404 para um conector desconhecido, 409 event_source_unavailable quando seu provedor não tem uma fonte de eventos |
create(input) |
criar um |
update(triggerId, input) |
editar um gatilho |
remove(triggerId) |
excluir um gatilho |
fire(triggerId) |
executá-lo agora |
setActivation(paused) |
pausar ou retomar todos os gatilhos do projeto |
create(input) recebe { 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 são obrigatórios.
cron/run_at são mutuamente exclusivos (type: 'cron'); secret_env (o
segredo HMAC do webhook) se aplica a type: 'webhook'.
Um gatilho event precisa de connector (um slug de conector) e event (um ID de tipo
de eventTypes). event_account é opcional: o rótulo de uma conta compartilhada
desse conector; null ou sua omissão usa a conta compartilhada padrão do conector.
event_source é opcional: o ID do adaptador de fonte de eventos, como composio. null ou sua omissão usa o
provedor do conector. O ID de tipo pertence a esse adaptador. event_config tem a estrutura definida pelo config_schema desse tipo.
eventTypes e eventApps informam o adaptador como source; provider é um alias obsoleto.
Cada gatilho listado inclui event: { connector, account, connected_as, type, config, source, provider, app, status: 'active' | 'needs_connection' | 'error' | 'pending', error, last_event_at } | null. Os templates de prompt leem o evento como
{{ event.data.<field> }} mais event.id, event.type, event.app,
event.connector e event.occurred_at.
session_access controla quem pode abrir as sessões criadas pelo gatilho. É
{ mode: 'private' | 'members' | 'project', memberIds: string[], groupIds: string[] } and defaults to private. Essa política é um estado de execução
local da conta. Ela não entra no manifesto portátil beeuni.yaml. Atualizar apenas
session_access não cria um commit Git. Uma sessão fixada mantém suas próprias configurações de
compartilhamento. Um gerente de projeto sempre pode abrir sessões criadas por gatilhos, incluindo
sessões que usam private ou acesso para membros selecionados.
session_access é uma configuração de visibilidade por recurso sobre o modelo de papéis,
não um papel. Ela decide quem pode abrir as sessões de um gatilho. Não concede nenhuma
permissão negada pela decisão do papel. Veja
Contas e acesso.
p.marketplace / p.registry — itens instalados
Instala os arquivos de um item do catálogo na branch padrão do projeto.
registry.* é um alias idêntico de marketplace.*.
| método | função |
|---|---|
marketplace.list() · marketplace.install(id) |
itens instalados · instalar um item do catálogo |
marketplace.updates() · marketplace.update(name) · marketplace.updateAll() |
atualizações disponíveis · atualizar um · atualizar todos |
marketplace.remove(name) |
desinstalar um item |
p.files — arquivos do repositório (leitura)
Acesso somente leitura à árvore Git do projeto. Para ler e gravar arquivos em uma sessão em execução, use as operações de arquivo da sessão — veja Arquivos em Módulos abaixo.
| método | função |
|---|---|
listDirectory({ ref?, path? }) |
um nível de pasta: { entries: [{ path, type, size? }], truncated }. Use para construir uma árvore; cada pasta está completa até 5.000 entradas. |
list(options?) · read(path, ref?) |
todos os arquivos em um caminho, recursivamente, limitado a 1.000 (a resposta inclui X-Beeuni-Truncated: 1 quando limitada) · o conteúdo de um arquivo em uma ref Git |
search(query, { content?, ref?, limit? }) |
pesquisar nomes de arquivos em todo o repositório, ou conteúdo com content: true |
archive(options?) · history(path) |
baixar um tarball · o histórico Git de um arquivo |
p.git — histórico
| método | função |
|---|---|
commits() |
o log de commits |
commit(sha) · commitDiff(sha) |
um commit · seu diff |
branches() · versionDiff(from, to) |
branches · diff entre duas refs |
p.changeRequests — ciclo de vida e merge
Uma solicitação de alteração (CR) é a forma de integrar o trabalho de uma sessão à branch padrão.
| método | função |
|---|---|
list() · get(crId) |
CRs abertas · uma CR |
diff(crId) · mergePreview(crId) |
seu diff · visualizar o resultado do merge |
open(input) · merge(crId, input?) |
abrir · fazer merge de uma CR |
close(crId, input?) · reopen(crId, input?) |
fechar sem fazer merge · reabrir uma fechada |
requestChanges(crId, input) |
registrar feedback, opcionalmente enviado de volta à sessão de origem |
p.sessions — e o handle da sessão
| método | descrição |
|---|---|
list() |
as sessões do projeto |
create(input?) |
criar uma sessão |
session(sid) |
o identificador da sessão (igual a beeuni.session(id, sid)) |
O identificador da sessão é o coração do runtime — consulte Sessões.
create(input) aceita connector_bindings identificados pelo slug da conexão do conector.
Cada valor nomeia um connection_id. Ele também aceita secrets para
restringir segredos originados no backend. require_connectors está obsoleto e
inativo: o campo ainda é aceito (um cliente antigo nunca é rejeitado por
enviá-lo), mas nada o lê — uma sessão nunca é recusada no momento da criação
por um conector sem uma conta utilizável. Consulte Contas e o bloqueio no momento da chamada.
p.approvals — caixa de entrada de aprovações de conectores
Ações pendentes protegidas por conectores aguardando uma decisão — dá suporte à
UX de aprovação de permissões (APPROVE / ASK / BLOCK).
| método | descrição |
|---|---|
list(options?) · sessionsNeedingInput(options?) |
aprovações pendentes · sessões bloqueadas aguardando uma decisão |
resolve(executionId, decision, scope?) |
aprovar ou negar uma — decision: 'approve' | 'deny', scope: 'once' | 'session' | 'session_all' |
p.gateway — observabilidade de LLM
Logs de solicitações, agregações de custo/latência, orçamentos e chaves de API do gateway para o tráfego de modelos deste projeto.
| método | descrição |
|---|---|
logs(opts?) · log(logId) |
entradas do log de solicitações · uma entrada do log |
overview(days?) · series(days?) · breakdown(days?) · sessions(days?) · errors(days?) |
agregações, custo por sessão e erros em um intervalo |
budgets() · setBudget(input) · deleteBudget(budgetId) |
ler · criar/editar · remover um orçamento |
keys() · createKey(name) · revokeKey(keyId) |
listar · gerar · revogar uma chave de API do gateway |
playground(prompt, models) |
executar um prompt em até 6 modelos |
routing.get() · routing.set(policy) · routing.reset() |
ler · substituir · herdar a política de roteamento |
routing.preview(input) |
resolver uma rota sem invocar um modelo |
Uma política de roteamento contém um modelo padrão, um modelo de visão e uma
cadeia ordenada de fallback; cada modelo é tentado no máximo uma vez; fallbackOn é
transient ou any-error.
O gateway passa para o próximo modelo de fallback somente quando o modelo atual falha antes de retornar qualquer saída:
transient: um erro de rede, um timeout, qualquer5xxou402,403,429.any-error: toda falha, incluindo um400.
Uma falha após o início da saída permanece com esse modelo. Uma solicitação com sua própria chave de provedor (BYOK) nunca faz fallback para um modelo faturado pela Beeuni. Cada modelo de fallback recebe seus próprios padrões de geração.
p.channels — Slack / e-mail / voz
Superfícies de conectores que permitem que um agente atue como um app do Slack, um endereço de e-mail ou participe de uma chamada de voz em tempo real.
| método | descrição |
|---|---|
slack.installation() · slack.mode() · slack.manifest() |
instalação atual · modo · manifesto do app |
slack.connect(input) · slack.disconnect() |
conectar · desconectar |
slack.getFile(url) · slack.uploadFile(input) |
baixar · enviar um arquivo por meio do proxy do servidor |
email.installation(connectorSlug?) · email.mode() |
instalação atual · modo |
email.connect(input) · email.disconnect(...) · email.updatePolicy(input) |
conectar · desconectar · atualizar a política de envio/resposta |
voice.setBotName(name) |
renomear o bot em uma chamada em andamento |
p.modelDefaults — preferências do modelo padrão
Padrões de modelo no escopo da conta, do agente e do projeto, resolvidos pelo gateway.
| método | descrição |
|---|---|
get() · set(input) · clear(params) |
ler · definir um padrão · limpar uma substituição |
p.setDefaultAgent — agente padrão do projeto
p.setDefaultAgent(agentName) verifica se o agente foi declarado e está habilitado,
então o define como default_agent no beeuni.yaml do projeto. Novas sessões
preferem esse agente, a menos que o usuário escolha outro.
p.updateFeatureFlag — flags de recurso
p.updateFeatureFlag(feature, enabled) ativa ou desativa uma flag de recurso para o
projeto. Passe enabled: null para limpar a substituição e voltar ao
padrão da plataforma. Ele chama o PATCH /v1/projects/:id/features canônico.
feature é um de FEATURE_FLAG_KEYS (exportado de @beeuni/sdk, tipado como
FeatureFlagKey). O chamador precisa da permissão project.settings.write do projeto;
a rota responde 403 caso contrário.
Toda rota protegida por flag rejeita da mesma forma enquanto a flag estiver desativada: HTTP 403
com { error, code: "feature_disabled", feature }. Use isFeatureDisabledError(error)
para testar essa condição e featureDisabledKey(error) para ler a chave da flag — nunca
compare o texto da mensagem.
p.updateExperimentalFeature(feature, enabled) é o alias obsoleto. Ele
continua chamando o alias de rota obsoleto PATCH /v1/projects/:id/experimental
para que consumidores fixados em uma API implantada mais antiga continuem funcionando. Use
p.updateFeatureFlag em código novo.
p.sandbox — templates e builds de snapshot
Configuração de build do sandbox além de sandboxHealth/sandboxTemplates no identificador
do projeto: templates de Dockerfile/imagem/pool aquecido e seus builds de snapshot.
| método | descrição |
|---|---|
list() · snapshots() |
sandboxes deste projeto · snapshots compilados |
rebuildSnapshot(slug?) · fixWithAgent() |
reconstruir um snapshot · pedir a um agente para corrigir um build com falha |
createTemplate(input) · updateTemplate(...) · removeTemplate(...) · buildTemplate(...) |
adicionar · editar · excluir · compilar um template |
setProvider(provider) |
solicitar uma troca de provedor. null (ou o padrão da plataforma / o provedor já ativo) é aplicado imediatamente; trocar para um provedor habilitado diferente inicia uma transição durável de preparação→verificação→ativação — o provedor atual continua atendendo enquanto a imagem aquecida do destino é compilada e verificada, e então ativada. O retorno é uma união marcada: kind:'project' (imediato) ou kind:'preparation' (consultar getProjectSandboxProviderTransition() até activated/failed) |
Ganchos de administração da plataforma (@beeuni/sdk/react)
Esses ganchos atendem ao console de administração. A API só responde a eles
para um administrador da plataforma. Cada mutação invalida as consultas de
['admin', 'accounts'].
| Hook | O que faz |
|---|---|
useAdminRole(userId, options?) |
ler a função do chamador de GET /user-roles → { isAdmin, role }. userId identifica o cache. A ausência de userId desativa a consulta. Faz nova busca na montagem e ao receber foco, portanto uma função revogada deixa de controlar o acesso em uma navegação. |
useAdminGrantCredits() |
mutação { accountId, amount, description, isExpiring }: adicionar crédito à carteira. POST /admin/api/accounts/:id/credits. Move dinheiro: confirme primeiro na UI. |
useAdminDebitCredits() |
mutação { accountId, amount, description }: remover crédito da carteira. POST /admin/api/accounts/:id/credits/debit. Move dinheiro: confirme primeiro na UI. |
useAdminSetTier() |
mutação { accountId, tier }: definir o nível do plano. |
useAdminGrantTrial() |
mutação { accountId, tierKey, seats, durationDays, creditGrant?, note? }: conceder ou substituir um período de avaliação. A conta se comporta como tierKey até o fim da janela. creditGrant também adiciona crédito à carteira. |
useAdminRevokeTrial() |
mutação { accountId }: encerrar agora um período de avaliação ativo. Responde 400 quando não há nenhum ativo. |
Escape hatch
beeuni.runtime() retorna o cliente REST tipado do runtime para o sandbox
ativo.
Em um cliente criado por createScopedBeeuni (@beeuni/sdk/server), ele lança uma exceção
— o runtime global “ativo” é o sandbox da solicitação de outro locatário em um
servidor multi-inquilino, um vazamento entre locatários. Use o
beeuni.session(pid, sid).runtime com escopo de sessão (chame ensureReady() primeiro), que
resolve o próprio sandbox dessa sessão.
Módulos
Os módulos sem framework por trás da fachada do cliente e dos hooks do React. Use-os quando precisar de uma operação sem a fachada, de um helper puro ou de uma camada de isolamento exclusiva do Node. Cada módulo tem um nível de estabilidade para que você saiba sobre o que construir.
| Categoria | Significado |
|---|---|
| Canônico | Importe da raiz @beeuni/sdk. Use isso em todo código novo. |
| Suportado | Um subcaminho dedicado (@beeuni/sdk/react, @beeuni/sdk/server). De primeira classe, não obsoleto. |
| Alias obsoleto | Um subcaminho antigo que ainda funciona. Reexporta código que a raiz já exporta. Importe da raiz em vez disso. |
| Interno | Fora do semver. Não importe isso no código do host. |
O ponto de entrada raiz é canônico. Todos os nomes abaixo que não dependem de frameworks podem ser importados
diretamente de @beeuni/sdk:
import { files, getSessionHealth, getClient, authenticatedFetch, backendApi } from '@beeuni/sdk';
Módulos canônicos
| Módulo | O que faz |
|---|---|
| Arquivos | Operações de arquivos do workspace: listar, ler, pesquisar, gravar |
| Runtime de sessão | Sondagem de integridade e construtores de URLs de prévia/proxy |
| Cliente runtime | O cliente REST tipado do runtime e todo o seu conjunto de tipos |
| Autenticação | authenticatedFetch e acessores de token |
| REST de projetos | As funções REST brutas encapsuladas pela fachada |
| Cliente de API | backendApi, o cliente HTTP tipado de baixo nível |
| Turnos | Agrupamento de mensagens em turnos, cálculos de custo e status — veja Turnos |
| Transcrições | formatTranscript, uma exportação Markdown no lado do cliente |
| Listas do compositor | As listas de agentes e modelos do compositor de sessão: quais oferecer, quais são executados |
Arquivos
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}`);
},
});
Uploads maiores que 64 KiB atravessam o limite do sandbox em blocos verificados. O callback de progresso é executado após cada bloco chegar ao sistema de arquivos da sessão.
uploadNativeFile({ uri, name, type? }, targetPath, baseUrl) envia um
arquivo do dispositivo a partir do React Native em uma única requisição. O runtime transmite os bytes de
uri, portanto eles nunca entram no heap do JS. Ele usa a mesma autenticação, prazo e
reexecução de 401 que files.upload. Não divide em blocos.
fetchProjectArchive, fetchCostExportCsv e as chamadas de versão do sandbox enviam
pelo mesmo transporte. Uma falha lança um ApiError com status.
files.write(path, blob) substitui o arquivo em path e falha se path for uma
pasta. files.create(path) cria um arquivo vazio e nunca sobrescreve: quando um
arquivo ou pasta já existe em path, lança 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 tem como alvo o sandbox globalmente ativo. Se o host executa mais de uma
sessão ao mesmo tempo, chame s.files no identificador da sessão em vez disso. Ele sempre
tem como alvo o sandbox da própria sessão. Veja Sessões.
Funções auxiliares do runtime de sessão
import { getSessionHealth, isRuntimeReady } from '@beeuni/sdk';
const result = await getSessionHealth();
if (result.ok && isRuntimeReady(result.health)) {
// the sandbox daemon is ready
}
getSessionHealth nunca lança uma exceção para um status fora de 2xx. Retorna
{ status, ok, health, body } e deixa você decidir o que um status significa. O
mesmo módulo exporta as funções auxiliares de URL que reescrevem a saída localhost de um agente
como uma URL de proxy acessível: detectLocalhostUrls, rewriteLocalhostUrl,
proxyLocalhostUrl, parseLocalhostUrl e buildWebProxyUrl.
Cliente runtime
import { getClient } from '@beeuni/sdk';
const client = getClient();
const { data } = await client.session.list({ limit: 100 });
getClient() retorna o cliente de compatibilidade tipado do runtime para o sandbox ativo,
com a autenticação já injetada. Prefira beeuni.session(pid, sid).runtime, o
mesmo cliente com escopo de uma sessão, ao getClient() global quando o
host executar mais de uma sessão.
Funções auxiliares de autenticação
import { authenticatedFetch, getAuthToken } from '@beeuni/sdk';
const res = await authenticatedFetch(`${runtimeUrl}/beeuni/health`);
const token = await getAuthToken();
O token vem da função getToken que você passou para createBeeuni.
A maior parte do código do aplicativo não precisa deste módulo — as camadas de arquivos, sessões e fachada
já autenticam por você.
Cliente de API
import { backendApi } from '@beeuni/sdk';
const data = await backendApi.get('/some/endpoint');
await backendApi.post('/some/endpoint', { name: 'x' });
backendApi é o cliente HTTP tipado no qual todas as funções REST se baseiam. Use-o
apenas para um endpoint que ainda não tenha um wrapper tipado.
Listas de agentes e modelos do compositor
Crie os seletores de agentes e modelos de um compositor de sessão com as mesmas regras usadas pelo aplicativo web Beeuni. Todas as funções são puras: busque as entradas com o cliente e depois passe-as para as funções.
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 retorna explicit: undefined quando o compositor está em
seu padrão. model é a chave a exibir e enviar. O
id de cada modelo achatado é a referência armazenada por uma seleção; modelRefToKey(ref, gatewayEnabled) converte uma
referência armazenada (uma fixação de sessão, uma vinculação de canal, o model de um gatilho) de volta em uma
chave.
Subcaminhos suportados
| Subcaminho | O que faz |
|---|---|
@beeuni/sdk/react |
Hooks do React — veja Hooks do React |
@beeuni/sdk/server |
Configuração com escopo de requisição para backends multitenant |
@beeuni/sdk/wire-message-id |
Apenas o relógio de IDs de mensagens do protocolo runtime (um módulo, sem importações). A raiz exporta os mesmos nomes |
IDs de mensagens do protocolo
O messageId de um prompt é sua posição na transcrição. O runtime ordena
mensagens por msg_ + um relógio de 48 bits (Date.now() * 0x1000, 48 bits inferiores) +
14 caracteres base62, e o relógio volta ao início a cada 2^36 ms (cerca de 2,2 anos).
Nunca o codifique manualmente.
import { mintWireMessageId } from '@beeuni/sdk';
// `after`: the ids already in this session's transcript.
const messageId = mintWireMessageId({ after: transcriptIds });
A geração é datada dois minutos atrás e depois elevada um tick acima do ID mais recente
em after que esteja no máximo uma hora à frente. Um chamador que mantém a posição mais recente
como relógio em vez de IDs usa mintWireMessageIdAbove({ nowMs, newestKnownTime }), which returns { id, time }. newestWireIdClock(ids)
para encontrar esse relógio. Todas as comparações são feitas no anel, portanto IDs dos dois lados de um
retorno ao início mantêm sua ordem real.
O relógio de 48 bits volta ao início a cada ~2,2 anos, então nunca compare dois relógios com >
ou <=: um ID gerado logo após um retorno ao início é numericamente menor que um gerado
logo antes. Use wireIdClockDelta(clock, reference), a distância com sinal
no anel (positiva quando clock está à frente), e maxWireIdClock(clocks) para
o mais recente entre vários:
import { maxWireIdClock, wireIdClockDelta } from '@beeuni/sdk/wire-message-id';
const floor = maxWireIdClock([transcriptNewest, deliveredNewest]);
const stale = floor !== null && wireIdClockDelta(clientClock, floor) <= 0n;
Isolamento no lado do servidor
createBeeuni armazena sua configuração, incluindo a função de token, em uma
variável global do processo. Isso funciona para uma aba do navegador, uma CLI ou um
servidor de tenant único. Não é seguro para um servidor Node que processa requisições
simultâneas de usuários diferentes, porque a última chamada de createBeeuni prevalece para
todas as requisições em andamento. @beeuni/sdk/server resolve isso com isolamento por
requisição:
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 isolam a configuração por requisição com
AsyncLocalStorage do Node. Nunca importe @beeuni/sdk/server de um bundle de
navegador — ele inclui estaticamente node:async_hooks.
O runtime() de nível superior de um cliente com escopo lança uma exceção (ele resolveria o
sandbox de outro tenant). Acesse o runtime de uma sessão específica via
beeuni.session(pid, sid).runtime após await s.ensureReady().
Aliases obsoletos
Cerca de vinte subcaminhos antigos ainda funcionam: /files, /turns, /session, /auth,
/projects-client, /api-client, /config, /event-stream,
/opencode-client, /platform-client e outros. Cada um reexporta código que o
ponto de entrada raiz @beeuni/sdk já exporta. Eles continuam funcionando para que nenhum existente
import breaks, but new code should import from the root.
Módulos internos
@beeuni/sdk/internal/* contém os stores do zustand que o próprio runtime de apps/web usa
internamente — estado de sincronização de sessão, rastreamento do runtime ativo e controle de
reconexão. Este subcaminho está explicitamente fora do semver. Não o importe no
código do host; os Hooks do React já expõem o estado de que você
precisa.
Turnos
Funções simples que agrupam mensagens de sessão em turnos e classificam cada
parte da mensagem. Use-as para criar um renderizador de chat personalizado em vez do
de referência em apps/web. Sem React, sem DOM — cada exportação é uma
função simples ou um tipo, que pode ser chamado com segurança de qualquer host.
import { classifyPart, classifyTurn, toolInfo, toolViewModel } from '@beeuni/sdk';
Importe todas as funções do ponto de entrada raiz @beeuni/sdk. O
subcaminho @beeuni/sdk/turns ainda funciona, mas é um alias obsoleto. Código
novo deve usar o ponto de entrada raiz — veja Distribuição.
Classificar uma parte
classifyPart(part) normaliza um dos 12 tipos de parte do formato de
transcrição do Beeuni (beeuni.transcript.v1, BEEUNI_TRANSCRIPT_SCHEMA) em um
ClassifiedPart — uma união indexada por kind. Cada variante já resolve os
campos necessários para um renderizador: status da ferramenta, saída JSON
analisada e detecção de imagem.
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 |
formato |
|---|---|
text |
{ id, text, synthetic } — ignora partes synthetic; elas marcam o prompt sintético do modo shell |
reasoning |
{ id, text } |
tool |
{ id, tool: ToolView } |
file |
{ id, filename?, mime, url, isImage, isPdf } |
subtask |
{ id, description, agent, prompt, model? } |
patch |
{ id, hash, files, fileCount } |
snapshot |
{ id, snapshot } |
agent |
{ id, name } |
retry |
{ id, attempt, message, createdAt } |
compaction |
{ id, auto, overflow, tailStartId? } |
step |
{ id, phase: 'start' | 'finish', snapshot?, reason?, cost?, tokens? } |
unknown |
{ raw } — um tipo de parte que esta versão do SDK não conhece |
Uma parte de transmissão não reconhecida se torna unknown em tempo de
execução, em vez de lançar uma exceção. Isso permite que um cliente mais
antigo converse com um servidor mais novo.
Uma parte de ferramenta é classificada em 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) cria uma diretamente a partir de uma parte de ferramenta. Leia
estes campos em vez do próprio state.metadata de um harness: o mesmo cartão então
renderiza um edit do runtime (filePath, filediff) e um edit do pi
(path, edits, um patch unificado).
Algumas ferramentas (web_search, image_search, chamadas de conectores) informam
state.status: 'completed' mesmo quando o corpo JSON contém success: false. classifyPart detecta
isso e também define ToolView.status como 'error' nesse caso.
classifyTurn(message) classifica cada parte de uma mensagem do assistente e retorna um
ClassifiedTurn com três campos:
parts— cada parte, classificadaerror— demessage.info.error, se houverisEmpty— verdadeiro quando o turno não tem erro nem parte com conteúdo visível
Metadados de ferramentas
toolKind(name) é a taxonomia única de ferramentas: ela mapeia o nome da
ferramenta de qualquer harness (write do pi, oc-apply_patch do runtime,
pty_spawn de um plugin) para um ToolKind — read, edit,
write, bash, web_search, task, question, … ou other.
As famílias de narração, os modelos de visualização, as categorias
toolInfo e o grupo de ferramentas de contexto derivam dela. inputPath(input) lê
o caminho de um arquivo da ferramenta a partir de filePath, file_path ou
path.
toolKind('oc-apply_patch'); // 'apply_patch'
toolKind('pty_spawn'); // 'pty'
inputPath({ path: 'app.py' }); // 'app.py'
Duas outras consultas também descrevem uma ferramenta. Não as confunda.
toolInfo(name)— sem ícone, retorna{ label, category }.classifyPartusa isso internamente.ToolCategoryé'shell' | 'files' | 'search' | 'edit' | 'web' | 'task' | 'other'.getToolInfo(name, input)— ciente de ícone, retorna{ icon, title, subtitle }para a UI de cartão de ferramenta de referência. O subtítulo vem da entrada da ferramenta, por exemplo, um caminho de arquivo ou uma consulta de pesquisa.
toolInfo('bash'); // { label: 'Shell', category: 'shell' }
getToolInfo('write', { filePath: '/workspace/main.go' });
// { icon: 'file-pen', title: 'Write', subtitle: 'main.go /workspace' }
Ambas as funções correspondem a prefixos de nomes de ferramentas, portanto
as famílias de ferramentas de plugins do Beeuni (agent_*, session_*,
task_*, trigger_*, project_*, pty_*) são resolvidas sem atualização
do registro. Um nome de ferramenta desconhecido nunca lança uma exceção —
ele recorre a humanizeToolName(name) com a categoria 'other'.
Modelos de visualização de ferramentas
toolViewModel(classifiedTool) mapeia uma parte de ferramenta classificada para um formato criado
para uma família de ferramentas. Assim, uma UI pode renderizá-la de forma
especial, em vez de como um blob JSON genérico.
const vm = toolViewModel(classifiedTool);
if (vm.kind === 'shell') {
render(vm.command, vm.stdout, vm.exitCode);
}
kind |
formato | ferramentas |
|---|---|---|
web-search |
{ query, results?, answer?, error? } |
web_search, image_search |
shell |
{ command, stdout?, exitCode? } |
bash |
file-read |
{ path, preview? } |
read |
file-write |
{ path, preview? } |
write |
file-edit |
{ path, diff?: DiffLine[] } |
edit, morph_edit |
search |
{ pattern, matches?: SearchMatch[] } |
grep, glob |
task |
{ description, agent? } |
task |
todo |
{ items: TodoItem[] } |
todowrite |
question |
{ questions: QuestionItem[], answers? } |
question, ask |
generic |
{ label, inputPretty?, outputPretty? } |
todo o restante, sempre seguro para renderizar |
DiffLine é { type: 'added' | 'removed' | 'unchanged', text }. Os campos de string têm limites para que uma saída
de ferramenta muito grande nunca interrompa uma renderização: 4000 caracteres
para JSON formatado e 256 KB antes de executar um diff.
Agrupar mensagens em turnos
Um turno combina uma mensagem do usuário com as mensagens do assistente que respondem a ela. É a unidade que uma UI de chat renderiza como uma única interação.
import { groupMessagesIntoTurns, collectTurnParts, type TurnLike } from '@beeuni/sdk';
const turns: TurnLike[] = groupMessagesIntoTurns(messages);
for (const turn of turns) {
const parts = collectTurnParts(turn);
}
groupMessagesIntoTurns vincula cada mensagem do assistente à mensagem do usuário pai.
Quando o vínculo pai está ausente, recorre à ordem das mensagens. Também
anexa ao primeiro turno uma mensagem órfã do assistente — sem pai e anterior
a todas as mensagens do usuário —, não ao último.
Helpers relacionados:
findLastTextPart(parts)— o texto da resposta final do turnoturnHasSteps(parts)— verdadeiro se existir uma partetool,compaction,snapshotoupatchisShellMode(turn)/getShellModePart(turn)— um turno que consiste em um prompt sintético acionando uma chamadabash
Type guards
Restrinja uma parte por type:
import { isTextPart, isToolPart, getPartText } from '@beeuni/sdk';
if (isTextPart(part)) {
// part.type narrowed to 'text'
}
const text = getPartText(part); // works for 'text' and 'reasoning' parts
Também estão disponíveis: isReasoningPart, isFilePart, isAgentPart,
isCompactionPart, isSnapshotPart, isPatchPart, isStepPart
(step-start e step-finish).
Status e erros
import { getWorkingState, getTurnStatus, formatDuration } from '@beeuni/sdk';
const status = getTurnStatus(parts, childMessages); // "Running commands..."
formatDuration(4300); // "4s" — durations under 1s return ''
getTurnStatus verifica as partes de um turno em busca da última linha de status.
Quando a última parte é uma delegação task em execução, passe
childMessages para que o status mostre a atividade real do subagente, em vez de
uma linha genérica de “Delegando…”.
import { getTurnError, getChildSessionError, unwrapError } from '@beeuni/sdk';
getTurnError(turn); // the first assistant error, unwrapped
getChildSessionError(childMessages); // newest error in a sub-agent's messages
unwrapError(rawError); // normalizes double-JSON and mixed error shapes
Custo e totais de tokens
import { getTurnCost, getSessionCost, formatCost, formatTokens } from '@beeuni/sdk';
const info = getTurnCost(partsWithMessage, modelPricingLookup);
const sessionCost = getSessionCost(messages, modelPricingLookup);
formatCost(0.0032); // "$0.003"
formatTokens(12345); // "12k"
Ambas as funções leem os totais de custo e tokens das partes step-finish.
Quando uma parte informa zero, elas estimam o custo a partir das contagens de
tokens usando um ModelPricingLookup.
As mensagens de assinatura do ChatGPT/Codex contribuem com $0.00,
incluindo mensagens históricas com custos de execução diferentes de zero. O
uso de tokens e contexto continua visível. Sessões mistas mantêm as cobranças
por mensagens da API paga. Os modelos da API da OpenAI continuam cobráveis,
incluindo modelos da API cujos nomes contêm codex.
Sessões filhas e solicitações pendentes
A árvore de conversas de uma sessão de projeto (a raiz e as conversas de
subagentes que ela gerou) vem da lista runtime_sessions. Estes helpers a leem,
preferindo os nomes atuais aos anteriores à 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
Uma chamada de ferramenta task delega para uma sessão filha. Estes
helpers conectam um turno pai às próprias mensagens dessa filha.
import { getChildSessionId, getChildSessionToolParts } from '@beeuni/sdk';
const childId = getChildSessionId(taskToolPart);
const steps = getChildSessionToolParts(childMessages);
Associe uma solicitação pendente de permissão ou pergunta à sua chamada de ferramenta e encontre quais partes de ferramenta ocultar enquanto ela estiver ativa:
import { getPermissionForTool, getHiddenToolParts, isToolPartHidden } from '@beeuni/sdk';
const permission = getPermissionForTool(permissions, callID);
const hidden = getHiddenToolParts(activePermission, activeQuestion);
Formatação e listas
import { getFilename, getDirectory, relativizePath, stripAnsi } from '@beeuni/sdk';
getFilename('/workspace/src/main.go'); // "main.go"
getDirectory('/workspace/src/main.go'); // "/workspace/src"
relativizePath('/workspace/src/main.go', '/workspace'); // "src/main.go"
Os helpers de lista de sessões operam nos mesmos dados de sessão:
import { sortSessions, childMapByParent, allDescendantIds } from '@beeuni/sdk';
sessions.sort(sortSessions(Date.now())); // pins sessions updated in the last 60s
const childMap = childMapByParent(sessions);
const descendants = allDescendantIds(childMap, sessionId);
Estado de nova tentativa: getRetryInfo(sessionStatus) retorna { attempt, message, next, details? } when status.type === 'retry', with message limitado a 60
caracteres. details preserva um envelope estruturado do gateway de LLM
quando presente: o provedor final, o código do gateway, o ID da solicitação,
a sugestão, o status upstream e as falhas dos candidatos na ordem. Cada falha
de candidato contém attempt, provider, routeModel, resolvedModel,
stage, o status opcional, code e message. Novas tentativas
em texto simples legado retornam details: undefined. getRetryMessage(sessionStatus) retorna a mensagem
completa sem encapsulamento. Quando o runtime retém apenas essa mensagem, o
composto do gateway ainda inclui o ID da solicitação e o provedor, o modelo
resolvido, o status HTTP, o código e a mensagem limitada de cada candidato.
Tipos estruturais
As funções de agrupamento e status aceitam tipos estruturais mínimos —
PartLike, MessageInfoLike, TurnLike, ToolStateLike,
SessionStatusLike — em vez dos tipos concretos de transcrição.
Os formatos da sua própria mensagem e das partes são mantidos sem alterações, desde que correspondam aos campos obrigatórios. classifyPart e classifyTurn são a exceção.
Eles usam a união Part do Beeuni (beeuni.transcript.v1), portanto a verificação de exaustividade detecta um novo tipo de parte no momento da compilação.
Distribuição
npm install @beeuni/sdk
O pacote é distribuído como ESM compilado, com declarações de tipo completas do TypeScript.
react e @tanstack/react-query são dependências opcionais de mesmo nível. Se você
usar @beeuni/sdk/react, instale ambas.
import { createBeeuni } from '@beeuni/sdk'; // framework-free core
import { useSession } from '@beeuni/sdk/react'; // optional React layer
import { createScopedBeeuni } from '@beeuni/sdk/server'; // Node and Bun servers
Pontos de entrada e estabilidade
A entrada raiz, @beeuni/sdk, é a canônica. Ela exporta toda a superfície independente de framework e funciona em navegadores, Node 18+, Bun e runtimes de edge.
| Entrada | Nível | Contrato |
|---|---|---|
@beeuni/sdk |
Canônica | Independente de framework. Nunca importa React ou node:*. |
@beeuni/sdk/react |
Compatível | Hooks do React. A única entrada que importa React. |
@beeuni/sdk/server |
Compatível | Isolamento da configuração por requisição para servidores Node e Bun, via node:async_hooks. Nunca inclua em um bundle de navegador. |
Subcaminhos legados (/projects-client, /turns, /files e outros) |
Obsoletos | Ainda funcionam. Cada um reexporta a partir da raiz. Em vez disso, importe da raiz. |
@beeuni/sdk/internal/* |
Interna | Usada apenas pelo app web do Beeuni. Não é uma API compatível. |
Bundles de CDN
O pacote também inclui dois bundles para navegador, compilados pelo tsup: um bundle ESM
(dist/beeuni.esm.min.js) e um global IIFE (dist/beeuni.global.js) que
define window.Beeuni.
<script src="https://unpkg.com/@beeuni/sdk/dist/beeuni.global.js"></script>
<script>
const beeuni = Beeuni.createBeeuni({
backendUrl: 'https://api.beeuni.ai/v1',
getToken: async () => KEY,
});
</script>
window.Beeuni expõe a mesma entrada raiz que a importação do npm:
Beeuni.createBeeuni, Beeuni.classifyTurn, Beeuni.ApiError.
Consulte também
- SDK — instalação e sua primeira sessão.
- Sessions — ciclo de vida, streaming e tratamento de erros.
- React hooks — a camada reativa criada sobre esses módulos.
Acesso do agente ao repositório
A configuração do agente aceita repository_access?: boolean (padrão true).
Defina false para executar novas sessões sem o repositório do projeto ou acesso à API do repositório.
As permissões de Git, segredos, conectores e ferramentas permanecem separadas. As sessões existentes mantêm a política salva.
AgentConfigBlock.workspace está obsoleto. O SDK mapeia branch/runtime legados para o campo booleano.
Uma gravação legada de read exige uma escolha explícita de repository_access; ela não habilita o acesso somente leitura ao repositório.
Acesso a provedores e modelos
Leia beeuni.projects.modelAccess(projectId). Altere um destino com beeuni.projects.setModelAccess(projectId, { target: 'provider' | 'model', id, enabled }).
Use o ID de provedor beeuni para os Beeuni Managed Models, ou um ID de provedor do catálogo para BYOK, Codex e provedores personalizados. Use o ID completo do protocolo do gateway para um modelo. A desativação do provedor abrange modelos futuros e preserva as preferências individuais de modelo e as credenciais salvas.
O modelo padrão atual e seu provedor exigem uma substituição antes da desativação (409 cannot_disable_default). As solicitações diretas ao gateway para destinos desativados falham com model_disabled ou provider_disabled. As solicitações upstream já em andamento são concluídas normalmente. O sinalizador enforced da resposta é falso quando o projeto usa o runtime nativo em vez do gateway.
Os consumidores React usam useModelAccess(projectId) de @beeuni/sdk/react. A mutação setEnabled(change) atualiza o catálogo de gerenciamento e o seletor de sessões.