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 call | What 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.NewDecoder | Decode 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.