automation

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 22, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CronSchedule

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

CronSchedule fires according to a standard 5-field cron expression:

┌───────────── minute  (0–59)
│ ┌─────────── hour    (0–23)
│ │ ┌───────── dom     (1–31)
│ │ │ ┌─────── month   (1–12)
│ │ │ │ ┌───── weekday (0–6, 0=Sun)
│ │ │ │ │
* * * * *

Supports: *, N, N-M, */N, N,M,…, and combinations thereof.

func Cron

func Cron(expr string) (*CronSchedule, error)

Cron parses a 5-field cron expression. Returns an error on invalid syntax.

func MustCron

func MustCron(expr string) *CronSchedule

MustCron parses expr and panics on error.

func (*CronSchedule) Next

func (c *CronSchedule) Next(from time.Time) time.Time

func (*CronSchedule) String

func (c *CronSchedule) String() string

type DiscardSink

type DiscardSink struct{}

DiscardSink silently drops every result. Useful in tests.

func (DiscardSink) Write

func (DiscardSink) Write(_ context.Context, _ Result) error

type ExecuteConfig

type ExecuteConfig struct {
	// StreamFn receives each text delta in real time. May be nil.
	StreamFn func(string)
	// ModelOverride specifies a different model for this execution only.
	// Format: "provider:model". Empty means use RunnerConfig.Model.
	ModelOverride string
	// SystemPrompt replaces the entire Seshat default system prompt.
	// Empty means use the default.
	SystemPrompt string
}

ExecuteConfig holds per-execution overrides applied on top of RunnerConfig.

type ExecuteFunc

type ExecuteFunc func(ctx context.Context, w Workflow, opts Options) (Result, error)

ExecuteFunc is the core execution signature threaded through the middleware chain.

type ExecutionState

type ExecutionState struct {
	WorkflowName string    `json:"workflow_name"`
	LastRunAt    time.Time `json:"last_run_at"`
	NextRunAt    time.Time `json:"next_run_at,omitempty"`
	LastStatus   string    `json:"last_status"` // "success" | "error" | "running"
	LastError    string    `json:"last_error,omitempty"`
	RunCount     int64     `json:"run_count"`
	SuccessCount int64     `json:"success_count"`
	FailureCount int64     `json:"failure_count"`
	ConsecErrors int       `json:"consec_errors"`
}

ExecutionState tracks the persistent history of a workflow across runs.

type Executor

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

Executor orchestrates workflow execution: it combines the Runner with middleware, output sinks, and state management.

func NewExecutor

func NewExecutor(cfg ExecutorConfig) (*Executor, error)

NewExecutor builds an Executor from cfg. WithRecovery() is always prepended so panics never escape.

func (*Executor) Close

func (e *Executor) Close()

Close releases the underlying Runner and all its resources.

func (*Executor) Run

func (e *Executor) Run(ctx context.Context, w Workflow, opts Options) (Result, error)

Run executes w with opts, runs all middleware, feeds sinks, and updates state.

type ExecutorConfig

type ExecutorConfig struct {
	RunnerConfig RunnerConfig
	// Middleware is applied in order (first = outermost wrapper).
	Middleware []Middleware
	// Sinks receive the completed Result after each execution.
	Sinks []Sink
	// State persists execution history. May be nil (no persistence).
	State StateStore
}

ExecutorConfig configures the Executor.

type FileSink

type FileSink struct {
	// Dir is the directory where output files are written. Created if absent.
	Dir string
	// Format is "text" (default) or "json".
	Format string
}

FileSink writes the result to a file. The filename is derived from the workflow name and the run timestamp.

func (*FileSink) Write

func (s *FileSink) Write(ctx context.Context, r Result) error

type FileStateStore

type FileStateStore struct {
	Dir string
	// contains filtered or unexported fields
}

FileStateStore persists one JSON file per workflow in a directory. It is safe for use by a single process (no cross-process locking).

func NewFileStateStore

func NewFileStateStore(dir string) (*FileStateStore, error)

func (*FileStateStore) Delete

func (f *FileStateStore) Delete(_ context.Context, name string) error

func (*FileStateStore) List

func (*FileStateStore) Load

func (*FileStateStore) Save

type IntervalSchedule

type IntervalSchedule struct {
	Interval time.Duration
}

IntervalSchedule fires every fixed Interval starting from first use.

func Every

func Every(d time.Duration) *IntervalSchedule

func (*IntervalSchedule) Next

func (s *IntervalSchedule) Next(from time.Time) time.Time

func (*IntervalSchedule) String

func (s *IntervalSchedule) String() string

type MemoryStateStore

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

MemoryStateStore is an in-process store with no persistence. Suitable for testing or ephemeral single-run scenarios.

func NewMemoryStateStore

func NewMemoryStateStore() *MemoryStateStore

func (*MemoryStateStore) Delete

func (m *MemoryStateStore) Delete(_ context.Context, name string) error

func (*MemoryStateStore) List

func (*MemoryStateStore) Load

func (*MemoryStateStore) Save

