hive

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Background-task helpers. `bee bg` spawns detached child engines and drops their stdout/stderr under <beeHome>/sessions/bg/<session-id>.log. Pure helpers — no exec, no syscall — so the package stays portable.

Result fan-in helpers. Plain functions over []Result so callers can compose them without bringing in the Pool dependency.

Queen-and-workers orchestration.

The Queen runs three or four phases:

  1. decompose: ask Planner Runner to split the task into ≤8 sub-tasks (JSON objects pairing role + task).
  2. dispatch: round-robin sub-tasks to Workers, fan out via goroutines.
  3. review: (optional) hand worker outputs to Critic for a short critique.
  4. synthesize: hand all worker outputs (plus critique if any) back to Planner for a final summary.

Pool from spawn.go (slice 4A) is preferred when available; this file uses direct goroutine fan-out so the queen still builds even if 4A is missing.

Review gate: the queen's last quality pass after workers finish changing code, before the result is handed back (and the user commits).

Three reviewers each inspect the ACTUAL working-tree changes on one axis — correctness, persistence, integration — and list concrete findings. Every finding is then re-verified by an independent pass that must actively refute it to drop it; uncertain verdicts keep the finding so a real issue is never hidden. Confirmed findings flow into synthesize so the final answer names what still needs attention.

Fan-out orchestrator. Spawns up to MaxConcurrency workers in parallel, each driving its own Engine via the Runner contract. Results stream out on a channel as workers finish; cancellation propagates through ctx.

Triage: queen mode's adaptive front door. Not every task needs a planning + multi-reviewer hive — a typo fix, a rename, or a plain question is faster and cheaper as a single pass. A cheap side-LLM call (one token) decides, and the caller routes small/clear work straight to a normal turn, reserving the hive for tasks that actually warrant it.

Package hive implements multi-bee orchestration: fan-out (Pool), queen-and- workers (Queen), and the result fan-in primitives both share.

A Worker wraps a single loop.Engine running in its own goroutine. The TUI visual concept lives in internal/tui/hive.go and is intentionally separate.

Index

Constants

View Source
const MaxSubTasks = 8

MaxSubTasks caps how many sub-tasks the queen will accept from the planner. matches the prompt budget; defends against runaway plans.

Variables

This section is empty.

Functions

func EnsureLogDir

func EnsureLogDir(sessionID string) (string, error)

EnsureLogDir creates the parent directory for LogPath and returns the fully-qualified log path. Idempotent.

func LogDir

func LogDir() (string, error)

LogDir returns the directory holding background log files.

func LogPath

func LogPath(sessionID string) (string, error)

LogPath returns the absolute path where a background session's combined stdout/stderr should be written. It does not create anything on disk.

func MergeText

func MergeText(results []Result) string

MergeText concatenates the final text from each successful worker into a single transcript with `## <name>` headers. Failed workers are omitted.

func ReadPid

func ReadPid(sessionID string) (int, error)

ReadPid reads a pidfile if it exists.

func SpawnWorker added in v0.1.1

func SpawnWorker(parent *loop.Engine, label string) (*loop.Engine, *session.Rollout, error)

SpawnWorker clones a worker engine from parent, reusing its Provider, Tools, Skills, Cfg, and Cwd but giving it a fresh session rollout so the worker's transcript stays isolated from the parent's. Returns the engine and its rollout; the caller owns closing the rollout.

Memory and the live channels (StreamCh/ThinkCh/...) are intentionally left nil: a hive worker runs silently and its answer is read back from RunResult.FinalText, mirroring `bee swarm`'s cheap fan-out workers. label is debug-only — the session id is the canonical handle.

func Summary

func Summary(results []Result) string

Summary renders a human-readable summary block: counts, wall-clock, and one line per worker. Wall-clock is min(Started)..max(Ended), so it reflects actual parallel duration, not sum-of-bee-times.

func TriageSimple added in v0.1.1

func TriageSimple(ctx context.Context, p llm.Provider, model, task string) bool

TriageSimple returns true when task is small/clear enough to skip the hive. On any provider error, empty input, or ambiguous reply it returns false (complex) — over-planning a trivial task wastes tokens, but under-reviewing a risky change is worse, so ambiguity defaults to the full hive.

func WritePid

func WritePid(sessionID string, pid int) error

WritePid writes the process id to a pidfile beside the log.

Types

type Finding added in v0.1.1

type Finding struct {
	Dimension string
	Claim     string
	Confirmed bool
	Verdict   string
}

Finding is one issue a reviewer raised plus the verifier's verdict. A finding with Confirmed=false was refuted on re-verification and is dropped from the synthesis (but retained in QueenResult.Findings for the record).

type Hooks added in v0.1.1

type Hooks struct {
	OnPlan        func(plan []SubTask)
	OnWorkerStart func(idx int, sub SubTask)
	OnWorkerDone  func(idx int, res Result)
	OnReview      func(dimension string, claims []string)
	OnVerify      func(f Finding)
	OnCritique    func(critique string)
	OnSynthesize  func()
}

Hooks observes a Queen run as it progresses. Every callback is optional; nil callbacks are skipped, so existing callers (bee swarm) pass a zero Hooks and see unchanged behavior. Callbacks run on the goroutine driving the phase (OnWorkerStart/Done fire from worker goroutines) — keep them cheap and non-blocking (a channel send the UI drains is ideal).

type Pool

type Pool struct {
	MaxConcurrency int

	Workers []*Worker
	// contains filtered or unexported fields
}

Pool manages a bounded set of concurrent Workers.

func NewPool

func NewPool(max int) *Pool

