pleach
Cookbook

Reference apps

Two runnable examples that ship inside the @pleach/core npm package — minimal-agent for first-turn baselines, host-adapter for legacy-orchestrator integrations.

@pleach/core ships two runnable examples under examples/ in the package itself. Both run; both are commented; both demonstrate a distinct integration depth.

For agent shapes by problem (customer support, research, coding, multi-tenant SaaS, regulated domain), see Agent shapes. For end-to-end wiring patterns (streaming chat, custom tools, custom storage, BYOK, moderation, jobs, interrupts, cost reporting, OTel, multi-tenant, compliance, projections, hash-chain), see Recipes.

After npm install @pleach/core, the examples live at:

node_modules/@pleach/core/examples/
  minimal-agent/
  host-adapter/

For a working copy, clone the upstream repository:

git clone https://github.com/pleachhq/core
cd core/examples/minimal-agent

examples/minimal-agent

The "does it construct?" baseline. Proves new SessionRuntime() (the session runtime) works with zero config, mock-mode storage, and a synthesized provider. No external services, no API keys, no migrations.

What it shows

  • Default-config runtime construction.
  • A single tool defined via defineTool with a Zod schema.
  • A one-turn executeMessage call that streams events to the console.

Running it

cd examples/minimal-agent
npm install
HARNESS_MOCK_MODE=true node index.mjs

Output is the event stream printed line-by-line — session.created, step.start, message.delta chunks, tool.started, tool.completed, message.complete, step.end. Inspect each shape against Stream events.

Structure

minimal-agent/
  index.mjs        — entry point; constructs runtime + runs one turn
  tools.mjs        — one defineTool example
  README.md        — usage instructions
  package.json     — minimal deps

What to crib. The index.mjs is the shortest possible end-to-end agent loop. Use it as the starting skeleton for a throwaway script that wants @pleach/core as a CLI, a unit test fixture that exercises the runtime against mock storage, or a first-cut prototype before you wire real storage and providers.

What it doesn't show. Persistent storage — mock mode wires MemoryAdapter and state evaporates on exit. A real provider — the synthesized one returns plausible mock text. React, API routes, sync, plugins, safety policies, or audit ledger reads. The example is deliberately minimal.

examples/host-adapter

The "real integration" example. Documents the contract a host application must satisfy to call runtime.executeMessage(...) when the host has a legacy orchestrator integration.

What it shows

  • setHarnessModuleLoader registration.
  • The per-key inventory of capabilities a mature host wires.
  • The R-1 retirement progression (which keys have been absorbed into the substrate as typed config, with RETIRED markers).
  • The metaToolNames typed-config migration as the canonical example of a key moving from loader to runtime config.

Two files in the directory

FilePurpose
index.mjsMinimal no-op adapter that throws a documentation-pointer error for every key. Starting point for a brand-new host.
production-reference.tsFull production-shaped adapter with paths neutralized to @your-app/*. Reference lifted from a real production host.

Running the minimal version

cd examples/host-adapter
npm install
HARNESS_MOCK_MODE=true node index.mjs

The minimal adapter implements just enough keys for first-turn execution to land. Every other key throws a structured documentation-pointer error pointing at the relevant doc section.

Cribbing from production-reference.ts. The reference adapter is a fully-wired host integration. Use it as a template, then: remove every arm marked RETIRED YYYY-MM-DD — those capabilities have moved into the substrate as typed config, and re-wiring them is a regression. Replace @your-app/* import paths with your own host's module structure. Trim arms for capabilities you don't use; the full set is illustrative, and minimum viable is much smaller.

R-1 retirement markers. The reference file marks each retired arm with the substrate commit that absorbed the capability:

// RETIRED 2026-06-02 (R-1.A, commit 8e52b01f2)
// case "orchestrator.streamHelpers":
//   return import("@your-app/streamHelpers");

The comment block is left in place so future hosts cribbing from this file see the migration trail without re-reading the upstream commit log.

Which to start from

SituationStart from
Brand-new project on @pleach/coreminimal-agent
Tutorial or proof of conceptminimal-agent
Existing app, no legacy orchestratorminimal-agent, then add typed config + plugins
Host with a legacy orchestratorhost-adapter/index.mjs, implement keys as you hit them
Mature production integrationhost-adapter/production-reference.ts

Where to go next

On this page