Skip to main content

Why embed it

The repo’s main program is intentionally tiny and hardcoded. If you want to:
  • control the system prompt
  • choose your own default model
  • expose different tools
  • swap the UI layer
  • integrate with your application state
then you should assemble the packages directly in your own Go code.

Minimal example

The three pieces you compose

openai.Client

Responsible for HTTP requests and streaming SSE responses from an OpenAI-compatible endpoint.

loop.Loop

Owns the agent loop:
  • advertises tool schemas
  • streams assistant deltas
  • accumulates tool calls
  • executes tools
  • appends tool results
  • continues until no more tools are called
You provide the system prompt yourself by putting openai.SystemMessage(...) in the messages slice before calling RunLoop.

Your tools

You supply a map[string]loop.Tool. Each tool becomes a function-style schema in the model request.

Collecting the final conversation

After RunLoop finishes, call:
That returns the stored conversation, including assistant and tool messages produced during the run.

A common pattern

In a real application, it is normal to keep hrns as the thin agent core and put your policy around it:
  • validate user input before creating messages
  • choose the model outside the TUI
  • wrap tools with logging or authorization
  • persist agent.Messages() somewhere else
  • render agent.Chunks() in your own UI
That is the intended strength of this repo: small parts you can reason about and reassemble.