Go SDK
Use the Go builder to register endpoints, serve Step handlers, and start or inspect Flows.
Installation
go get github.com/kode4food/argyll/sdk/go
Client
The package name is argyll:
import (
"time"
"github.com/kode4food/argyll/sdk/go"
)
client := argyll.NewClient("http://localhost:8080", 30*time.Second)
The examples below use this client.
Register a Script Step
import (
"context"
"github.com/kode4food/argyll/engine/pkg/api"
argyll "github.com/kode4food/argyll/sdk/go"
)
err := client.NewStep().
WithID("price-calculator").
WithName("Price Calculator").
Required("quantity", api.TypeNumber).
Required("unit_price", api.TypeNumber).
Output("total", api.TypeNumber).
WithScript(api.ScriptConfig{
Language: api.ScriptLangLua,
Script: `return {total = quantity * unit_price}`,
}).
Register(context.Background())
Executable Script Steps use Lua. The jpath language identifier is available for JSONPath predicates and attribute mappings, not executable Script Steps.
Register an HTTP Step
err := client.NewStep().
WithID("lookup-customer").
WithName("Lookup Customer").
WithSyncExecution().
WithEndpoint("https://api.example.com/customers/{customer_id}").
WithMethod("GET").
WithTimeout(5000).
Required("customer_id", api.TypeString).
Output("customer", api.TypeObject).
Register(context.Background())
Serve a Sync Step
Start registers the Step and starts an HTTP server that handles invocations:
handler := func(ctx *argyll.StepContext, args api.Args) (api.Args, error) {
name := args["name"].(string)
return api.Args{"greeting": "Hello, " + name}, nil
}
err := client.NewStep().
WithID("greet").
WithName("Greet").
Required("name", api.TypeString).
Output("greeting", api.TypeString).
Start(handler)
Serve an Async Step
handler := func(ctx *argyll.StepContext, args api.Args) (api.Args, error) {
asyncCtx, err := argyll.NewAsyncContext(ctx)
if err != nil {
return nil, err
}
go func() {
result := doLongRunningWork(args)
asyncCtx.Success(api.Args{"result": result})
}()
return api.Args{}, nil // return immediately
}
err := client.NewStep().
WithID("process").
WithName("Process").
WithAsyncExecution().
Required("input", api.TypeObject).
Output("result", api.TypeObject).
Start(handler)
Serve a Step with Compensation
Use WithCompensateHandler to register a handler that undoes a completed Work Item. Start generates the compensation URL:
handler := func(ctx *argyll.StepContext, args api.Args) (api.Args, error) {
chargeID := chargeCard(args["amount"])
return api.Args{"charge_id": chargeID}, nil
}
compensateHandler := func(
ctx *argyll.StepContext, args api.Args,
) error {
chargeID := args["charge_id"].(string)
return refundCharge(ctx, chargeID)
}
err := client.NewStep().
WithID("charge-card").
WithName("Charge Card").
Required("amount", api.TypeNumber).
Output("charge_id", api.TypeString).
WithCompensated("charge_id").
WithCompensateHandler(compensateHandler).
Start(handler)
The compensation handler receives a flat argument map containing the selected Attributes under their invocation names. Return nil for success, api.ErrWorkNotCompleted to request another attempt, or another error to report permanent failure.
Code Generation
The Go Step Generator derives a Step contract and handler from an ordinary Go function.
Builder Methods
Identity
WithID(id),WithName(name),WithLabel(k, v),WithLabels(labels)
Attributes
Required(name, type): required inputOptional(name, type, default): optional input with default valueConst(name, type, value): constant — a fixed value baked into the Step definitionMeta(name, metaKey): metadata — injects a named metadata field (e.g.flow_id,webhook_url) at execution timeOutput(name, type): output attributeWithForEach(names...): mark array inputs for parallel expansionWithCompensated(names...): include Attributes in compensation requests
Execution Type
WithScriptExecution()selects Script execution
Action Mode
WithInvokeMode(api.ActionMode),WithCompensateMode(api.ActionMode): set how an action reports its result,api.ActionModeSync(default) orapi.ActionModeAsyncWithSyncExecution(),WithAsyncExecution(): shorthand for the invoke action’s mode
HTTP
WithEndpoint(url),WithMethod(method),WithTimeout(ms),WithHealthCheck(url)WithCompensate(url): set the endpoint URL and compensated handlingWithCompensateMethod(method): compensate HTTP method, defaults toPOSTWithCompensateTimeout(ms): compensate timeout, defaults to the Step timeoutWithCompensateHandler(handler): register a compensation handler (auto-generates the URL when used withStart)
Script
WithScript(api.ScriptConfig{...})- executable Script Steps use Lua
Predicate / Match
WithPredicate(api.ScriptConfig{...})- predicates may use Lua or JSONPath ("jpath")WithRequiredMatch(name, api.ScriptConfig{...}): match predicate on a required input
Behavior
WithHandling(api.Handling): choose standard, memoized, or compensated handlingWithFlowGoals(goals...): configure a Flow-type StepWithFlowSpace(spaceID): restrict its child flow to a Space
Lifecycle
Register(ctx): register or update the Step definition, retrying transient failuresStart(handler): register or update with retries, then serve
The builder applies the engine’s validation rules before registration and returns the same validation error locally.
Registering a Prepared Step
RegisterStep accepts an existing *api.Step. It validates the definition, retries transient failures, and updates an existing registration after a conflict.
err := client.RegisterStep(context.Background(), step)
List Steps
steps, err := client.ListSteps(context.Background())
Start a Flow
Use WithGoals(goals...) to set all Goals at once, or WithGoal(goal) to add one at a time. Both WithLabel and WithLabels are also available on Flows.
err := client.NewFlow("order-123").
WithGoals("send-confirmation").
WithInitialState(api.InitArgs{
"customer_id": []any{"cust-456"},
"order_amount": []any{99.99},
}).
Start(context.Background())
Initial values are arrays. Wrap each value in a slice.
Query Flow State
flow := client.Flow("order-123")
state, err := flow.GetState(context.Background())
status, err := flow.GetStatus(context.Background())