Documentation
¶
Overview ¶
Package team handles multi-agent coordination: routing messages between agents (Dispatcher) and polling inboxes to trigger execution (TeamBus).
Dependency chain (no cycles):
internal/agent → (AgentProfile, ProfileRegistry) internal/mailbox → (Message, Mailbox) internal/team → imports both, owns coordination logic
Index ¶
- Variables
- func FormatIncoming(msg mailbox.Message) string
- type AgentToolFactory
- type Dispatcher
- func (d *Dispatcher) Assign(ctx context.Context, fromID, role, teamID, subject, body string) error
- func (d *Dispatcher) Broadcast(ctx context.Context, fromID, teamID, subject, body string) error
- func (d *Dispatcher) Reply(ctx context.Context, fromID, toID, replyToID, subject, body string) error
- func (d *Dispatcher) Send(ctx context.Context, fromID, toID, subject, body string) error
- type ErrNoAgentForRole
- type MessageHandler
- type Team
- type TeamBus
- type TeamRegistry
- func (r *TeamRegistry) AddMember(ctx context.Context, teamID, agentID string) error
- func (r *TeamRegistry) Create(ctx context.Context, t Team) error
- func (r *TeamRegistry) Delete(ctx context.Context, id string) error
- func (r *TeamRegistry) Get(ctx context.Context, id string) (Team, error)
- func (r *TeamRegistry) GetByName(ctx context.Context, name string) (Team, error)
- func (r *TeamRegistry) List(ctx context.Context) ([]Team, error)
- func (r *TeamRegistry) Members(ctx context.Context, teamID string) ([]agent.AgentProfile, error)
- func (r *TeamRegistry) RemoveMember(ctx context.Context, agentID string) error
- func (r *TeamRegistry) Update(ctx context.Context, t Team) error
Constants ¶
This section is empty.
Variables ¶
var ErrTeamNotFound = db.ErrTeamNotFound
ErrTeamNotFound is returned when a team lookup yields no result.
Functions ¶
func FormatIncoming ¶
FormatIncoming formats a mailbox message as the opening user turn text fed to the agent's session.
Types ¶
type AgentToolFactory ¶
AgentToolFactory builds per-session tools scoped to a specific agent. It is called once per incoming message with the receiving agent's profile ID so that tools like mailbox_send can pre-bake the correct sender identity.
type Dispatcher ¶
type Dispatcher struct {
// contains filtered or unexported fields
}
Dispatcher routes messages between agents using the mailbox as transport.
func NewDispatcher ¶
func NewDispatcher(registry *agent.ProfileRegistry, mb mailbox.Mailbox) *Dispatcher
NewDispatcher creates a Dispatcher wired to the given registry and mailbox.
func (*Dispatcher) Assign ¶
func (d *Dispatcher) Assign(ctx context.Context, fromID, role, teamID, subject, body string) error
Assign delivers a task to the first agent matching the given role, optionally scoped to a team. Returns ErrNoAgentForRole when no match found.
func (*Dispatcher) Broadcast ¶
func (d *Dispatcher) Broadcast(ctx context.Context, fromID, teamID, subject, body string) error
Broadcast sends a message to all agents in a team. The sender (fromID) is excluded from the recipients.
type ErrNoAgentForRole ¶
ErrNoAgentForRole is returned by Assign when no agent matches the criteria.
func (*ErrNoAgentForRole) Error ¶
func (e *ErrNoAgentForRole) Error() string
type MessageHandler ¶
MessageHandler is called by TeamBus when a message arrives for an agent. The handler is responsible for processing the message and sending any reply via the Dispatcher. Session execution is wired here by the caller.
func NewSessionHandler ¶
func NewSessionHandler(eng *engine.Engine, toolFactory AgentToolFactory, profileReg *agent.ProfileRegistry, teams *TeamRegistry) MessageHandler
NewSessionHandler returns a MessageHandler that runs a live engine session for each incoming mailbox message. The parent engine is forked per message so concurrent agent sessions remain fully isolated (each gets its own Loop).
profileReg and teams are used to inject team-awareness into the system prompt (agent ID, team name, roster of teammates and their IDs). Either may be nil to skip the corresponding enrichment.
toolFactory, when non-nil, is called after session creation to register per-agent tools (e.g. mailbox_send, mailbox_broadcast). Pass nil if no extra tools are needed.
Usage:
dispatcher := team.NewDispatcher(reg, mb)
factory := func(id string) []tool.Tool {
return []tool.Tool{
mailboxtool.NewSendTool(dispatcher, id),
mailboxtool.NewBroadcastTool(dispatcher, id),
}
}
handler := team.NewSessionHandler(eng, factory, profileReg, teamReg)
bus := team.NewTeamBus(registry, mb, handler, 2*time.Second)
bus.Start(ctx)
type Team ¶
type Team struct {
// ID is a UUID — globally unique, never changes.
ID string `json:"id"`
// Name is a human-readable label, unique across all teams.
Name string `json:"name"`
// Description explains the team's purpose.
Description string `json:"description,omitempty"`
// Metadata holds arbitrary extension fields.
Metadata map[string]string `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Team is a named, persistent group of agents. Its ID is the stable routing key stored in AgentProfile.TeamID — use it when dispatching or broadcasting.
type TeamBus ¶
type TeamBus struct {
// contains filtered or unexported fields
}
TeamBus polls every registered agent's mailbox and dispatches incoming messages to the configured handler. It is intentionally minimal — session execution is wired by the caller via MessageHandler.
func NewTeamBus ¶
func NewTeamBus( registry *agent.ProfileRegistry, mb mailbox.Mailbox, handler MessageHandler, pollInterval time.Duration, ) *TeamBus
NewTeamBus creates a TeamBus. pollInterval controls how often each agent's inbox is checked; 0 defaults to 2 seconds.
type TeamRegistry ¶
type TeamRegistry struct {
// contains filtered or unexported fields
}
TeamRegistry stores and retrieves Team records backed by SQLite. Member assignment updates AgentProfile.TeamID directly so the mailbox routing keys stay consistent without a separate join table.
func NewTeamRegistry ¶
func NewTeamRegistry(database *db.DB, profiles *agent.ProfileRegistry) *TeamRegistry
NewTeamRegistry creates a TeamRegistry wired to the given DB and profile registry (used for member queries and assignment).
func (*TeamRegistry) AddMember ¶
func (r *TeamRegistry) AddMember(ctx context.Context, teamID, agentID string) error
AddMember assigns an agent to this team by updating AgentProfile.TeamID. An agent belongs to at most one team; re-calling with a different teamID moves the agent.
func (*TeamRegistry) Create ¶
func (r *TeamRegistry) Create(ctx context.Context, t Team) error
Create persists a new team. Returns an error when the name is already taken.
func (*TeamRegistry) Delete ¶
func (r *TeamRegistry) Delete(ctx context.Context, id string) error
Delete removes the team record. Agent profiles that reference this team's ID keep their TeamID field — callers should RemoveMember each agent first when disbanding cleanly.
func (*TeamRegistry) Get ¶
Get returns the team with the given UUID. Returns ErrTeamNotFound when absent.
func (*TeamRegistry) GetByName ¶
GetByName returns the team whose name matches exactly (case-sensitive). Returns ErrTeamNotFound when absent.
func (*TeamRegistry) List ¶
func (r *TeamRegistry) List(ctx context.Context) ([]Team, error)
List returns all teams ordered by name.
func (*TeamRegistry) Members ¶
func (r *TeamRegistry) Members(ctx context.Context, teamID string) ([]agent.AgentProfile, error)
Members returns all AgentProfiles currently assigned to the given team.
func (*TeamRegistry) RemoveMember ¶
func (r *TeamRegistry) RemoveMember(ctx context.Context, agentID string) error
RemoveMember clears AgentProfile.TeamID for the given agent.