Skip to content

Fork the template ​

Same checklist as TEMPLATE.md in the repo, kept in sync. Use this when you've forked before and don't need the tutorial walkthrough — just the list.

Re-sync is the design goal. Everything below customizes via config, SOUL.md, plugins, and env — not by editing core files. The fewer tracked files you touch, the cleaner git merge upstream/main (or a cherry-pick) stays. CHANGELOG.md is set to merge=union (.gitattributes), so your entries and upstream's coexist instead of conflicting.

0. Name + identity (config, not a rename) ​

Set your agent's user-facing name in config — it flows to the console brand, window/tab title, agent card, and system prompt:

  • identity.name in config/langgraph-config.yaml (or the setup wizard), and
  • config/SOUL.md for persona — it's loaded into the system prompt, so you don't edit graph/prompts.py. (The model answers natively — there is no <scratch_pad>/<output> protocol to preserve; reasoning streams on the gateway's reasoning_content channel.)

Do NOT sed the internal protoagent identifier. It's the stable template name for logger namespaces, the ~/.protoagent data dir, PROTOAGENT_* env vars, and the plugin namespace — all internal, never user-facing. Renaming it rewrites ~120 files and makes every upstream merge conflict, for zero functional gain. Leave it.

The few places that genuinely want your slug are env-driven, no file edit:

  • AGENT_NAME env var (Prometheus prefix, Langfuse tag). It also names the legacy A2A <NAME>_API_KEY header, which is deprecated — authenticate with the bearer token (auth.token / A2A_AUTH_TOKEN) instead.
  • Docker image label / GHCR path — set in your deploy, not the template.

1. Enable the release pipeline (no workflow edit) ​

Set the RELEASE_ENABLED repo variable to true:

bash
gh variable set RELEASE_ENABLED --body true

The release workflows gate on it, so you enable releases without touching prepare-release.yml / release.yml — and upstream changes to those files re-sync cleanly. Until the variable is set, releases won't fire (intentional).

2. Tools — keep / drop / add (config + plugins, no core edit) ​

The starter tools ship by default: current_time, calculator, web_search, fetch_url (keyless general) plus the memory, scheduler, notes, and tasks tools.

  • Drop the ones you don't want via config — list them under tools.disabled in config/langgraph-config.yaml (live-reloadable). No get_all_tools() edit.
  • Add your own as a plugin (plugins/<id>/ with a register(registry)), so they're discovered without touching core. See Plugins.

(Editing tools/lg_tools.py::get_all_tools() directly still works, but it's a core edit that conflicts on every upstream re-sync — prefer config + plugins.)

Integrations are plugins. The bundled ones (e.g. plugins/telegram) turn off with plugins: { disabled: [telegram] } — no directory delete, no core edit. Integrations like GitHub, Discord, Google, and Slack install as external plugins from their own repos (browse + install in Settings ▸ Plugins ▸ Discover).

See the starter tools reference for the shapes of the shipped ones.

Customize the console without editing core, too. The frontend has the same fork-safe seam as the backend (ADR 0061): drop a src/ext/<name>.tsx that calls registerSurface (a rail panel), registerSlashCommand (a client-side /<name>), registerComposerAction (a composer button), registerPaletteCommand (a command-palette command), or createUISlice (its own persisted UI state) — no edit to App.tsx / ChatSurface.tsx / ChatSessionSlot.tsx / uiStore.ts, so upstream pulls stay conflict-free. (Untrusted UI still goes through sandboxed plugin iframe views — see Building a plugin view.)

3. Configure subagents (optional) ​

graph/subagents/config.py ships with one researcher. Either:

  • Add more by registering SubagentConfig instances in SUBAGENT_REGISTRY and matching fields in graph/config.py::LangGraphConfig, or
  • Call create_agent_graph(config, include_subagents=False) in server/agent_init.py::_init_langgraph_agent() to skip subagents entirely.

See Configure subagents for the full pattern.

4. Point at a model ​

Edit config/langgraph-config.yaml::model.name. Two options:

  1. Gateway alias — register protolabs/<your-name> in your LiteLLM gateway, set name: protolabs/<your-name>. Swapping models becomes a gateway edit.
  2. Direct model — set name: openai/gpt-4o or anthropic/claude-opus-4-8 and let the gateway route through directly.

Option 1 is preferred.

5. Deploy ​

See Deploy via GHCR. The Dockerfile uses a single COPY . /opt/protoagent/ so new files don't need Dockerfile updates.

6. Delete TEMPLATE.md ​

Once the checklist is done, delete it and rewrite README.md to describe your specific agent.

Part of the protoLabs autonomous development studio.