Skip to Content
ProvidersWorkflow

Workflow

Workflows are under active development and are not yet stable. Breaking changes may happen between releases without warning. Feedback and bug reports are welcome via GitHub Issues .

Gestalt workflows define an ordered steps plan and one or more top-level on activations. A trusted workflow provider owns durable definitions, activation state, workflow runs, per-step execution state, run events, and run output.

The public workflow contract is intentionally small:

  • ApplyDefinition stores or updates one durable definition.
  • SetDefinitionPaused and SetActivationPaused control execution.
  • StartRun, SignalRun, and SignalOrStartRun operate on definition-backed runs and carry input.
  • DeliverEvent sends an app event to provider-owned activation matching.
  • GetRun, ListRuns, GetRunEvents, and GetRunOutput expose run state.

There are no separate public CRUD objects for cron or event activation records. Author one workflow definition with steps and on, then let the provider reconcile activations internally.

Definitions

Config-managed workflows live under workflows.definitions.

workflows: definitions: toolshed_pr_code_review: provider: temporal runAs: subject: id: service_account:github_webhook kind: service_account paused: false steps: - id: review app: name: codeReview operation: pullRequests.reviewWorkflow input: github: "${{ input.github }}" raw: "${{ input.raw }}" on: github_pr: event: type: github.pull_request source: github subject: repo:valon-technologies/toolshed input: github: "${{ signal.data.github }}" raw: "${{ signal.data.raw }}" nightly: schedule: cron: "0 2 * * *" timezone: America/New_York input: reason: nightly

Each definition is applied to the provider during bootstrap with a stable config ID. The provider assigns a generation and pins in-flight runs to the generation they started with.

Steps

A workflow step is either an app operation or an agent turn.

steps: - id: diagnose app: name: datadog operation: logs.search input: query: "${{ input.query }}" - id: summarize agent: provider: openai model: gpt-5.5 prompt: template: "Summarize: ${{ steps.diagnose.outputs.body }}" - id: notify app: name: slack operation: messages.post input: channel: "${{ input.channel }}" text: "${{ steps.summarize.outputs.text }}"

timeout/timeoutSeconds is an optional per-step override. Omit it to use the provider default.

Expressions

Workflow authoring uses ${{ ... }} expressions. Supported roots are:

  • input.*: run input after activation mapping.
  • signal.*: the latest signal or delivered event payload available while mapping activation input.
  • steps.<stepId>.outputs.*: output from a prior step.
  • steps.<stepId>.inputs.*: materialized inputs for a prior step.

when guards must resolve to booleans. A skipped dependency skips the dependent step with a missing-dependency reason.

Events

Apps deliver events through the workflow service.

import { Workflow } from "@valon-technologies/gestalt"; const workflows = Workflow.connect(); await workflows.deliverEvent( { type: "github.pull_request", source: "github", subject: "repo:valon-technologies/toolshed", datacontenttype: "application/json", data: { github, raw }, }, { appName: "github", providerName: "temporal" }, );

The provider matches the event against definition activations, evaluates the activation input mapping, and starts or signals runs with the resulting run.input.

Providers

A workflow provider implements the WorkflowProvider service:

type Provider struct{} func (p *Provider) ApplyDefinition( ctx context.Context, req *gestalt.ApplyWorkflowProviderDefinitionRequest, ) (*gestalt.WorkflowDefinition, error) { // Store req.Spec atomically and return the provider generation. return &gestalt.WorkflowDefinition{ Id: req.Spec.Id, Generation: 1, Target: req.Spec.Target, Activations: req.Spec.Activations, ProviderName: req.ProviderName, }, nil } func (p *Provider) StartRun( ctx context.Context, req *gestalt.StartWorkflowProviderRunRequest, ) (*gestalt.WorkflowRun, error) { return &gestalt.WorkflowRun{ Id: req.IdempotencyKey, DefinitionId: req.DefinitionId, DefinitionGeneration: req.ExpectedDefinitionGeneration, Input: req.Input, }, nil }

Providers execute one durable unit per step and persist the run projection after each step. GetRun returns the current step list, and GetRunEvents / GetRunOutput expose the event stream and final output.