The Problem
Businesses need a way to assemble a production‑grade web agent without writing custom code for each slot (retrieval, memory, channel, etc.). Existing libraries force bespoke wiring or hard‑coded provider lists, making upgrades and partner integrations painful.
What This Does
webagent supplies a declarative framework: a JSON spec selects a provider per slot, and the framework stitches the chosen components into a running agent.
cmd/webagent/main.goparses the CLI and triggers eitherbuild.BuildAgentorbuild.ValidateSpec.build/build.goresolves the spec, pulls providers from the registries incore/core.go, and wires them together.action/action.godefines theProviderinterface; concrete providers live inaction/mcp.go(browser tool) andaction/provider.go(demo).brain/gateway.goimplements the OpenAI‑compatible gateway, whilebrain/echo.gosupplies a no‑op echo brain for demos.
The framework enforces safety by wrapping every provider in action.Guard (see action/guard.go), which runs the chosen guardrail before execution.
How It Is Wired
Entry point – cmd/webagent/main.go
mainparses flags;serveorvalidateare routed tobuild.BuildAgentorbuild.ValidateSpec.build.BuildAgentcallscore.NewAgentwith the resolved slots.core.NewAgentiterates over the slot list defined incore/core.go, calling each slot’s registry to obtain the provider (brain/registry.go,action/provider.go, etc.).- For the
actionslot,action.Guardwraps the chosen provider; the guard uses theguardrailslot (guardrail/guardrail.go). - Channels are created via
channels/channels.go; the Slack provider (channels/slack.go) and WhatsApp stub (channels/whatsapp.go) are examples. - The final
Agentobject has a methodRunthat listens on each channel and forwards messages to the brain (brain/gateway.goorbrain/echo.go).
External effects
- Network: HTTP requests to the chosen LLM endpoint (e.g., OpenRouter) through
brain/gateway.go. - File system: Storing API keys via
cmd/webagent/keys.go; keys are written to~/.config/webagent/keys.json(mode 0600). - Logging: Optional observability via the
Observerslot, currently stubbed inobservability/observability.go.
The module graph shows a single hub at core/core.go; any change to slot registration can ripple through the whole agent, so those files should be guarded by unit tests (see core/core_test.go).
How To Use It
Setup
git clone https://github.com/moses-y/webagent
cd webagent
go build ./cmd/webagent
Configuration
- API keys are stored with
webagent keys set <name>; they live in~/.config/webagent/keys.json. - Example specs are in
examples/*.json.
Running
# Validate a spec
webagent validate examples/bakery.json
# Start an agent
webagent serve examples/bakery.json
The CLI defaults to the echo brain; to use a real model, set a key and reference it in the spec:
webagent keys set openrouter
# in the spec: "model": {"type":"openrouter","config":{"model":"anthropic/claude-sonnet-5"}}
webagent serve myspec.json
Real‑World Use
A food‑delivery startup can deploy examples/zomato.json with a live retrieval backend and a whatsapp channel. The agent receives user messages, queries the live retrieval provider, and replies via the same channel—no custom code required. Adding a new channel (e.g., Telegram) is a single provider registration in channels/telegram.go and a spec update.
Code Health & Issues
- Low – Secret‑shaped paths in
secrets/secrets.go(3 occurrences). - 22 test files cover core logic (
core/core_test.go,brain/gateway_test.go, etc.). - CI is defined in
.github/workflows/ci.yml; builds on Linux, macOS, and Windows. - No license file found; the repository lacks an SPDX header, which may affect downstream compliance.
The Bottom Line
webagent delivers a clean, declarative way to assemble web agents, abstracting slot selection and provider wiring. Its Go‑module architecture and extensive tests make it a solid foundation for production use, provided the missing license header and precaution around secret handling are addressed. It is best suited for teams that need rapid agent iteration with minimal custom code.