Documentation
¶
Overview ¶
Package headless holds the platforms that run without an interactive terminal: platform/worker for one-shot batches and platform/timer for in-process schedules. Neither ever reads stdin, which is what makes them safe under systemd, cron, containers, and anywhere stdin is /dev/null.
Index ¶
- Constants
- func NewTimer(cfg TimerConfig) (agentkit.Platform, error)
- func NewWorker(cfg WorkerConfig, deps WorkerDeps) (agentkit.Platform, error)
- type TaskSpec
- type Timer
- func (t *Timer) PermissionCapability() permission.Capability
- func (t *Timer) PlatformID() string
- func (t *Timer) Receive(ctx context.Context) (agentkit.MessageEvent, error)
- func (t *Timer) Send(_ context.Context, event agentkit.OutboundEvent) error
- func (t *Timer) SetClockForTest(now func() time.Time, sleep func(context.Context, time.Duration) error)
- type TimerConfig
- type Worker
- type WorkerConfig
- type WorkerDeps
Constants ¶
const ( OutputText = "text" OutputJSON = "json" )
Output modes.
const ( // SessionFresh gives every task or tick its own session. This is the default // because the alternative fails slowly: a periodic job pinned to one session // grows its context every tick until it hits the model's window. SessionFresh = "fresh" // SessionFixed reuses one session id so the agent remembers across runs. // Pair it with compaction, or the context grows without bound. SessionFixed = "fixed" )
Session id modes shared by worker and timer.
Variables ¶
This section is empty.
Functions ¶
func NewTimer ¶
func NewTimer(cfg TimerConfig) (agentkit.Platform, error)
NewTimer registers platform/timer: Fire the same prompt on a fixed interval.
Best practices:
- Ticks are anchored to the start time and missed ones are skipped, so a slow turn does not make the schedule drift.
- Use platform/worker with a cron expression when you need calendar times rather than an interval.
func NewWorker ¶
func NewWorker(cfg WorkerConfig, deps WorkerDeps) (agentkit.Platform, error)
NewWorker registers platform/worker: Headless one-shot task runner for prompts or shell scripts.
Best practices:
- The worker exits at EOF after its task list; calendar cron belongs in schedule/cron.
- Script tasks need workspace and shell deps, checked at startup rather than silently skipped.
Types ¶
type TaskSpec ¶
type TaskSpec struct {
Prompt string `json:"prompt"`
// Script is a workspace-relative path to a bash script executed directly.
Script string `json:"script,omitempty"`
// Cron is rejected: use schedule/cron with the same registry instead.
Cron string `json:"cron,omitempty"`
// ID names the task in logs. Defaults to task-<n>.
ID string `json:"id,omitempty"`
// Note is free-form context stored with the job.
Note string `json:"note,omitempty"`
}
TaskSpec is one worker task. In YAML it may be written either as a bare string (run once at startup) or as an object with prompt or script.
Each task uses exactly one mode:
- prompt: send text to the agent as a turn
- script: run a workspace-relative bash script without an agent turn
Calendar cron belongs in schedule/cron, not here.
func (*TaskSpec) UnmarshalJSON ¶
UnmarshalJSON accepts a bare string so `tasks: ["do a thing"]` keeps working alongside `tasks: [{prompt: "..."}]`.
type Timer ¶
type Timer struct {
// contains filtered or unexported fields
}
Timer turns the process into a daemon that wakes on a fixed interval. Ticks are anchored to the start time rather than to the end of the previous turn, so a slow turn does not make the schedule drift; missed boundaries are skipped rather than queued, because a backlog of stale ticks is never what a schedule meant.
func (*Timer) PermissionCapability ¶
func (t *Timer) PermissionCapability() permission.Capability
func (*Timer) PlatformID ¶ added in v0.1.1
type TimerConfig ¶
type TimerConfig struct {
// EverySeconds is the tick interval. Required.
EverySeconds int `json:"everySeconds"`
// Prompt is the task text sent on every tick. Required.
Prompt string `json:"prompt"`
// Immediate fires the first tick at startup instead of waiting a full
// interval. Defaults to true, so a restart does useful work right away.
Immediate *bool `json:"immediate"`
// MaxRuns bounds the number of ticks; 0 means run until shutdown.
MaxRuns int `json:"maxRuns"`
// SessionMode is fresh (default) or fixed.
SessionMode string `json:"sessionMode"`
// SessionID is the id used in fixed mode, and the prefix in fresh mode.
SessionID string `json:"sessionId"`
// Output is text (default) or json, one event object per line.
Output string `json:"output"`
// Stream echoes assistant deltas as they arrive.
Stream bool `json:"stream"`
}
type Worker ¶
type Worker struct {
// contains filtered or unexported fields
}
Worker runs a batch of one-shot tasks and then reports EOF. It never reads stdin, so it is safe under systemd, cron, and CI.
func (*Worker) PermissionCapability ¶
func (w *Worker) PermissionCapability() permission.Capability
func (*Worker) PlatformID ¶ added in v0.1.1
type WorkerConfig ¶
type WorkerConfig struct {
// Tasks each run as one turn at startup, in order. Positional command-line
// arguments override this list.
Tasks []TaskSpec `json:"tasks"`
// Prompt is the single-task shorthand, used when Tasks is empty.
Prompt string `json:"prompt"`
// SessionMode is fresh (default) or fixed.
SessionMode string `json:"sessionMode"`
// SessionID is the id used in fixed mode, and the prefix in fresh mode.
SessionID string `json:"sessionId"`
// Output is text (default) or json, one event object per line.
Output string `json:"output"`
// Stream echoes assistant deltas as they arrive. Off by default: an
// unattended run wants the result, not the typing.
Stream bool `json:"stream"`
}