Documentation
¶
Overview ¶
Package workflow loads and runs declarative pipelines (workflow files) that chain scripts, tool calls, one-shot model completions, and subagent delegations without routing intermediate data through the main model.
Design: docs/guides/workflow.zh.md. The invariant is that the main conversation never touches large payloads: steps exchange data by reference (artifact files under work/workflow/<run>/) and only the rendered result template crosses back to the model.
Package workflow registers tool/workflow: run a named declarative pipeline (script / tool / model / agent steps) with model-small name+args input, so large payloads flow between steps without crossing the main model.
Index ¶
Constants ¶
const ( StepScript = "script" StepTool = "tool" StepModel = "model" StepAgent = "agent" )
Step types.
const DefaultModelMaxInputBytes = 16384
DefaultModelMaxInputBytes bounds the rendered model-step prompt. Exceeding it fails the step instead of silently truncating: routing a large payload back through a model is exactly what workflows exist to avoid.
const MaxViewBytes = 50 * 1024
MaxViewBytes caps the inline view a step state exposes to templates; larger outputs are written to an artifact file and referenced by path instead.
Variables ¶
var DefaultDirs = []string{workspace.ScopeLocal + ":workflows", workspace.ScopeGlobal + ":workflows"}
DefaultDirs are scanned when the plugin config omits dirs; local wins.
Functions ¶
func NewWorkflow ¶
func NewWorkflow(cfg WorkflowConfig, deps WorkflowDeps) (agentkit.Tool, error)
NewWorkflow registers tool/workflow: Run a fixed pipeline from the workflows directory by name.
Best practices:
- Point deps.runtime at a sibling tools/runtime that includes tool/shell-bash (bash) and the tools your steps call, and never includes tool/workflow itself.
- Keep step data exchange by reference: scripts and tools read/write files; the model only sees the rendered result.
- Mount through tools/runtime deps.tools; the "workflow" slash command is contributed via CommandProvider on the same instance.
Types ¶
type Engine ¶
type Engine struct {
// Tools executes tool steps through the policy/approval pipeline. Use a
// sibling tools/runtime instance that does not include tool/workflow.
Tools agentkit.ToolRuntime
// Workspace resolves scoped dirs and the artifact root.
Workspace workspace.Service
// LLM backs model steps (one-shot completion).
LLM agentkit.LLMProvider
// Subagent backs agent steps.
Subagent subagent.Spawner
// Telemetry receives workflow.step / workflow.run events.
Telemetry captelemetry.Toolkit
}
Engine runs workflows against injected capabilities. All fields except Workspace are optional per step type; a step whose capability is missing fails with a clear error.
type JSON ¶
type JSON struct{ V any }
JSON wraps a structured step output so direct template actions ({{ .steps.x.json }}) render compact JSON while dig can still navigate it.
type Step ¶
type Step struct {
ID string `json:"id"`
Type string `json:"type"`
// ContinueOnError records the failure in step state and runs the next step.
ContinueOnError bool `json:"continueOnError,omitempty"`
TimeoutSeconds int `json:"timeoutSeconds,omitempty"`
// script
Run string `json:"run,omitempty"`
Dir string `json:"dir,omitempty"`
// tool
Tool string `json:"tool,omitempty"`
Args map[string]any `json:"args,omitempty"`
// model
Model string `json:"model,omitempty"`
Prompt string `json:"prompt,omitempty"`
OutputSchema map[string]any `json:"outputSchema,omitempty"`
MaxInputBytes int `json:"maxInputBytes,omitempty"`
// agent
Agent string `json:"agent,omitempty"`
Task string `json:"task,omitempty"`
}
Step is one pipeline stage. Fields are type-specific; see the design doc.
type Workflow ¶
type Workflow struct {
Name string `json:"-"`
Description string `json:"description"`
Inputs map[string]any `json:"inputs"`
Steps []Step `json:"steps"`
Result string `json:"result"`
// Dir is the directory holding the workflow file; relative script paths
// resolve against it.
Dir string `json:"-"`
// Path is the workflow file itself, for error messages.
Path string `json:"-"`
}
Workflow is one parsed pipeline file. Name comes from the file name.
func Discover ¶
Discover re-reads every configured dir and returns the workflows found, sorted by name. Like subagent Definitions, re-reading per call makes edits take effect without a reload command. The first dir wins on duplicate names; files that fail to parse are collected into errs (and skipped) so one bad file does not block the others.
func (*Workflow) InputsJSONSchema ¶
InputsJSONSchema returns the declared inputs schema as a JSON string for the tool description; empty when no inputs are declared.
type WorkflowConfig ¶
type WorkflowConfig struct {
// Dirs are scoped workflow directories in precedence order (first dir wins
// on duplicate names). Defaults to local:workflows then global:workflows.
Dirs []string `json:"dirs,omitempty"`
}
type WorkflowDeps ¶
type WorkflowDeps struct {
// Runtime executes tool steps; use a sibling tools/runtime instance without
// tool/workflow itself (cycle break, same pattern as tool/subagent).
Runtime agentkit.ToolRuntime `json:"runtime"`
Workspace workspace.Service `json:"workspace"`
// LLM is required only when a workflow uses model steps.
LLM agentkit.LLMProvider `json:"llm,omitempty"`
// Subagent is required only when a workflow uses agent steps.
Subagent subagent.Spawner `json:"subagent,omitempty"`
// Telemetry receives workflow.run / workflow.step events.
Telemetry captelemetry.Toolkit `json:"telemetry,omitempty"`
}