branching

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: May 26, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BranchManager

type BranchManager struct {
	Branches     map[string]*ConversationBranch `json:"branches"`
	ActiveBranch string                         `json:"active_branch"`
	RootBranch   string                         `json:"root_branch"`
	// contains filtered or unexported fields
}

BranchManager manages conversation branches and switching between them.

func NewBranchManager

func NewBranchManager() *BranchManager

NewBranchManager creates a new BranchManager with a "main" root branch.

func (*BranchManager) Abandon

func (bm *BranchManager) Abandon(branchID string) error

Abandon marks a branch as abandoned.

func (*BranchManager) AddMessage

func (bm *BranchManager) AddMessage(role, content string, toolUse []string)

AddMessage appends a message to the currently active branch.

func (*BranchManager) BuildBranchContext

func (bm *BranchManager) BuildBranchContext() string

BuildBranchContext formats branch info suitable for inclusion in a system prompt.

func (*BranchManager) CompareBranches

func (bm *BranchManager) CompareBranches(branchA, branchB string) string

CompareBranches returns a diff-like comparison of two branches showing where they diverged and what each branch did differently.

func (*BranchManager) ExportBranch

func (bm *BranchManager) ExportBranch(branchID string) ([]byte, error)

ExportBranch serializes the specified branch as JSON.

func (*BranchManager) Fork

func (bm *BranchManager) Fork(name string, atMessage int) (*ConversationBranch, error)

Fork creates a new branch from the current active branch at the specified message index. Messages up to atMessage are copied into the new branch. The new branch becomes active.

func (*BranchManager) GetActiveMessages

func (bm *BranchManager) GetActiveMessages() []BranchMessage

GetActiveMessages returns messages from the currently active branch.

func (*BranchManager) GetBranches

func (bm *BranchManager) GetBranches() []*ConversationBranch

GetBranches returns all branches.

func (*BranchManager) ImportBranch

func (bm *BranchManager) ImportBranch(data []byte) (*ConversationBranch, error)

ImportBranch deserializes a branch from JSON and adds it to the manager. If a branch with the same ID already exists, a new ID is generated.

func (*BranchManager) Merge

func (bm *BranchManager) Merge(sourceBranchID string) error

Merge merges the source branch into the currently active branch. Messages after the fork point are appended to the active branch. The source branch is marked as "merged".

func (*BranchManager) Prune

func (bm *BranchManager) Prune(olderThan time.Duration)

Prune removes abandoned branches that are older than the specified duration.

func (*BranchManager) Switch

func (bm *BranchManager) Switch(branchID string) error

Switch changes the active branch to the specified branch ID.

type BranchMessage

type BranchMessage struct {
	Role      string    `json:"role"`
	Content   string    `json:"content"`
	ToolUse   []string  `json:"tool_use,omitempty"`
	Timestamp time.Time `json:"timestamp"`
}

BranchMessage represents a single message within a conversation branch.

type CascadeRouter

type CascadeRouter struct {
	Enabled      bool
	FrugalMode   bool   // more aggressive downgrading
	DefaultModel string // fallback when classification is inconclusive
	Roles        routing.ModelRoles
	// contains filtered or unexported fields
}

CascadeRouter selects the optimal model for each request based on task complexity. It uses pre-request classification (before we have a response) to route:

  • simple/chat tasks -> cheap model (haiku)
  • debug/review/refactor -> mid model (sonnet)
  • generation -> expensive model (opus)

The router also tracks routing decisions for analytics.

func NewCascadeRouter

func NewCascadeRouter(defaultModel string, roles routing.ModelRoles) *CascadeRouter

NewCascadeRouter creates a router with sensible defaults. The defaultModel is used as the fallback when classification yields no strong signal and no role-specific model is configured.

func (*CascadeRouter) DecisionCount

func (cr *CascadeRouter) DecisionCount() int

DecisionCount returns how many routing decisions have been recorded.

func (*CascadeRouter) Decisions

func (cr *CascadeRouter) Decisions() []RoutingDecision

Decisions returns a snapshot of all routing decisions made so far.

func (*CascadeRouter) Savings

func (cr *CascadeRouter) Savings() float64

Savings estimates the USD saved by routing decisions compared to always using the most expensive model. This is a rough heuristic: it sums the per-million-token price difference for each decision where the selected model is cheaper than the original.

func (*CascadeRouter) SelectModel

func (cr *CascadeRouter) SelectModel(prompt string, currentModel string, userOverride string) string

