Documentation
¶
Overview ¶
Package builder implements the agent build and upgrade pipeline.
Index ¶
- Variables
- func CommitAndPush(workDir, message string) (string, error)
- func CommitScaffold(repoPath, agentID string, data scaffold.ScaffoldData) (string, error)
- func CreateBranch(repoPath, branch string) error
- func CreateUpgradeBranch(repoPath, agentID, runID string) error
- func InitMonorepo(path string) error
- func MergeBranch(repoPath, branch string) error
- func RemoveAgentCode(repoPath, agentID string) error
- func SparseCheckout(repoPath, branch, agentID, targetDir string) error
- type BuildInput
- type BuildService
- func (b *BuildService) AcquireUpgradeLock(ctx context.Context, agentID string) error
- func (b *BuildService) Build(_ context.Context, input BuildInput) error
- func (b *BuildService) CancelBuild(agentID string) bool
- func (b *BuildService) CancelBuildAndWait(agentID string, timeout time.Duration) bool
- func (b *BuildService) MonorepoPath() string
- func (b *BuildService) RecoverStuckOperations(ctx context.Context) error
- func (b *BuildService) RunUpgrade(_ context.Context, input UpgradeInput)
- func (b *BuildService) SetEventPublisher(ep EventPublisher)
- func (b *BuildService) SetUpgradeNotifier(n PostUpgradeNotifier)
- func (b *BuildService) WarmBuildCache(ctx context.Context)
- func (b *BuildService) WarmRuntimeCaches(ctx context.Context)
- type BuilderPromptData
- type EventPublisher
- type LibsPaths
- type PostUpgradeNotifier
- type UpgradeInput
Constants ¶
This section is empty.
Variables ¶
var ErrUpgradeInProgress = errors.New("upgrade already in progress")
ErrUpgradeInProgress is returned when an upgrade is already running for the agent.
Functions ¶
func CommitAndPush ¶
CommitAndPush commits all changes on the current branch in workDir, pushes to origin. Returns commit hash.
func CommitScaffold ¶
func CommitScaffold(repoPath, agentID string, data scaffold.ScaffoldData) (string, error)
CommitScaffold creates branch build/{agentID}/init, materializes scaffold, commits. Returns the commit hash. Safe to call on retry — deletes a stale branch if it exists.
func CreateBranch ¶
CreateBranch creates a new branch from main/master.
func CreateUpgradeBranch ¶
CreateUpgradeBranch creates branch upgrade/{agentID}/{runID} from main. Uses `-B` (create-or-reset) so retries don't fail on a leftover branch from a prior failed attempt — Fix-this-error reuses the failed run's id as the branch suffix, and successful upgrades currently never delete the branch after merging, so collisions are easy to hit. Whatever was on the old branch was from a failed run and not worth keeping.
func InitMonorepo ¶
InitMonorepo initializes a bare git repo at path if it doesn't exist.
func MergeBranch ¶
MergeBranch fast-forward merges branch into main, rebasing the branch onto current main first if a parallel build advanced main while this branch's work was running. Cross-agent rebases never conflict (each agent lives under its own agents/<id>/), and the per-agent build lock prevents same-agent races, so the rebase is safe in practice.
func RemoveAgentCode ¶
RemoveAgentCode deletes the agent directory from the monorepo and commits.
func SparseCheckout ¶
SparseCheckout clones the repo into targetDir with only agents/{agentID}/ checked out.
Types ¶
type BuildInput ¶
type BuildInput struct {
AgentID string
Name string
Slug string
UserID string
BuildModel string // stored on agent for future upgrades
Instructions string // optional: when non-empty, run Sol code generation after scaffold
}
BuildInput describes what to build.
type BuildService ¶
type BuildService struct {
// contains filtered or unexported fields
}
BuildService orchestrates the agent build and upgrade pipeline.
func New ¶
func New(cfg *config.Config, database *db.DB, containers container.ContainerManager, encryptor *crypto.Encryptor, logger *zap.Logger) *BuildService
New creates a BuildService. Panics if any dependency is nil.
func (*BuildService) AcquireUpgradeLock ¶
func (b *BuildService) AcquireUpgradeLock(ctx context.Context, agentID string) error
Upgrade runs the upgrade pipeline for an existing agent. This is synchronous — caller should run in a goroutine if needed. AcquireUpgradeLock atomically checks that no upgrade is running for the agent and sets upgrade_status to "building". Returns ErrUpgradeInProgress if an upgrade is already active. Call RunUpgrade after a successful lock.
func (*BuildService) Build ¶
func (b *BuildService) Build(_ context.Context, input BuildInput) error
Build runs the full build pipeline: scaffold → Sol code gen → compile → containerize → deploy. This is synchronous — caller should run in a goroutine if needed. If input.AgentID is set, uses the existing agent record (created by the API handler for async 202 responses). If empty, creates a new agent record.
func (*BuildService) CancelBuild ¶
func (b *BuildService) CancelBuild(agentID string) bool
CancelBuild cancels a running build/upgrade for the given agent. Returns true if a build was running and cancelled. Does not block on teardown — use CancelBuildAndWait when the caller needs the toolserver and DB writes to settle before proceeding.
func (*BuildService) CancelBuildAndWait ¶ added in v0.2.8
func (b *BuildService) CancelBuildAndWait(agentID string, timeout time.Duration) bool
CancelBuildAndWait cancels a running build/upgrade and blocks until the goroutine has run its deferred cleanup (toolserver SIGKILL, DB status write) or until timeout elapses. Returns true if a build was running. Used by Delete to avoid racing the workspace rm and agent-row delete against the upgrade's in-flight writes.
func (*BuildService) MonorepoPath ¶
func (b *BuildService) MonorepoPath() string
MonorepoPath returns the agent monorepo path.
func (*BuildService) RecoverStuckOperations ¶
func (b *BuildService) RecoverStuckOperations(ctx context.Context) error
RecoverStuckOperations resets any builds or upgrades left in progress after an unclean shutdown. Should be called on startup.
func (*BuildService) RunUpgrade ¶
func (b *BuildService) RunUpgrade(_ context.Context, input UpgradeInput)
RunUpgrade executes the upgrade pipeline for an agent that already has its upgrade_status set to "building" via AcquireUpgradeLock.
func (*BuildService) SetEventPublisher ¶
func (b *BuildService) SetEventPublisher(ep EventPublisher)
SetEventPublisher sets the event publisher for build/upgrade lifecycle events.
func (*BuildService) SetUpgradeNotifier ¶
func (b *BuildService) SetUpgradeNotifier(n PostUpgradeNotifier)
SetUpgradeNotifier sets the notifier called after successful upgrades to notify the originating conversation.
func (*BuildService) WarmBuildCache ¶
func (b *BuildService) WarmBuildCache(ctx context.Context)
WarmBuildCache pre-downloads Go module dependencies so that the first real agent build hits a warm cache. Materializes a real scaffold and runs a full docker build (same Dockerfile.tmpl + go.mod.tmpl as real builds), then removes the throwaway image. The cache mounts persist.
func (*BuildService) WarmRuntimeCaches ¶
func (b *BuildService) WarmRuntimeCaches(ctx context.Context)
WarmRuntimeCaches seeds the named volumes that the build-prompt loop's direct `go mod tidy` / `go build` invocations consume — distinct from the BuildKit cache mount that WarmBuildCache populates. The agent-builder container at runtime sets GOMODCACHE=/tmp/go-mod and GOCACHE=/tmp/go-cache (see container/docker.go) backed by the airlock-go-mod-cache and airlock-go-build-cache Docker named volumes. Without this seed, the first build-prompt iteration pays full download cost for ~25 modules in agentsdk+sol's transitive dep tree. The volumes persist across airlock restarts.
type BuilderPromptData ¶
type BuilderPromptData struct {
HasWebSearch bool
}
BuilderPromptData holds template data for the builder system prompt.
type EventPublisher ¶
type EventPublisher interface {
PublishBuildEvent(ctx context.Context, agentID, buildID uuid.UUID, status, errMsg string)
PublishBuildLogLine(ctx context.Context, agentID, buildID uuid.UUID, seq int64, stream, line string)
}
EventPublisher publishes build/upgrade lifecycle events. Implemented by realtime.PubSub via an adapter.
type LibsPaths ¶
type LibsPaths struct {
// Owned is the directory containing agentsdk/goai/sol. Either the
// operator's AGENT_LIBS_PATH (live dev source) or the extracted cache.
Owned string
// Ext is the directory containing goose/templ. Always the extracted
// cache (devs don't edit these).
Ext string
}
LibsPaths is what callers need to wire up the per-agent docker build's two BuildKit contexts (libs-owned + libs-ext) and the toolserver's bind-mount overlay (Owned).
func EnsureLibs ¶
func EnsureLibs(ctx context.Context, image, explicitPath, cacheDir string, logger *zap.Logger) (LibsPaths, error)
EnsureLibs guarantees that:
- The agent-builder image's full /libs/* set is materialized on the host under <cacheDir>/<image-id>/, cached by image ID so a tag bump triggers re-extraction.
- If explicitPath (AGENT_LIBS_PATH) is set, the owned subdirs all exist there. Owned then points at explicitPath; Ext at the cache.
- If explicitPath is empty (prod), both Owned and Ext point at the cache.
type PostUpgradeNotifier ¶
type PostUpgradeNotifier interface {
NotifyUpgradeComplete(ctx context.Context, agentID uuid.UUID, conversationID, status, message string) error
}
PostUpgradeNotifier is called after an upgrade finishes (success or failure) to post a single message into the originating conversation.
status is "success" or "error". message is the human-readable text to surface — typically sourced from the agent-builder's exit tool on success, or the underlying failure reason on error. The notifier posts exactly ONE message and does not trigger a follow-up LLM turn — the agent's own exit-tool summary already describes the outcome, so re-prompting just produces redundant text.
type UpgradeInput ¶
type UpgradeInput struct {
AgentID string
RunID string // the run that triggered the upgrade
Reason string // "llm_request", "auto_fix", "manual"
Description string // what to change
ConversationID string // conversation that triggered the upgrade (for post-upgrade reply)
ErrorMessage string // from failed run (auto_fix)
PanicTrace string // from failed run (auto_fix)
InputPayload string // JSON of failed run input (auto_fix)
Actions string // JSON of recorded actions before failure (auto_fix)
Messages string // conversation messages from the failed run
}
UpgradeInput describes an upgrade request.