Groups
A persisted, named, ordered collection of agents plus a coordination strategy, addressed as one unit via @team.
The public home of
ryu-teams. Source, builds, and releases live here — binaries for every platform are attached to each release.This tree is generated from the Ryu monorepo, so commits pushed here directly are replaced on the next sync. Pull requests are welcome — open them here and they are ported into the monorepo, then flow back out. Ryu as a whole: https://github.com/amajorai/ryu
Install
App: Install (opens the Ryu desktop app and asks you to confirm)
CLI:
ryu apps add @ryu/teams
Crate:
cargo install ryu-teams
Prebuilt binaries for every platform are attached to each release.
License
Apache-2.0 — see LICENSE.
Parts
backend/(ryu-teams) — an extracted Core capability crate: the SQLiteTeamStore(agent-id membership only) and the/api/teams/*HTTP surface. The surface is now served OUT-OF-PROCESS by theryu-teamssidecar bin (below) via the manifestpublic_mount— there is no in-processteams_routesmerge and noteamscargo feature. The crate stays a non-optional path-dep only for the group chat types the session loop consumes (see the weld below), not for the moved surface. This crate has zero dependency onapps/core: its only cross-cutting need, the data-dir path, is injected by the host atTeamStore::open.backend/src/main.rs(ryu-teamsbin) — the same crate also builds a standalone out-of-process sidecar ([[bin]] name = "ryu-teams"): a loopback axum server that opens the node'steams.db, nests the crate'sroutes()under/api/teams, and gates every route with the Core-injectedRYU_EXT_TOKENbearer (fail-closed;/healthis the one un-gated probe). It reuses the crate lib, so nothing is duplicated. Core spawns it via thekind: localsidecar spec in@ryu/teams(RYU_TEAMS_BIN/RYU_TEAMS_PORT, default:8002) and proxies/api/teams/*to it — exactly likeryu-mail.ui/— the self-contained Groups Companion. It lists and edits groups, manages members from the host's read-only agent catalog, selects coordination and lead-agent settings, and handles its own loading, recovery and confirmation states. Calls go through the capability-gatedwindow.ryubridge:app.requestcan reach only this app's sidecar,registry.agentsexposes the agent catalog without credentials, andui.toastreports completed mutations through the host notification system.- group chat orchestration stays in Core. The session loop consumes only the shared
ryu-teams-contractsrecords. The app crate and its HTTP implementation remain out of process; no Teams app code is linked into Core.
Manifest (Core fixture)
- id
@ryu/teams, with one HTML Companion runnable. Theapp:http,core:list_agents, andui:toastgrants cover its own-sidecar CRUD, member picker, and host toast feedback. It has no document or external-service dependency. - sidebar The app contributes its live group list. Rows open the Companion, where group selection and creation stay app-owned instead of creating partial records in the shell.
- contributes three
hook_events(team.created,team.updated,team.deleted), raised fromapi.rsviaryu-app-eventsso hooks and workflows can react to a roster change without polling. The HTTP surface is the right place to raise them because the sidecar ownsteams.dboutright: Core reaches it over loopback (teams_client.rs), so every mutation, including its ownagent_builder's, passes through those handlers once.
Surface
/api/teams (list/create) · per-team :id · :id/members and :id/members/:agent_id
(membership edits). Types: TeamRecord, Coordination, CreateTeam, UpdateTeam.
Swap seam
Membership is agent-id references only, so any agent card can join any group; the coordination strategy is a stored enum, not hardcoded behavior.