type Middleware

type Middleware func(next ExecuteFunc) ExecuteFunc

Middleware wraps an ExecuteFunc to add cross-cutting behaviour. Middlewares are applied innermost-first: Chain(A, B, C) produces A(B(C(core))).

func Chain

func Chain(middlewares ...Middleware) Middleware

Chain composes a slice of middlewares into a single middleware. The first middleware is the outermost (runs first on entry, last on exit).

func WithLogging

func WithLogging(logger *log.Logger) Middleware

WithLogging logs workflow start, completion, and errors to logger. Pass nil to use the default log package.

func WithMetrics

func WithMetrics(onResult func(Result)) Middleware

WithMetrics calls onResult after every execution (success or failure). Use this to feed Prometheus counters, Datadog metrics, or custom logging.

func WithRecovery

func WithRecovery() Middleware

WithRecovery catches panics from the workflow, converts them to errors, and ensures the Result is always populated.

func WithRetry

func WithRetry(maxAttempts int, backoff time.Duration) Middleware

WithRetry retries a failed workflow up to maxAttempts additional times, waiting backoff (doubled each attempt) between attempts. Overrides opts.MaxRetries and opts.RetryBackoff when both are non-zero.

func WithTimeout

func WithTimeout(d time.Duration) Middleware

WithTimeout cancels the workflow if it exceeds d. Opts.Timeout takes precedence when non-zero.

type MultiSink

type MultiSink struct {
	Sinks []Sink
}

MultiSink fans a Result out to multiple sinks. All sinks are called even if one errors; errors are joined.

func NewMultiSink

func NewMultiSink(sinks ...Sink) *MultiSink

func (*MultiSink) Write

func (m *MultiSink) Write(ctx context.Context, r Result) error

type OnceSchedule

type OnceSchedule struct {
	At time.Time
}

OnceSchedule fires exactly once at At.

func Once

func Once(at time.Time) *OnceSchedule

func (*OnceSchedule) Next

func (s *OnceSchedule) Next(from time.Time) time.Time

func (*OnceSchedule) String

func (s *OnceSchedule) String() string

type Options

type Options struct {
	// Model overrides the Runner's default model for this execution only.
	// Format: "provider:model" (e.g. "anthropic:claude-sonnet-4-6").
	Model string

	// DryRun skips actual LLM execution and returns an empty Result.
	// Useful for validating scheduler configuration without incurring cost.
	DryRun bool

	// Timeout caps the total wall-clock time for the workflow.
	// Zero means no per-execution timeout (context deadline still applies).
	Timeout time.Duration

	// MaxRetries is the number of additional attempts after a failure.
	// Zero means no retry. Used by WithRetry middleware.
	MaxRetries int

	// RetryBackoff is the initial wait between retries (doubles each attempt).
	// Defaults to 5s when zero and MaxRetries > 0.
	RetryBackoff time.Duration

	// Extra holds workflow-specific key-value options that are not part of
	// the standard contract. Workflows may inspect this map for opt-in features.
	Extra map[string]any
}

Options configure a single workflow execution. Workflow-specific parameters (e.g. topics, target path) belong in the workflow struct itself; Options covers cross-cutting execution concerns.

func DefaultOptions

func DefaultOptions() Options

DefaultOptions returns sensible defaults for interactive or scheduled runs.

func (Options) Get

func (o Options) Get(key string) any

Get retrieves a value from Extra. Returns nil if the key is absent.

func (*Options) Set

func (o *Options) Set(key string, value any)

Set stores a key-value pair in Extra, initialising the map if needed.

func (Options) WithDryRun

func (o Options) WithDryRun() Options

WithDryRun returns a copy of o with DryRun enabled.

func (Options) WithModel

func (o Options) WithModel(model string) Options

WithModel returns a copy of o with the model overridden.

func (Options) WithRetry

func (o Options) WithRetry(maxRetries int, backoff time.Duration) Options

WithRetry returns a copy of o with retry configured.

func (Options) WithTimeout

func (o Options) WithTimeout(d time.Duration) Options

WithTimeout returns a copy of o with the timeout set.

type Registry

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

Registry is a thread-safe catalog of named workflows. Workflows are registered once at startup and looked up by name at runtime.

func NewRegistry

func NewRegistry() *Registry

NewRegistry returns an empty Registry.

func (*Registry) Get

func (r *Registry) Get(name string) (Workflow, bool)

Get returns the workflow registered under name, or (nil, false) if absent.

func (*Registry) Len

func (r *Registry) Len() int

Len returns the number of registered workflows.

func (*Registry) List

func (r *Registry) List() []Workflow

List returns all registered workflows sorted by name.

func (*Registry) MustRegister

func (r *Registry) MustRegister(w Workflow)

MustRegister calls Register and panics on error. Intended for package-level init blocks where duplicate registration is a programming error.

func (*Registry) Names

func (r *Registry) Names() []string

Names returns all registered workflow names sorted alphabetically.

func (*Registry) Register

func (r *Registry) Register(w Workflow) error

