Documentation
¶
Index ¶
- type AgentConfig
- type CronSchedule
- type DBJobStore
- func (s *DBJobStore) CreateJob(ctx context.Context, job *Job) error
- func (s *DBJobStore) CreateRun(ctx context.Context, run *JobRun) error
- func (s *DBJobStore) DeleteJob(ctx context.Context, id, ownerID string) error
- func (s *DBJobStore) GetJob(ctx context.Context, id string) (*Job, error)
- func (s *DBJobStore) GetRun(ctx context.Context, id string) (*JobRun, error)
- func (s *DBJobStore) ListJobs(ctx context.Context, ownerID string) ([]*Job, error)
- func (s *DBJobStore) ListRuns(ctx context.Context, jobID string, limit int) ([]*JobRun, error)
- func (s *DBJobStore) UpdateJob(ctx context.Context, job *Job) error
- func (s *DBJobStore) UpdateRun(ctx context.Context, run *JobRun) error
- type DiscardSink
- type ExecuteConfig
- type ExecuteFunc
- type ExecutionState
- type Executor
- type ExecutorConfig
- type FileSink
- type FileStateStore
- func (f *FileStateStore) Delete(_ context.Context, name string) error
- func (f *FileStateStore) List(_ context.Context) ([]ExecutionState, error)
- func (f *FileStateStore) Load(_ context.Context, name string) (*ExecutionState, error)
- func (f *FileStateStore) Save(_ context.Context, s ExecutionState) error
- type IntervalSchedule
- type Job
- type JobRun
- type JobScheduler
- func (s *JobScheduler) AddJob(ctx context.Context, job *Job) error
- func (s *JobScheduler) GetJob(ctx context.Context, id string) (*Job, error)
- func (s *JobScheduler) GetRun(ctx context.Context, id string) (*JobRun, error)
- func (s *JobScheduler) ListJobs(ctx context.Context, ownerID string) ([]*Job, error)
- func (s *JobScheduler) ListRuns(ctx context.Context, jobID string, limit int) ([]*JobRun, error)
- func (s *JobScheduler) PauseJob(ctx context.Context, id string) error
- func (s *JobScheduler) RemoveJob(ctx context.Context, id, ownerID string) error
- func (s *JobScheduler) ResumeJob(ctx context.Context, id string) error
- func (s *JobScheduler) Run(ctx context.Context) error
- func (s *JobScheduler) RunNow(ctx context.Context, id string) (*JobRun, error)
- func (s *JobScheduler) SetLogger(l *log.Logger)
- func (s *JobScheduler) SetRunnerResolver(resolver RunnerResolver)
- func (s *JobScheduler) UpdateJob(ctx context.Context, job *Job) error
- type JobStatus
- type JobStore
- type MemoryStateStore
- func (m *MemoryStateStore) Delete(_ context.Context, name string) error
- func (m *MemoryStateStore) List(_ context.Context) ([]ExecutionState, error)
- func (m *MemoryStateStore) Load(_ context.Context, name string) (*ExecutionState, error)
- func (m *MemoryStateStore) Save(_ context.Context, s ExecutionState) error
- type Middleware
- type MultiSink
- type OnceSchedule
- type Options
- type Registry
- type Result
- type RunStatus
- type Runner
- type RunnerConfig
- type RunnerResolver
- type Schedule
- type ScheduledRun
- type Scheduler
- type Sink
- type StateStore
- type StdoutSink
- type SystemPrompter
- type Trigger
- type TriggerType
- type WebhookSink
- type Workflow
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AgentConfig ¶
type AgentConfig struct {
// Slug references a named agent definition in seshat-ai (e.g. "accounting-agent").
// When set, the daemon fetches the agent's model, tools, system_prompt, and
// max_turns from seshat-ai and merges them with any inline overrides below.
Slug string
// BaseType is the built-in agent type to use as a starting point.
// Empty defaults to "general-purpose".
BaseType string
// Tools is the list of tool name patterns the agent is allowed to use
// (e.g. "read", "web_search", "bash"). Empty = all tools (or inherits from agent).
Tools []string
// Skills is the list of skill names to load for this agent.
Skills []string
// Model overrides the agent/server default (format "provider:model").
Model string
// MaxTurns caps autonomous execution. 0 = inherit from agent or single turn.
MaxTurns int
// SystemPrompt overrides the default system prompt when non-empty.
SystemPrompt string
}
AgentConfig defines the agent that executes a job. When Slug is set the daemon resolves the full agent definition from seshat-ai and uses it as the base configuration; all other fields act as overrides.
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 (*CronSchedule) String ¶
func (c *CronSchedule) String() string
type DBJobStore ¶
type DBJobStore struct {
// contains filtered or unexported fields
}
DBJobStore implements JobStore backed by a seshat DB instance.
func NewDBJobStore ¶
func NewDBJobStore(database *db.DB) *DBJobStore
NewDBJobStore wraps a DB instance as a JobStore.
func (*DBJobStore) CreateRun ¶
func (s *DBJobStore) CreateRun(ctx context.Context, run *JobRun) error
func (*DBJobStore) DeleteJob ¶
func (s *DBJobStore) DeleteJob(ctx context.Context, id, ownerID string) error
type DiscardSink ¶
type DiscardSink struct{}
DiscardSink silently drops every result. Useful in tests.
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 ¶
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.
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.
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 (f *FileStateStore) List(_ context.Context) ([]ExecutionState, error)
func (*FileStateStore) Load ¶
func (f *FileStateStore) Load(_ context.Context, name string) (*ExecutionState, error)
func (*FileStateStore) Save ¶
func (f *FileStateStore) Save(_ context.Context, s ExecutionState) error
type IntervalSchedule ¶
IntervalSchedule fires every fixed Interval starting from first use.
func Every ¶
func Every(d time.Duration) *IntervalSchedule
func (*IntervalSchedule) String ¶
func (s *IntervalSchedule) String() string
type Job ¶
type Job struct {
ID string
OwnerID string // user ID from the calling app — empty means unowned (system job)
Name string
Description string
Trigger Trigger
Agent AgentConfig
Task string
Status JobStatus
LastRunAt *time.Time
NextRunAt *time.Time
LastRunStatus string // "success" | "error" | ""
CreatedAt time.Time
UpdatedAt time.Time
}
Job is a persisted automation task: trigger + agent config + task description.
type JobRun ¶
type JobRun struct {
ID string
JobID string
StartedAt time.Time
EndedAt *time.Time
Status RunStatus
Output string
Error string
}
JobRun records a single execution of a Job.
type JobScheduler ¶
type JobScheduler struct {
// contains filtered or unexported fields
}
JobScheduler manages the lifecycle of persisted automation jobs. It ticks every 10 seconds, checks due jobs, and fires them as goroutines. All job state is persisted via JobStore so the scheduler survives restarts.
func NewJobScheduler ¶
func NewJobScheduler(store JobStore, runner *Runner) *JobScheduler
NewJobScheduler builds a JobScheduler backed by store and runner.
func (*JobScheduler) AddJob ¶
func (s *JobScheduler) AddJob(ctx context.Context, job *Job) error
AddJob persists a new job and computes its initial NextRunAt.
func (*JobScheduler) ListJobs ¶
ListJobs returns jobs for ownerID; "" returns all (admin/scheduler use).
func (*JobScheduler) PauseJob ¶
func (s *JobScheduler) PauseJob(ctx context.Context, id string) error
PauseJob marks a job as paused so the scheduler skips it.
func (*JobScheduler) RemoveJob ¶
func (s *JobScheduler) RemoveJob(ctx context.Context, id, ownerID string) error
RemoveJob deletes a job and cancels any in-flight execution. ownerID="" bypasses ownership check (admin/system use).
func (*JobScheduler) ResumeJob ¶
func (s *JobScheduler) ResumeJob(ctx context.Context, id string) error
ResumeJob re-activates a paused job and recomputes its next run time.
func (*JobScheduler) Run ¶
func (s *JobScheduler) Run(ctx context.Context) error
Run blocks and ticks the scheduler until ctx is cancelled.
func (*JobScheduler) RunNow ¶
RunNow immediately fires a job outside of its schedule. Returns the JobRun created for this execution.
func (*JobScheduler) SetLogger ¶
func (s *JobScheduler) SetLogger(l *log.Logger)
SetLogger replaces the default logger.
func (*JobScheduler) SetRunnerResolver ¶
func (s *JobScheduler) SetRunnerResolver(resolver RunnerResolver)
SetRunnerResolver installs a dynamic runner resolver that fetches per-user LLM credentials at execution time. When set, it overrides the static runner.
type JobStore ¶
type JobStore interface {
CreateJob(ctx context.Context, job *Job) error
// GetJob returns a job by ID regardless of owner (for internal scheduler use).
GetJob(ctx context.Context, id string) (*Job, error)
// ListJobs returns all jobs for ownerID; pass "" to list all (scheduler/admin).
ListJobs(ctx context.Context, ownerID string) ([]*Job, error)
UpdateJob(ctx context.Context, job *Job) error
// DeleteJob deletes a job by ID; ownerID="" bypasses ownership check (admin).
DeleteJob(ctx context.Context, id, ownerID string) error
CreateRun(ctx context.Context, run *JobRun) error
UpdateRun(ctx context.Context, run *JobRun) error
ListRuns(ctx context.Context, jobID string, limit int) ([]*JobRun, error)
GetRun(ctx context.Context, id string) (*JobRun, error)
}
JobStore is the persistence interface for automation jobs and their runs.
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 (m *MemoryStateStore) List(_ context.Context) ([]ExecutionState, error)
func (*MemoryStateStore) Load ¶
func (m *MemoryStateStore) Load(_ context.Context, name string) (*ExecutionState, error)
func (*MemoryStateStore) Save ¶
func (m *MemoryStateStore) Save(_ context.Context, s ExecutionState) error
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 ¶
type OnceSchedule ¶
OnceSchedule fires exactly once at At.
func Once ¶
func Once(at time.Time) *OnceSchedule
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) WithDryRun ¶
WithDryRun returns a copy of o with DryRun enabled.
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 (*Registry) MustRegister ¶
MustRegister calls Register and panics on error. Intended for package-level init blocks where duplicate registration is a programming error.
func (*Registry) Register ¶
Register adds w to the registry. Returns an error if a workflow with the same name is already registered.
func (*Registry) Unregister ¶
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.
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.
type RunnerConfig ¶
type RunnerConfig struct {
Model sdk.ModelIdentifier
ProviderConfig *providers.Config
MaxTokens int
// WebSearchKeys provides per-owner web search provider keys.
// When set, the web_search tool uses these keys instead of reading from the
// process environment — required for safe multi-tenant execution.
WebSearchKeys map[string]string
// RAGService enables the rag_search/rag_ingest tools for this
// execution when set. Callers embedding automation in a multi-tenant
// host (e.g. seshat-ai/seshat-server) are expected to build one scoped
// to the right organization/corpus namespace per execution, the same
// way WebSearchKeys is resolved per owner rather than read from a
// single process-wide config.
RAGService *rag.Service
// DoclingURL enables the read_document_url tool when set — fetches
// and converts a remote document (PDF, webpage, ...) to markdown via a
// running docling-serve instance. Unlike WebSearchKeys/RAGService this
// isn't a secret or per-tenant value, so it's fine to read straight
// from RunnerConfig rather than resolved per execution.
DoclingURL string
}
RunnerConfig is the base template used to build an SDK client for each workflow execution.
type RunnerResolver ¶
type RunnerResolver func(ctx context.Context, ownerID string, agentSlug string, modelOverride string) (*Runner, AgentConfig, error)
RunnerResolver resolves a per-owner Runner at execution time. agentSlug is the named agent to resolve (empty = no named agent). modelOverride is the job-level model override (may be empty). The second return value carries the resolved base AgentConfig from the named agent definition; the scheduler merges it with the job's inline AgentConfig (inline fields take precedence over the resolved base).
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 ¶
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 ¶
NewScheduler creates a Scheduler backed by executor.
func (*Scheduler) Add ¶
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.
type Sink ¶
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).
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 Trigger ¶
type Trigger struct {
Type TriggerType
Cron string // valid when Type == TriggerTypeCron
Interval time.Duration // valid when Type == TriggerTypeInterval
RunAt *time.Time // valid when Type == TriggerTypeOnce
}
Trigger defines when an automation job fires.
func (Trigger) ToSchedule ¶
ToSchedule converts a Trigger to the Schedule interface used by the engine.
type TriggerType ¶
type TriggerType string
const ( TriggerTypeCron TriggerType = "cron" TriggerTypeInterval TriggerType = "interval" TriggerTypeOnce TriggerType = "once" )
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