Chat

September 8, 2026 · View on GitHub

Status: foundational harness primitives (filesystem + bash) plus the planning, skills, subagents, workspace, and HITL permissions capabilities. Pluggable backend implementations (in-memory, remote sandbox) are available — see b4.config.ts. Tool-output offloading is supported for workspace-backed routes, and conversation summarization is available as an opt-in config.

What this shows

  • B4.run route discovery and the tools/ convention
  • Workspace capability — when a route's working directory contains workspace/, B4.run auto-contributes readFile/writeFile/listDir/runBash tools wired through pluggable backends. The filesystem and exec backends default to local node:fs / child_process; swap them in b4.config.ts for in-memory storage, remote sandboxes, etc.
  • AGENTS.md memory autoload — B4.run auto-injects workspace/AGENTS.md into the system prompt on every turn; the agent updates it via writeFile
  • Planningplan.md in the route directory opts the agent into the built-in writeTodos tool, a todos state channel, and a plan_update Agent Protocol stream event. The AG-UI adapter maps valid root updates to standard replacement b4.plan activity snapshots.
  • Skillssrc/app/chat/skills/<name>/SKILL.md files are auto-listed in the agent's system prompt (name + description). The agent calls readSkill({ name }) to load a skill's full body on demand. Two example skills ship with the demo: workspace-conventions and recover-from-failure.
  • Subagents/coordinator dispatches to specialist subagents (research, summarizer) via an auto-generated task({ subagent, input }) tool. Subagent runs bubble subagent.* Agent Protocol stream events with call_id correlation, and the AG-UI adapter maps matching lifecycles to bounded replacement b4.subagent snapshots. The basic web client registers b4ActivityRenderers from @b4run/ag-ui/react, but drives only /chat and does not expose /coordinator, so drive coordinator runs through Agent Protocol instead.
  • HITL permissionsb4.config.ts seeds allow/deny lists for runBash. Unknown commands in interactive mode emit an interrupt; resume the thread with once, always, or deny to continue. See Permissions for the interrupt/resume flow.
  • End-to-end streaming to a CopilotKit V2 web client over B4.run's AG-UI endpoint (POST /agui/{routeId}, see @b4run/ag-ui) for basic /chat messages. The browser uses CopilotKit's same-origin multi-route runtime under /api/copilotkit/*; the runtime's HttpAgent owns the server-to-server B4.run call. The client presents plan/subagent activities and the standard permission decision control.

Model choice

This example uses gpt-5 with reasoning: { effort: "high" }. In live testing, smaller models (gpt-5-mini, gpt-5-nano) tend to ignore explicit tool-use directives and produce generic "what can I help you with?" responses on the first turn — they don't reliably exercise the planning + memory capabilities. gpt-5 engages with tools and actually drives an agent loop. The tradeoff: each turn costs more.

If you swap to a smaller model, expect to do more prompt-engineering work to get tool calls to fire.

Quickstart

Run these commands from the repository root:

cd examples/chat
cp server/.env.example server/.env   # add OPENAI_API_KEY
cp web/.env.example web/.env.local
pnpm install
pnpm dev
# open http://localhost:3000

Layout

examples/chat/
├── server/                 # @b4-example/chat-server (B4.run routes)
│   ├── b4.config.ts      # appDir + optional backends config
│   ├── workspace/          # shared workspace (AGENTS.md lives here)
│   └── src/app/
│       ├── chat/                              # /chat route
│       │   ├── index.ts                       # agent({ model, systemPrompt })
│       │   ├── state.ts
│       │   ├── system-prompt.ts
│       │   ├── plan.md                        # presence enables planning
│       │   └── skills/                        # SKILL.md files per skill
│       └── coordinator/                       # /coordinator route + subagents
│           ├── index.ts
│           └── subagents/
│               ├── research/index.ts
│               └── summarizer/index.ts
└── web/                    # @b4-example/chat-web (CopilotKit v2 web client)
    └── app/
        ├── layout.tsx                 # imports @copilotkit/react-core/v2/styles.css
        ├── page.tsx                   # CopilotKit + CopilotSidebar
        └── api/copilotkit/[...path]/route.ts # V2 runtime + HttpAgent → B4.run /agui/%2Fchat%23agent

Security caveats

runBash executes shell commands on your machine with cwd: workspace/ and a timeout. This is NOT a sandbox. Network calls, package installs, file ops outside workspace/ via shell expansion — all possible. Do not point untrusted users at this example.

Current capability notes

  • HITL permission gating is active in this demo. The example config pre-approves a few read-only shell commands and denies destructive patterns; any other runBash command pauses the run for a human decision in interactive mode. Path escapes outside workspace/ are also permission-gated by the workspace capability. See Permissions and the configuration reference. The basic web client renders CopilotKit's standard interrupt decision control.
  • Tool-output offloading is supported by the runtime and is active whenever the app root has a workspace/ directory. Large tool results are written under workspace/tool-outputs/ and replaced in context with a preview plus a readFile handle. Tune thresholds and retention with the toolOutput config. See Context Management and the configuration reference.
  • Conversation summarization is supported but opt-in. This example leaves it disabled by default; enable summarization.enabled in b4.config.ts when you want older message history compacted after a token threshold. See Context Management and the configuration reference.

The remaining limitations are scoped to this example's surface, not missing runtime capabilities:

  • Nested-object tool inputs (e.g., edit_file({ edits: [{ old, new }] })) — typegen extension
  • The web client only drives /chat; /coordinator is outside this basic client's UI.