Espaces et agents
Coordonnez plusieurs agents sur un contexte partage avec des espaces, des sessions et des handoffs adosses a des jetons de capacite.
La couche agent : un espace est une base de donnees barrel creee a travers
barrel_spaces, partagee en detenant un jeton de capacite pour elle. Les sessions
donnent aux agents un contexte de travail avec un TTL glissant dans un espace ; un
handoff transfere du travail a un autre agent comme un jeton dont la possession est
le droit d’accepter. Lisez ceci quand vous coordonnez plusieurs agents sur un
contexte partage.
Quand l’utiliser
- Plusieurs agents ont besoin de lire et ecrire le meme contexte sans le copier.
- Vous voulez un acces revocable, par espace, au lieu d’un seul identifiant global.
- Les agents se passent des taches et le destinataire doit voir le contexte de l’emetteur en place.
Espaces et jetons de capacite
Un espace est une base de donnees avec un nom genere (sp_ + 16 caracteres) plus
un document de registre dans la base de donnees systeme _barrel_spaces. Les
bases de donnees d’espace s’ouvrent a travers le gestionnaire de cycle de vie des
bases de Barrel, ainsi les espaces inactifs se ferment eux-memes et des centaines
d’espaces ephemeres restent bon marche.
{ok, _} = application:ensure_all_started(barrel_spaces),
{ok, #{id := SpaceId, db := Db}} = barrel_spaces:create_space(#{
label => <<"joint research">>,
session_ttl => 3600 %% default session TTL, seconds
}),
%% Db is a regular barrel handle: documents, search, timeline all work
{ok, _} = barrel:put_doc(Db, #{<<"id">> => <<"notes">>}),
%% grant access: the token is shown once, only its hash is stored
{ok, Token, _Grant} = barrel_caps:grant(SpaceId, #{
rights => [read, write], %% read < write < admin
subject => <<"agent-bob">>}),
%% the holder verifies (or resolves an auth context)
{ok, _} = barrel_caps:verify(Token, SpaceId, write),
{ok, #{space := SpaceId, rights := _}} = barrel_caps:auth_context(Token),
%% revoke one grant, or drop the space (revokes everything)
ok = barrel_caps:revoke(Token),
ok = barrel_spaces:drop_space(SpaceId).
open_space/2 rouvre un espace existant ; les options d’execution (une spec
encryption, une config de store supplementaire) doivent etre repassees a chaque
ouverture, exactement comme pour n’importe quelle base de donnees barrel. Les cles
de chiffrement par espace sont l’histoire d’isolation : voir
chiffrement.
Sessions
Une session est un document dans la base de donnees d’espace ecrit avec un TTL ; chaque mutation le fait glisser. Les messages sont des documents separes dont les ids se trient chronologiquement. Une session expiree disparait des lectures immediatement et est marquee d’un tombstone par le balayeur de TTL de l’espace ; un janitor collecte ensuite ses messages orphelins.
{ok, Space} = barrel_spaces:open_space(SpaceId),
{ok, Sid} = barrel_session:create(Space, #{agent => <<"alice">>,
ttl => 1800}),
{ok, _} = barrel_session:add_message(Space, Sid, #{
role => <<"user">>, content => <<"draft is half done">>}),
{ok, Messages} = barrel_session:get_messages(Space, Sid,
#{limit => 50, order => desc}),
{ok, _ExpiresAt} = barrel_session:touch(Space, Sid),
%% structured working state and pinned context
{ok, _} = barrel_session:set_data(Space, Sid, <<"cursor">>, 42),
{ok, PinId} = barrel_session:pin_context(Space, Sid,
#{content => <<"key fact">>,
priority => 0}),
{ok, Pinned} = barrel_session:list_pinned(Space, Sid),
ok = barrel_session:delete(Space, Sid). %% cascades to messages
TTL de document (la machinerie en dessous)
Les sessions empruntent une primitive generale qui fonctionne sur n’importe quelle
base de donnees barrel : l’option d’ecriture expires_at (ms unix). Les documents
expires se lisent comme introuvables immediatement ; un balayeur par base de
donnees a activer les transforme en vrais tombstones (pour que la replication et
les branches restent correctes).
{ok, _} = barrel:put_doc(Db, Doc, #{expires_at => Now + 60000}),
%% absent = preserve the current expiry, 0 = clear it
{ok, Swept} = barrel_docdb:sweep_ttl(DbName).
Activez le balayeur avec ttl_sweep_interval (ms) dans la config docdb de la base
de donnees ; les espaces le mettent a 60000 par defaut.
Handoffs
Un handoff est un espace partage plus une capacite. En creer un emet une autorisation et renvoie le jeton une fois ; quiconque detient le jeton accepte. Accepter fait passer le document de handoff de en-attente a accepte avec un CAS (les doubles acceptations perdent), ouvre l’espace, et cree une session pour l’accepteur dedans : le contexte est lu en place, rien n’est copie.
{ok, #{handoff_id := Hid, token := HandoffToken}} =
barrel_handoff:create(Space, #{
task_name => <<"finish the draft">>,
from_agent => <<"alice">>, to_agent => <<"bob">>,
from_session => Sid,
pending => [<<"polish conclusion">>]}),
%% bob, holding only the token:
{ok, #{handoff := H, space := BobSpace, session := BobSid}} =
barrel_handoff:accept(HandoffToken, #{agent => <<"bob">>}),
%% work happens in the shared space, then:
{ok, _} = barrel_handoff:complete(HandoffToken,
#{result => <<"shipped">>}),
%% completion revokes the token by default
%% or hand it on, keeping the lineage (parent/root/depth)
{ok, #{token := NextToken}} = barrel_handoff:chain(HandoffToken, #{
task_name => <<"review the draft">>, to_agent => <<"carol">>}).
Les documents de handoff vivent dans la base de donnees de registre, ainsi les
handoffs en attente sont decouvrables avec barrel_handoff:list/1 (filtres :
space, status, to_agent, from_agent) ou en s’abonnant au flux de
changements du registre.
Via REST et MCP
barrel_server expose tout ceci sous /spaces et /handoffs ; les jetons de
capacite fonctionnent comme bearers la (et seulement la). Voir
rest-server. Les memes operations existent comme
outils MCP (space_*, session_*, handoff_*) ; voir
mcp.
Notes
- Echelle des droits :
read < write < admin. Admin couvre l’octroi, la revocation, et l’emission de handoff. La verification est locale (le registre est une base de donnees sur le meme noeud) ; les jetons sont aleatoires, stockes haches, compares en temps constant. - Le registre (
_barrel_spaces) tient les documents d’espace, d’autorisation et de handoff comme des documents ordinaires : les folds et le flux de changements les voient. - Un espace chiffre a besoin de sa spec de chiffrement a chaque ouverture, y
compris a l’interieur de
barrel_handoff:accept/2(passezopen_opts). Via REST et MCP, les espaces s’ouvrent avec les options par defaut, ainsi les espaces chiffres sont reserves a l’API Erlang en v1. barrel_spaces_janitorbalaie periodiquement les messages de session orphelins des espaces ouverts (janitor_interval, 5 minutes par defaut) ;barrel_spaces_janitor:sweep/0execute une passe maintenant.