Documentation
¶
Overview ¶
Package waggle is bee's self-improving procedure memory.
The forage recorder watches the agent's read-only tool stream; the miner detects repeated routes through it; the promoter crystallizes a route into a runnable exec-skill (a waggle) that later sessions follow instead of re-deriving. The name comes from the waggle dance: how a bee encodes a proven foraging route for the hive to repeat.
Index ¶
- func CompactLedger(path string, keep map[string]bool) error
- func Demote(s *Store, stats map[string]Stat, minFails int) (int, error)
- func GC(s *Store) (int, error)
- func Promote(user *Store) (int, error)
- func PruneStale(s *Store, stats map[string]Stat, maxAge time.Duration, now time.Time) (int, error)
- func ReadLedger(path string) (map[string]Stat, error)
- func Render(name string, c Candidate, scope Scope) (string, bool)
- type Call
- type Candidate
- type CurateResult
- type Ledger
- type LedgerEntry
- type Manager
- type ManagerConfig
- type Meta
- type MineConfig
- type Param
- type Recorder
- type Replayer
- type Route
- type Scope
- type Stat
- type Store
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CompactLedger ¶
CompactLedger rewrites a ledger, keeping only entries whose Name is in keep. Run it after deleting waggle files so a later re-mine of the same (content- stable) name starts with clean stats instead of inheriting a dead route's history — otherwise stale Fails would auto-demote the fresh route. A missing ledger is a no-op.
func Demote ¶
Demote disables waggles whose predictive replay repeatedly diverged without ever paying off: at least minFails recorded divergences (per the ledger) and zero successful uses. A demoted waggle keeps its file (for inspection) but is marked disabled, so LoadRoutes skips it and replay stops firing a route the tree has outgrown. Idempotent: already-disabled waggles are not re-counted. Returns the number newly demoted.
func GC ¶
GC prunes a store: it removes files that fail to parse, have no script, or duplicate a script already kept. Returns the number removed. Safe to run any time — it only touches files under the waggle store, which bee owns.
func Promote ¶
Promote copies any route present in >= 2 distinct project stores into the user store, so a route the agent rediscovers across projects becomes portable. The copy is re-tagged scope: user. Routes already in the user store are skipped. Returns the number promoted.
func PruneStale ¶
PruneStale removes waggles a store never paid off: zero recorded uses (per the ledger stats) and a file older than maxAge. Returns the number removed. now is injected so tests are deterministic. Waggles with any use are always kept.
func ReadLedger ¶
ReadLedger aggregates a JSONL ledger by waggle name. A missing file is not an error (returns an empty map); malformed lines are skipped.
Types ¶
type Call ¶
Call is one recorded tool invocation in the forage log. Args holds the tool's input flattened to strings (sorted-key iteration gives a deterministic shape). Mutates marks a state-changing tool so the miner can exclude it. OutHash and EstTokens feed dedup and yield estimation.
type Candidate ¶
Candidate is a detected reusable route. Steps holds the representative (first) occurrence; Params lists the varying argument positions; Count is the number of non-overlapping times the route's shape recurred.
func Mine ¶
func Mine(calls []Call, cfg MineConfig) []Candidate
Mine scans calls for repeated contiguous read-only routes, returning candidates ranked by score (length * count) descending. Windows containing a mutator are never considered. Callers typically act on the top candidate.
type CurateResult ¶
type CurateResult struct {
RemovedProj int
RemovedUser int
PrunedProj int
PrunedUser int
Demoted int
Promoted int
}
CurateResult reports what a Curate pass changed, for the gc summary line.
func Curate ¶
func Curate(proj, user *Store, staleAge time.Duration, minFails int, now time.Time) (CurateResult, error)
Curate runs the full library maintenance pass over both scopes, in the order that keeps each step's guarantee intact:
- GC — drop duplicate/broken files.
- Demote — disable chronic divergers (rewriting the file refreshes its mtime) so the prune below keeps them this run.
- Prune — delete never-paid-off stale files; a just-demoted file survives via its fresh mtime and only ages out on a later pass.
- Compact — drop ledger history for files now gone, so a re-mined identical route starts clean instead of inheriting a dead route's stats.
- Promote — copy routes recurring across projects (skipping disabled) into the user store.
now is injected for deterministic tests.
type Ledger ¶
type Ledger struct {
// contains filtered or unexported fields
}
Ledger is an append-only reuse log for one scope, persisted as JSONL beside that scope's skills dir. Appends are serialized so concurrent replays in one session can't interleave a line.
func (*Ledger) Append ¶
func (l *Ledger) Append(e LedgerEntry) error
Append records one reuse event, creating the file and parent dir on demand.
type LedgerEntry ¶
type LedgerEntry struct {
Name string `json:"name"`
Steps int `json:"steps"`
Yield int `json:"yield"`
// Fail marks a divergence: the route matched a prefix but its tail exec
// failed or returned nothing. Recorded with zero yield; curation demotes a
// waggle that keeps diverging without ever paying off.
Fail bool `json:"fail,omitempty"`
}
LedgerEntry is one recorded reuse of a waggle. Yield is the estimated tokens saved by collapsing the route's remaining round-trips (chars/4), not a measured counterfactual — useful for ranking and curation, not accounting.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager ties the recorder, miner and promoter to a store. The loop feeds it every read-only tool call via Observe; it periodically mines the forage log and writes one new crystallizable waggle per sweep. All work is read-only and best-effort: a failure never disrupts the turn.
func NewManager ¶
func NewManager(store *Store, cfg ManagerConfig) *Manager
NewManager returns a manager writing to store. A nil store yields a no-op manager so callers need not branch.
type ManagerConfig ¶
type ManagerConfig struct {
Mine MineConfig
Scope Scope
MinePeriod int
}
ManagerConfig tunes the live crystallization loop. Mine bounds detection; Scope tags written waggles; MinePeriod is how many observations between sweeps (default 8) so mining never runs on the hot path of every single tool call.
type MineConfig ¶
MineConfig bounds the search. MinLen/MaxLen cap route length; K is the minimum number of non-overlapping occurrences before a route is worth crystallizing.
type Param ¶
Param marks an argument position whose value varies across occurrences, so it becomes a parameter of the crystallized route rather than a literal.
type Recorder ¶
type Recorder struct {
// contains filtered or unexported fields
}
Recorder is a bounded per-session ring buffer of recent tool calls.
func NewRecorder ¶
NewRecorder returns a recorder holding at most capacity recent calls. A non-positive capacity defaults to 200.
type Replayer ¶
type Replayer struct {
// contains filtered or unexported fields
}
Replayer follows known routes. It watches the live read-only call stream and, when the most recent calls match the start of a stored route whose remaining steps are fully determined (no unbound params), runs those remaining steps deterministically off the model's path and returns their combined output to fold into the triggering tool result. Everything is read-only, so a wrong match wastes a little read work and never causes damage.
func NewReplayer ¶
NewReplayer builds a replayer over routes. minPrefix is the smallest number of matched leading steps before a route fires (clamped to >= 2) — the conservatism knob that stops one ubiquitous call from hijacking exploration.
func (*Replayer) Follow ¶
func (r *Replayer) Follow(ctx context.Context, exec func(context.Context, string) (string, error)) (string, bool)
Follow checks the current window for a fireable route and, if found, runs its remaining steps via exec (which must apply the host's safety + truncation). It returns the formatted block to append to the triggering tool result and true, or "" and false when nothing fires. Best-effort: an exec error or empty output yields no block. A given concrete plan fires at most once per session.
func (*Replayer) Routes ¶
Routes returns how many routes the replayer holds (0 for a nil/empty one).
type Route ¶
type Route struct {
Name string
Steps []Call
Params []Param
// Scope attributes a fired route to its store's ledger. Defaults to project.
Scope Scope
}
Route is a stored waggle rehydrated for predictive replay: the ordered steps (literal args carry values; param args are wildcards) plus which positions are params. Steps mirror the miner's Candidate so translation is shared.
func LoadRoutes ¶
LoadRoutes reads every replayable waggle in a store. A missing dir is not an error (returns nil). Files without a structured route block are skipped (they still work as exec-skills, just aren't replayed).
type Stat ¶
type Stat struct {
Uses int
Yield int
Fails int // recorded divergences (replay matched but its tail exec failed)
}
Stat is a waggle's aggregated reuse: how many times it was followed and the total estimated tokens saved.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a directory of waggle skill files for one scope. Project stores are keyed by a hash of the project root (the same scheme as the checkpoint store) so path-bearing routes never leak between projects; the user store is shared.
func ProjectStore ¶
ProjectStore returns the per-project waggle store, rooted at <beeHome>/waggle/proj/<hash>/skills.
func (*Store) IsDisabled ¶
IsDisabled reports whether the named waggle was demoted by curation. The on-demand lookup path uses this to refuse a retired route.
func (*Store) LedgerPath ¶
LedgerPath is the reuse-log path for this store, a sibling of the skills dir.