Register adds w to the registry. Returns an error if a workflow with the same name is already registered.

func (*Registry) Unregister

func (r *Registry) Unregister(name string)

Unregister removes w from the registry. No-op if the name is not present.

type Result

type Result struct {
	WorkflowName string
	StartedAt    time.Time
	FinishedAt   time.Time
	Duration     time.Duration
	Output       string // accumulated text streamed by the agent
	Error        error
	Metadata     map[string]any // arbitrary key-value pairs set by middleware or workflow
}

Result holds the complete outcome of a single workflow execution.

func (Result) Success

func (r Result) Success() bool

Success reports whether the workflow completed without error.

type Runner

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

Runner creates a fresh SDK client for each workflow execution. It holds no mutable state, making it safe for concurrent use.

func NewRunner

func NewRunner(cfg RunnerConfig) (*Runner, error)

NewRunner builds a Runner from cfg.

func (*Runner) Close

func (r *Runner) Close()

Close is a no-op — Runner holds no long-lived resources.

func (*Runner) Execute

func (r *Runner) Execute(ctx context.Context, w Workflow, ec ExecuteConfig) error

Execute runs w against a fresh SDK client and session. A new client is created for every call, which ensures ExecuteConfig overrides (model, system prompt) are fully isolated between executions.

type RunnerConfig

type RunnerConfig struct {
	Model          sdk.ModelIdentifier
	ProviderConfig *providers.Config
	MaxTokens      int
}

RunnerConfig is the base template used to build an SDK client for each workflow execution.

type Schedule

type Schedule interface {
	// Next returns the next time the schedule fires after from.
	// Returns the zero Time if the schedule never fires again.
	Next(from time.Time) time.Time
	// String returns a human-readable description of the schedule.
	String() string
}

Schedule computes the next trigger time after a given reference point.

type ScheduledRun

type ScheduledRun struct {
	WorkflowName string
	Schedule     string
	NextRun      time.Time
}

ScheduledRun is a read-only view of a single job's next execution.

type Scheduler

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

Scheduler runs registered workflows according to their schedules. It uses a single goroutine and a timer-based loop; it does not spawn a goroutine per job. Concurrent job execution is not supported by design — use multiple Schedulers if you need parallel pipelines.

func NewScheduler

func NewScheduler(executor *Executor) *Scheduler

NewScheduler creates a Scheduler backed by executor.

func (*Scheduler) Add

func (s *Scheduler) Add(w Workflow, schedule Schedule, opts Options) *Scheduler

Add registers a workflow with its schedule and options. Returns the Scheduler to allow method chaining.

func (*Scheduler) Next

func (s *Scheduler) Next() []ScheduledRun

Next returns a snapshot of the upcoming scheduled runs, sorted by time.

func (*Scheduler) Run

func (s *Scheduler) Run(ctx context.Context) error

Run blocks and runs scheduled jobs until ctx is cancelled. It ticks at most once per second to avoid busy-wait.

func (*Scheduler) RunNow

func (s *Scheduler) RunNow(ctx context.Context, name string, opts Options) (Result, error)

RunNow immediately executes the workflow registered under name, bypassing the schedule. Returns ErrNotFound if the name is not registered.

type Sink

type Sink interface {
	Write(ctx context.Context, r Result) error
}

Sink receives a completed Result after a workflow finishes. Sinks are called sequentially by the Executor; use MultiSink for fan-out.

type StateStore

type StateStore interface {
	Load(ctx context.Context, workflowName string) (*ExecutionState, error)
	Save(ctx context.Context, state ExecutionState) error
	List(ctx context.Context) ([]ExecutionState, error)
	Delete(ctx context.Context, workflowName string) error
}

StateStore persists and retrieves execution state across process restarts.

type StdoutSink

type StdoutSink struct {
	// Quiet suppresses the footer when true.
	Quiet bool
}

StdoutSink prints a human-readable summary of the result to stdout. The workflow's streaming output is already printed in real time via StreamFn; StdoutSink adds a completion footer (duration, status).

func (*StdoutSink) Write

func (s *StdoutSink) Write(_ context.Context, r Result) error

type SystemPrompter

type SystemPrompter interface {
	SystemPrompt() string
}

SystemPrompter is an optional interface a Workflow can implement to provide a fully custom system prompt that replaces the Seshat default. When satisfied, the Executor builds a dedicated SDK client for that execution.

type WebhookSink

type WebhookSink struct {
	URL     string
	Headers map[string]string
	// Timeout for the HTTP request. Defaults to 15s.
	Timeout time.Duration
	// contains filtered or unexported fields
}

WebhookSink sends the result as a JSON POST to a URL.

func NewWebhookSink

func NewWebhookSink(url string) *WebhookSink

func (*WebhookSink) Write

func (s *WebhookSink) Write(ctx context.Context, r Result) error

type Workflow

type Workflow interface {
	Name() string
	Description() string
	Run(ctx context.Context, session *sdk.Session) error
}

Workflow is the interface every automation workflow must implement.

Jump to

Keyboard shortcuts

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