SelectModel picks the best model for a given prompt. If userOverride is non-empty the user's explicit choice always wins (override is never downgraded). The returned string is the model name to use for the API call.

func (*CascadeRouter) Summary

func (cr *CascadeRouter) Summary() string

Summary returns a human-readable summary of routing activity.

type ConversationBranch

type ConversationBranch struct {
	ID        string            `json:"id"`
	ParentID  string            `json:"parent_id"`
	Name      string            `json:"name"`
	ForkPoint int               `json:"fork_point"`
	Messages  []BranchMessage   `json:"messages"`
	CreatedAt time.Time         `json:"created_at"`
	Status    string            `json:"status"`
	Metadata  map[string]string `json:"metadata,omitempty"`
}

ConversationBranch represents a named branch in the conversation tree.

type ModelTier

type ModelTier int

ModelTier represents the cost tier of a model.

const (
	TierCheap     ModelTier = iota // haiku-class
	TierMid                        // sonnet-class
	TierExpensive                  // opus-class
)

type RoutingDecision

type RoutingDecision struct {
	OriginalModel string    `json:"original_model"`
	SelectedModel string    `json:"selected_model"`
	TaskType      string    `json:"task_type"`
	Reason        string    `json:"reason"`
	Timestamp     time.Time `json:"timestamp"`
}

RoutingDecision records a single model selection event.

type ShadowWorkspace

type ShadowWorkspace struct {
	// contains filtered or unexported fields
}

ShadowWorkspace provides a temporary directory where file edits can be validated (e.g. via `go vet`, `tsc`, `pylint`) without touching the original source tree.

func NewShadowWorkspace

func NewShadowWorkspace() (*ShadowWorkspace, error)

NewShadowWorkspace creates a new temporary directory for shadow validation.

func (*ShadowWorkspace) Close

func (sw *ShadowWorkspace) Close()

Close removes the shadow workspace temp directory and all its contents.

func (*ShadowWorkspace) TempDir

func (sw *ShadowWorkspace) TempDir() string

TempDir returns the path to the shadow workspace temp directory.

func (*ShadowWorkspace) ValidateEdit

func (sw *ShadowWorkspace) ValidateEdit(originalPath, newContent string) []ValidationError

ValidateEdit copies a file into the shadow workspace, writes newContent to the copy, runs the language-appropriate validation tool, and returns any errors found. The temp copy is cleaned up before returning.

func (*ShadowWorkspace) ValidateMultipleEdits

func (sw *ShadowWorkspace) ValidateMultipleEdits(edits map[string]string) map[string][]ValidationError

ValidateMultipleEdits validates several files at once and returns a map of file path to validation errors.

type SnowballDetector

type SnowballDetector struct {
	// contains filtered or unexported fields
}

SnowballDetector detects when token consumption is growing faster than progress, signalling that the agent is stuck in a snowball pattern where each turn consumes more tokens without proportional progress.

func NewSnowballDetector

func NewSnowballDetector(maxTokens int) *SnowballDetector

NewSnowballDetector creates a detector with the given absolute token ceiling. The default growth threshold is 2.0x (last 3 turns vs first 3 turns).

func (*SnowballDetector) IsSnowballing

func (sd *SnowballDetector) IsSnowballing() bool

IsSnowballing returns true if the last 3 turns consumed 2x+ tokens compared to the first 3 turns AND progress per token is declining.

func (*SnowballDetector) RecordTurn

func (sd *SnowballDetector) RecordTurn(tokens int, progress float64)

RecordTurn records token usage and estimated progress for a single turn. Progress should be in the range [0, 1].

func (*SnowballDetector) Reset

func (sd *SnowballDetector) Reset()

Reset clears all recorded data.

func (*SnowballDetector) ShouldAbort

func (sd *SnowballDetector) ShouldAbort() bool

ShouldAbort returns true if total tokens exceed maxTokens or the growth rate exceeds 3x between the first and last 3-turn windows.

func (*SnowballDetector) String

func (sd *SnowballDetector) String() string

String implements the Stringer interface for SnowballDetector.

func (*SnowballDetector) Summary

func (sd *SnowballDetector) Summary() string

Summary returns a human-readable summary of the snowball state.

type ValidationError

type ValidationError struct {
	File    string
	Line    int
	Column  int
	Message string
}

ValidationError represents a single validation issue.

Jump to

Keyboard shortcuts

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