jobs

package
v0.31.0 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package jobs runs and tracks detached background agent sessions. A job is a child `memcode` process whose output streams to a log file under .memcode/jobs/<id>/; its metadata (task, pid, status) lives beside the log. Background agents are writers, so they coordinate through a single repo-wide writer lock — the "one serialized writer" half of memcode's concurrency model: any number of read-only explorers may run at once, but mutating jobs run one at a time, queueing on the lock rather than clobbering each other's edits.

Index

Constants

View Source
const (
	StatusRunning = "running"
	StatusWaiting = "waiting"
	StatusDone    = "done"
	StatusFailed  = "failed"
	StatusStopped = "stopped" // process gone but never recorded a finish
)

Status values for a job.

Variables

This section is empty.

Functions

func AcquireWriter

func AcquireWriter(ctx context.Context, root string) (release func(), err error)

AcquireWriter blocks until this process holds the repo-wide writer lock, then returns a release func. It coordinates background writer jobs so only one mutates the tree at a time; a stale lock (owner process gone) is reclaimed. ctx cancellation aborts the wait.

func Finish

func Finish(root, id string, exitCode int, result string) error

Finish records a job's terminal status (called by the child when it exits). result is the agent's final text, persisted so a report-back job can feed it to the calling LLM.

func Heartbeat added in v0.27.0

func Heartbeat(root, id, activity string, tokensIn, tokensOut int64) error

Heartbeat updates a RUNNING job's live activity/token readout. It re-reads the meta immediately before writing and refuses to touch a job that is no longer running, so it can never resurrect (or clobber) a terminal record — if Finish or Stop landed first, their status/result win and the heartbeat is dropped. The child stops heartbeating before it calls Finish, so within the child process the two never interleave.

func LogPath

func LogPath(root, id string) string

LogPath returns the path to a job's log file.

func Stop

func Stop(root, id string) error

Stop terminates a running job: signals its process (SIGTERM, then SIGKILL if it doesn't exit), and records the job as stopped. Returns an error if the job isn't found or isn't running. This is the safety valve for a runaway detached agent — the TUI/CLI equivalent of /kill for in-session shells.

Types

type ExecutionBudgets added in v0.28.0

type ExecutionBudgets struct {
	MaxSeconds         int `json:"max_seconds,omitempty"`
	MaxToolCalls       int `json:"max_tool_calls,omitempty"`
	MaxDelegationDepth int `json:"max_delegation_depth,omitempty"`
}

type Job

type Job struct {
	ID         string `json:"id"`
	Task       string `json:"task"`
	Mode       string `json:"mode"`
	ReportBack bool   `json:"report_back,omitempty"` // true → on finish, feed Result back to the calling LLM (agent{background}), not just the user
	Result     string `json:"result,omitempty"`      // the agent's final text (set by Finish) — what gets reported back
	PID        int    `json:"pid"`
	// StartSig is the child process's start-time signature captured at spawn (ps lstart on
	// unix; "" where unavailable). PIDs recycle, so before reporting a job as running — and
	// especially before SIGNALING its pid — the live process's signature must match: a
	// mismatch means the pid now belongs to an unrelated process. Additive field; old metas
	// without it keep the plain liveness check.
	StartSig   string    `json:"start_sig,omitempty"`
	Status     string    `json:"status"`
	ExitCode   int       `json:"exit_code"`
	StartedAt  time.Time `json:"started_at"`
	FinishedAt time.Time `json:"finished_at,omitempty"`
	// Live readout, heartbeated by the running child (~1s) so frontends can show
	// what a detached agent is doing right now. Additive; absent in old metas.
	Activity          string          `json:"activity,omitempty"`   // latest tool label, e.g. "bash(go test ./...)"
	TokensIn          int64           `json:"tokens_in,omitempty"`  // child session input tokens so far
	TokensOut         int64           `json:"tokens_out,omitempty"` // child session output tokens so far
	HeartbeatAt       time.Time       `json:"heartbeat_at,omitempty"`
	AgentID           string          `json:"agent_id,omitempty"`
	ObjectiveID       string          `json:"objective_id,omitempty"`
	SubgoalID         string          `json:"subgoal_id,omitempty"`
	RunID             string          `json:"run_id,omitempty"`
	ParentRunID       string          `json:"parent_run_id,omitempty"`
	SessionID         string          `json:"session_id,omitempty"`
	PolicyHash        string          `json:"policy_hash,omitempty"`
	ExecutionEnvelope json.RawMessage `json:"execution_envelope,omitempty"`
}

func Get

func Get(root, id string) (Job, error)

Get returns one job with live status reconciled.

func List

func List(root string) ([]Job, error)

List returns all jobs, newest first, with live status reconciled (a job recorded as running whose process is gone is reported as stopped).

func Spawn

func Spawn(root, task, mode string, chrome, reportBack bool, session string) (Job, error)

Spawn launches a detached `memcode run <task>` child, redirecting its output to the job log, and records the job as running. The child is invoked with --job <id> so it acquires the writer lock and records its own completion. When chrome is true, --chrome is forwarded so backgrounded browser jobs keep the capability (Chrome always launches with a visible window).

func SpawnWithSpec added in v0.28.0

func SpawnWithSpec(spec SpawnSpec) (Job, error)

type ResourceGrant added in v0.28.0

type ResourceGrant struct {
	IDs []string `json:"ids,omitempty"`
}

type SpawnSpec added in v0.28.0

type SpawnSpec struct {
	Root, Task, Mode, SessionID, AgentID, ObjectiveID, SubgoalID, RunID, ParentRunID, PolicyHash, BrowserMode string
	ToolPolicy                                                                                                ToolPolicy
	ResourceGrant                                                                                             ResourceGrant
	Budgets                                                                                                   ExecutionBudgets
	ReportBack                                                                                                bool
}

type ToolPolicy added in v0.28.0

type ToolPolicy struct {
	Allowed  []string `json:"allowed,omitempty"`
	Disabled []string `json:"disabled,omitempty"`
}

Job is one background agent session.

Jump to

Keyboard shortcuts

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