Vihren

Go-native agent harnesses on Temporal.

Vihren is an Agent Development Kit for building durable agents in Go while keeping Temporal visible. Typed codegen removes workflow plumbing; durable value handles keep large agent data out of workflow history.

go install vihren.dev/vihren/cmd/vihren-gen@latest

Typed Temporal codegen

The first public Vihren layer is code generation for Temporal's Go SDK. Raw Temporal calls often cross important workflow and activity boundaries through names and result plumbing the compiler cannot fully check. Vihren generates typed activity proxies, workflow clients, and worker registration while leaving your workflow code close to the native SDK.

Without Vihren
var out GreetingOutput
err := workflow.ExecuteActivity(
	ctx,
	"ComposeGreeting",
	in,
).Get(ctx, &out)
return out, err
With Vihren
return Activity.ComposeGreeting(ctx, in)

With Vihren both the input and output values are type-checked

This is proof of the design direction: remove repetitive plumbing without hiding Temporal. View the complete example.

Large values without large workflow histories

Documents, tool results, model context, and conversation history can overwhelm Temporal payload limits or be written repeatedly as an agent runs. Vihren v0.3 stores the large bytes once and keeps small durable claims in workflow history.

workflow reads
Temporal ExternalStorage transparently stores a large payload and materializes it when workflow code needs the value.
workflow routes
blob.Value[T] lets activities exchange a typed inline value or storage handle without fetching large bytes into the workflow.

embeddedtemporal.WithLocalStorage wires both paths to one DataConverter-aware local filesystem and SQLite backend. The released foundation is local-only and does not yet include garbage collection.

Read how the storage model works · Browse the blob API · Run the measured example · v0.3.0 release

Smallest useful example

You can direct Vihren using simple workflow and activity annotations.

examples/codegenhello/workflow.go
// GreetingInput is the typed input for both the workflow and the activity.
type GreetingInput struct {
	Name string
}

//vihren:activity
func (a *GreetingActivities) ComposeGreeting(
	ctx context.Context,
	in GreetingInput,
) (GreetingOutput, error) {
	return GreetingOutput{
		Message: fmt.Sprintf("%s, %s", a.Prefix, in.Name),
	}, nil
}

//vihren:workflow
func HelloWorkflow(
	ctx workflow.Context,
	in GreetingInput,
) (GreetingOutput, error) {
	ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
		StartToCloseTimeout: time.Second,
	})
	return Activity.ComposeGreeting(ctx, in)
}
generate
go generate ./examples/codegenhello

View the complete runnable example.

Looking for design partners

The larger goal is a Go-native Agent Development Kit on Temporal: agent loops, tools, memory, human review, sandboxed execution, testing, and observability designed as durable workflow primitives.

If Temporal is infrastructure for your product and you are adding LLM-assisted or tool-using steps to long-running workflows, become a design partner or email [email protected].

Writing

All writing