# weft — full site text Generated from the HTML at weftgo.dev so it matches what readers see. Index: https://weftgo.dev/llms.txt --- *Source: https://weftgo.dev/* *Summary: Open-source Go framework for AI agents: tools are plain Go functions, every run is recorded with OpenTelemetry, and Studio replays any run from any step.* v0.14.2 · open source · MIT · Go 1.26+ # AI agents in Go. Batteries included. Tools are plain Go functions. weft runs the loop, keeps the conversation, records every run, and lets you replay any of them. $go get github.com/weftgo/weft@v0.14.2 OpenAI · Anthropic · Google · MCP · OpenAI-compatible servers ``` type Order struct { ID string `json:"id"` } func lookup(ctx context.Context, in Order) (string, error) { return db.Status(ctx, in.ID) // yours } func main() { defer otel.Install()() // record runs agt := weft.New( anthropic.Model("claude-sonnet-5"), weft.Tool("lookup_order", "Find an order.", lookup)) res, _ := agt.Generate(ctx, weft.Prompt("Where is order 1042?")) fmt.Println(res.Text()) } ``` Order 1042 shipped this morning.2 steps · 1 tool call · recorded in ./.weft/weft.db why weft ## The agent loop is 40 lines. Production is everything else. weft is built the way Go is built, and handles what breaks after the demo. ### Reads like the standard library Small interfaces, `context`, functional options, iterators. If you know `net/http`, you know weft. weft.New(model, tools...) ### Tools run in parallel Calls fan out on goroutines. One failure goes back to the model as data; the others finish. weft.Parallelism(8) ### A human approves A refund parks the run. A person decides over any channel, and the next run resumes. weft.RequireApproval() ### Sessions survive restarts Every step is appended as it happens. Reopen after a crash and the conversation continues. thread.Open(ctx, st, id, agt) ### Every run is recorded Standard OpenTelemetry into a local SQLite file, or Datadog, Langfuse and any OTLP endpoint. defer otel.Install()() ### Tests run offline Script a model, or record a real one once and replay it in CI. Free and deterministic. wefttest.Replay(t, "testdata") the api ## Everything an agent needs, in code you can already read. Streaming is a range loop over typed events. Cancel with `context`; each stream ends with exactly one terminal error. ``` for ev, err := range agt.Stream(ctx, prompt).Events() { if err != nil { return err } switch ev := ev.(type) { case weft.TextDelta: io.WriteString(w, ev.Text) case weft.ToolStart: slog.Info("tool", "name", ev.Name) } } ``` The final answer is decoded into a struct, on every provider. An invalid submission is a tool error the model fixes. ``` type Verdict struct { Approved bool `json:"approved"` Reason string `json:"reason"` } agt := weft.New(model, weft.Output[Verdict](), lookup) v, res, err := weft.GenerateAs[Verdict](ctx, agt, prompt) ``` A gated call parks and the run ends with it pending. Resume with the decision; a denial is a result the model reads. ``` refund := weft.Tool("refund", "Refund an order.", doRefund, weft.RequireApproval()) res, _ := agt.Generate(ctx, weft.Prompt("Refund order 42")) call := res.Pending[0] // ask someone: Slack, a UI, email res, _ = agt.Generate(ctx, weft.Messages(res.Messages...), weft.Approve(call.ID)) ``` A session is an append-only file. A crash mid-turn loses nothing; reopen it with the same agent. ``` st, _ := jsonl.Open(dir) // or thread/sqlite, thread.Memory() s, _ := thread.Create(ctx, st, agt) turn, _ := s.Send(ctx, weft.User("Where is order 1234?")) res, _ := turn.Wait() // after a restart: the same conversation s, _ = thread.Open(ctx, st, id, agt) ``` A subagent is a tool. Its events nest in the parent's stream, its usage adds up, and its failure is data. ``` researcher := weft.New(model, searchTool) orchestrator := weft.New(model, weft.Subagent("research", "Research in depth.", researcher, weft.Timeout(2*time.Minute))) ``` Agent tests run in `go test` with no network: a scripted model, or a real one recorded once. ``` model := wefttest.Script( wefttest.ToolCalls(wefttest.Call{ Name: "lookup_order", Args: `{"id":"1042"}`}), wefttest.Say("Order 1042 has shipped."), ) // or record a real model once, replay it forever model = wefttest.Replay(t, "testdata/order") ``` Full reference on pkg.go.dev (https://pkg.go.dev/github.com/weftgo/weft). studio ## See every run. Replay any step. Studio is the UI on your recordings: one `http.Handler` in your app, or `weft dev` from the terminal. [image: An Acme Support chat page on the left with two order questions and their answers. On the right, the weft devtools panel docked beside it lists the conversation's two turns and shows the open turn: span timings, the lookup_order tool call with its arguments and result, the reply, and Experiment and Re-run buttons.] The devtools panel docks beside your own chat page and follows the conversation live. [image: Studio's run page: prompt and answer, the two steps (a lookup_order tool call, then the reply), a span waterfall with invoke_agent, chat and execute_tool spans, and the selected tool span's timing and attributes.] Every step, tool call and span, with subagents nested under the call that started them. [image: Studio's playground: variant B's settings on the left; on the right, variant A's result with a diff against the original turn, variant B's lookup_order call awaiting a continue or skip decision, and a table comparing status, tokens, latency and steps.] Edit the prompt, model or tools and compare variants. Side-effect tools are replayed or parked, never fired twice. ### The exact request Each model call's system prompt, tool catalog and parameters, recorded beside the transcript. ### Replay from any step Edit the transcript in place and preview the exact request before it is sent. ### Step-aligned diff Compare runs step by step: what the model saw, called and answered. ### Search, cost, save as test Full-text search, cost per run, and any run exported as `wefttest` fixtures. ### One command for the dev loop `weft dev` starts Studio on `127.0.0.1:7331`, runs your app beside it, and restarts it on save. Apps in other languages send OpenTelemetry to the same port. ``` go install \ github.com/weftgo/weft/cmd/weft@v0.14.2 weft dev # Studio + your app weft runs --failed # find the bad run weft doctor # check the setup ``` architecture ## One module. Four layers. Use only what you need. Import `weft` for everything; only the packages you use are compiled in. Import `weft/core` for the loop alone. github.com/weftgo/weft weft/studio (https://pkg.go.dev/github.com/weftgo/weft/studio) + runtime See and replay any run: inspector, devtools panel, playground. weft/otel (https://pkg.go.dev/github.com/weftgo/weft/otel) + obsdb Record every run as OpenTelemetry, into SQLite or ClickHouse. weft/thread (https://pkg.go.dev/github.com/weftgo/weft/thread) Durable sessions: branching, compaction, approvals, steering. own moduleweft/core (https://pkg.go.dev/github.com/weftgo/weft/core) The loop: tools, parallel calls, streaming, approvals, subagents, MCP, providers. One dependency: the OpenTelemetry API. Official vendor SDKs, standard OpenTelemetry, no hosted service. MCP works both ways: consume servers as tools, or expose your tools as one. get started ## Your first agent in five minutes. - ### Install go get github.com/weftgo/weft@v0.14.2 - ### Write a tool A Go function with a typed input struct. `weft.Tool` reflects its JSON Schema; `weft.New` makes the agent. - ### Run and watch weft dev Studio opens beside your app with every run recorded. ### Using a coding agent? The repo ships `AGENTS.md` (https://github.com/weftgo/weft/blob/main/AGENTS.md), the whole API on one screen, and this site publishes `llms.txt`. Paste this into Claude Code, Cursor or Copilot: ``` Read https://weftgo.dev/llms-full.txt and https://github.com/weftgo/weft/blob/main/AGENTS.md. Build a Go agent with weft that answers support questions with a lookup_order tool, records every run, and serves Studio at /studio/. Test it with wefttest. ``` shipped · v0.14.2 Core, three providers, MCP, sessions, recording, Studio, replay and the `weft` command. next First-party HTTP/SSE serving, evals over recorded runs, a prompt registry. then Memory and durable-execution adapters, and a 1.0 core API behind a compatibility gate. faq ## Questions people ask. **What is weft?** weft is an open-source Go framework for building AI agents. Tools are plain Go functions; weft runs the agent loop, keeps durable sessions, records every run over OpenTelemetry, and ships Studio to inspect and replay any run. One Go module is the whole framework, and the loop alone is its own module. MIT licensed, Go 1.26+. **How do I get started with weft?** Run `go get github.com/weftgo/weft@v0.14.2`, write a tool as a Go function with a typed input struct, create an agent with `weft.New(model, tools...)`, and call `Generate`. Add `defer otel.Install()()` to record runs, then run `weft dev` (or mount `studio.Handler`) to see them in Studio. **Which Go agent framework should I use?** For a Go service, weft: a standard-library-shaped API, the vendors' official SDKs for OpenAI, Anthropic and Google, MCP both ways, parallel tools on goroutines, human approvals, durable sessions, OpenTelemetry recording, Studio, and offline tests. It is modular, so you can adopt only the core. **When is weft not the right fit?** When you want a hosted no-code agent builder, want to write the agent itself in Python or TypeScript, need a graph engine today (weft's is designed, not shipped), or need a frozen 1.0 API now. Studio still works for agents in any language: it ingests OpenTelemetry. **Can I use weft if my backend is Python, TypeScript or Java?** Yes, as a service. The agent runs as a small Go program beside your backend, which calls it over HTTP, gRPC or a queue; Go compiles to one static binary. Studio also ingests OpenTelemetry from agents written in any language: run `weft studio` and point the exporter at `127.0.0.1:7331`. **Which model providers does weft support?** OpenAI and any OpenAI-compatible server, Anthropic, and Google Gemini, through the vendors' official Go SDKs. MCP works both ways: consume MCP servers as tools, or expose your tools as an MCP server. **How do I see what my agent did?** Add `defer otel.Install()()` to record every event, transcript and span to a local SQLite file, then run `weft dev` or mount `studio.Handler(studio.DB(otel.LocalDB()))` in your HTTP mux. Studio shows each step, tool call, span and the exact request sent to the model. The same pipeline exports to Datadog, Langfuse or any OTLP endpoint. **Can I replay an agent run from the middle?** Yes. In Studio or the devtools panel, replay from any step, tool call or message, and edit the transcript first: the user message, a tool's arguments or result, or the reply. Studio previews the exact request the model will receive, and the step-aligned diff compares the replay with the original. **Is it safe to re-run a turn in the playground?** Yes. Experiments run in your process, and a tool that is not marked safe to re-run is answered from the recording or parked. Only the tools you opt in with `runtime.AllowSideEffects` run for real. **What is the weft command?** The `weft` binary (`go install github.com/weftgo/weft/cmd/weft@v0.14.2`) is the dev loop: `weft dev` runs Studio and your app together and restarts the app on save, `weft studio` serves Studio alone with OTLP ingest, `weft runs` lists runs, `weft export` turns a run into a `wefttest` fixture, and `weft doctor` checks the setup. **Can an AI coding assistant build with weft?** Yes. The repository ships `AGENTS.md`, which fits the whole API on one screen, and the site publishes `llms.txt` and `llms-full.txt`. The API follows the patterns models already know from `net/http`: small interfaces, context, functional options. **Is weft production ready?** weft is v0.14.2, pre-1.0. Every layer has been through a production-readiness review; the thread API and storage format are not frozen. Pin your versions, because breaking changes can still happen between minor releases.