NewPool builds a Pool with the given concurrency cap. A non-positive cap is treated as 1 — refusing to run any work would surprise callers.

func (*Pool) Run

func (p *Pool) Run(ctx context.Context) <-chan Result

Run dispatches submitted workers up to MaxConcurrency at a time. Each worker's Engine.Run is invoked with a context derived from ctx. Results land on the returned channel as workers finish; the channel closes once all workers are done (including those skipped by cancellation).

func (*Pool) Submit

func (p *Pool) Submit(w *Worker)

Submit registers a Worker with the pool. State starts at pending. Safe to call before Run; calling after Run is a no-op for that worker because the dispatcher has already iterated the snapshot.

func (*Pool) WorkersSnapshot

func (p *Pool) WorkersSnapshot() []*Worker

WorkersSnapshot returns a shallow copy of the Worker pointer slice for observers (TUI, tests). The pointed-to Worker structs are still shared, so reading State/Started/Ended is a live view.

type Queen

type Queen struct {
	Planner Runner
	Workers []Runner
	Critic  Runner
	// Reviewers drive the verified review gate (decompose → … → review →
	// verify → synthesize). When non-empty it supersedes Critic: each reviewer
	// is paired to a ReviewDimension by index and inspects the real working-tree
	// changes. Verifier (optional) re-checks every finding adversarially.
	Reviewers        []Runner
	Verifier         Runner
	ReviewDimensions []ReviewDimension // 0 => DefaultReviewDimensions()
	MaxParallel      int               // 0 => len(Workers)
	// Hooks observes progress for a live UI. Zero value = no observation.
	Hooks Hooks
}

Queen orchestrates a planner Runner and N worker Runners. Critic is optional; when set, its output is appended to the synthesize prompt.

func NewQueen

func NewQueen(planner Runner, workers []Runner) *Queen

NewQueen returns a Queen ready to Run. MaxParallel defaults to len(workers).

func (*Queen) Run

func (q *Queen) Run(ctx context.Context, task string) (QueenResult, error)

Run executes the full decompose → dispatch → (review) → synthesize pipeline.

type QueenResult

type QueenResult struct {
	Plan          []SubTask
	WorkerResults []Result
	Critique      string
	Findings      []Finding // verified review-gate findings (empty if gate not run)
	Final         string
}

QueenResult is the aggregate of one Queen.Run.

type Result

type Result struct {
	WorkerID string
	Name     string
	Task     string
	Final    string
	Err      error
	Started  time.Time
	Ended    time.Time
}

Result is what a Worker emits on completion. Final is the final assistant text; Err is non-nil if the run failed.

func Collect

func Collect(ch <-chan Result) []Result

Collect drains ch into a slice. Returns when the channel is closed. Order matches arrival order, not submission order.

type ReviewDimension added in v0.1.1

type ReviewDimension struct {
	Name  string
	Focus string
}

ReviewDimension is one axis the queen verifies. Focus is injected verbatim into the reviewer prompt so each reviewer stays on its single concern.

func DefaultReviewDimensions added in v0.1.1

func DefaultReviewDimensions() []ReviewDimension

DefaultReviewDimensions are the three axes checked after a hive run mutates the tree. Order is stable — reviewers are paired to dimensions by index.

type Role

type Role string

Role names a hive specialist. Each role pairs a tuned system prompt with a tool allowlist. The queen.go / pool.go wiring decides defaults when a role's AllowedTools is empty.

const (
	RoleQueen        Role = "queen"
	RoleSubqueen     Role = "subqueen"
	RoleBuilder      Role = "builder"
	RoleScoutPlanner Role = "scout_planner"
	RoleForeman      Role = "foreman"
	RoleSage         Role = "sage"
	RoleArchivist    Role = "archivist"
	RoleForager      Role = "forager"
	RoleDiviner      Role = "diviner"
	RoleCritic       Role = "critic"
	RoleEye          Role = "eye"
)

func AllRoles

func AllRoles() []Role

AllRoles returns every defined role in stable order.

func ParseRole

func ParseRole(s string) (Role, bool)

ParseRole accepts the canonical name (case-insensitive) and returns the Role + ok. Whitespace is trimmed.

func (Role) AllowedTools

func (r Role) AllowedTools() []string

AllowedTools returns the tool names this role may invoke. Empty slice means "all tools" — caller decides default. Returned slice is a copy.

func (Role) SystemPrompt

func (r Role) SystemPrompt() string

SystemPrompt returns the role-tuned system prompt text. Empty for unknown roles.

func (Role) Temperature

func (r Role) Temperature() float64

Temperature returns the recommended sampling temperature for the role.

type Runner

type Runner interface {
	Run(ctx context.Context, userMsg string) (loop.RunResult, error)
}

Runner is the contract Pool and Queen both rely on. It exists so callers can inject a stub Runner in tests instead of a real loop.Engine.

type State

type State string

State of a Worker bee.

const (
	StatePending  State = "pending"
	StateRunning  State = "running"
	StateDone     State = "done"
	StateFailed   State = "failed"
	StateCanceled State = "canceled"
)

type SubTask

type SubTask struct {
	Role Role
	Task string
}

SubTask pairs a single planner-emitted sub-task with the role that should execute it. Queen produces these during decompose and uses them downstream in dispatch + synthesize.

type Worker

type Worker struct {
	ID      string
	Name    string
	Task    string
	Engine  *loop.Engine
	State   State
	Started time.Time
	Ended   time.Time
}

Worker is one bee executing one task against its own Engine.

Engine is required; the rest is filled in by Pool/Queen and observed via the Result channel.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL