go-handler

A pugmark handler written in Go, using only github.com/firetiger-oss/pugmark/ipc. It follows the same log-replay shape as the Python examples: walk the append-only log of JSON events, fold each into in-process state, dispatch on the tail event’s kind, append one new event. No LLM dependency, so it runs without an API key and proves Go is a first-class handler language. Full source on GitHub.

The pipeline takes an input event and produces uppercased, reversed, and done events in sequence.

Build and run

go build -o /tmp/go-agent ./examples/go-handler
pugmark switch file:///tmp/pug-go          # point pugmark at this example's bucket
pugmark run --start -- /tmp/go-agent
pugmark log -A

The handler self-bootstraps by seeding an {"kind":"input","text":"Hello, Pugmark"} event when it sees an empty log; subsequent iterations advance through uppercased → reversed → done → pause.

What it shows

Pugmark Go SDK callWhat it does
ipc.DefaultSession()The default Session wired to stdin/stdout
s.Read()Iterate the session log in stream order as an iter.Seq2[Object, error]
obj.Body() + json.NewDecoderDecode each entry as a typed Event struct
switch ev.Kind { … }Fold one event into accumulated State; same shape for the final dispatch
ipc.LocalObject(&ipc.Output{Data: …, ContentType: "application/json"})Build an output object from JSON bytes
s.Write(obj)Append one new event to the log
s.Pause(reason)Terminate the pugmark run loop

Two switch blocks make up the whole handler: one fold(state, ev) switch to accumulate state during replay, and one outer switch on the tail event’s kind to decide what to write. Same shape as the Python examples; Go’s switch is the closest analogue to Python’s match.

The dispatch

switch kind {
case "":
    write(s, Event{Kind: "input", Text: "Hello, Pugmark"})
case "input":
    write(s, Event{Kind: "uppercased", Text: strings.ToUpper(state.Input)})
case "uppercased":
    write(s, Event{Kind: "reversed", Text: reverse(state.Uppercased)})
case "reversed":
    write(s, Event{Kind: "done", Text: fmt.Sprintf("processed %d characters", len(state.Input))})
case "done":
    must(s.Pause("workflow complete"))
}

The compiled Go binary can also be packaged into a Lambda function or container image. Each S3 object-creation event on the session bucket invokes the handler once with the new snapshot; see lambda-deploy.