simpleChatbot
One-line factory over @pleach/core for the minimal conversational agent. No sibling peers — supply your own provider adapter and the recipe handles session lifecycle, conversational state, and stream collection.
simpleChatbot is the smallest recipe in the package. It composes
only @pleach/core and returns a Chatbot wrapper around a real
SessionRuntime. The factory does not bundle a provider — you
register an OrchestratorAdapter ctor once at app boot and the
recipe forwards your orchestratorConfig through.
Best fit: a SaaS adding chat. Reach for this when you want a working chatbot in under ten lines and don't yet need retrieval, observability, or compliance scrubbing.
Quickstart
import { simpleChatbot } from "@pleach/recipes/chatbot";
import { setOrchestratorAdapterCtor } from "@pleach/core/runtime";
import { MyOrchestratorAdapter } from "./my-provider";
// Register the OrchestratorAdapter ctor once at app boot.
setOrchestratorAdapterCtor(MyOrchestratorAdapter);
const bot = simpleChatbot({
systemPrompt: "You are a helpful assistant.",
orchestratorConfig: {
provider: "openai",
model: "gpt-4o-mini",
apiKey: process.env.OPENAI_API_KEY!,
},
});
console.log(await bot.ask("hello"));
console.log(await bot.ask("what did I just say?"));A single bot instance holds the session across ask() calls,
so the second turn sees the first turn's history. Call
await bot.reset() (or its alias await bot.newSession()) to
discard the memoized session id; the next ask() lazily
creates a fresh one.
What it does
The factory constructs a SessionRuntime via
createPleachRuntime(...) and stores the
orchestratorConfig on host.strategies.orchestratorConfig.
On the first ask(), the runtime walks the registered adapter
ctor and binds your provider. Each subsequent ask() reuses
the same session id, so conversation state accumulates in the
underlying event log.
ask() returns the final assistant text. It collects the
message.delta and message.complete events from
runtime.executeMessage() and concatenates the deltas.
Streaming consumers should reach into bot.runtime directly.
Config reference
interface SimpleChatbotConfig {
/** Optional system prompt prepended to every conversation. */
systemPrompt?: string;
/**
* Provider/orchestrator config forwarded to the underlying
* SessionRuntime. Wires the LLM provider (model id, API key,
* etc.). When omitted, ask() returns the substrate placeholder.
*/
orchestratorConfig?: Record<string, unknown>;
// Plus the standard CreatePleachRuntimeConfig fields
// (host, plugins, storage, etc.) from @pleach/core.
}
interface Chatbot {
readonly runtime: SessionRuntime;
ask(message: string): Promise<string>;
newSession(): Promise<void>;
reset(): Promise<void>;
}Common gotchas
setOrchestratorAdapterCtorruns once per process. It registers a module-level ctor inside@pleach/core/runtime. Call it at app boot, before anysimpleChatbot({orchestratorConfig: ...}). Calling it again with a different ctor is a no-op after the first registration in v0.2.- Without
orchestratorConfig,ask()returns a placeholder. The string is"This is a placeholder response from the harness runtime."This is the documented no-provider contract — useful for shape tests, not for production. ChatStreamErrorcarries the original failure on.cause. If the stream emits{type: "error"}or throws,ask()rejects withChatStreamError. Branch onerror.causeto distinguish provider errors from abort signals from network timeouts.- Subpath import is load-bearing. Import from
@pleach/recipes/chatbot, not the root barrel. The factory referencescreatePleachRuntimefrom@pleach/core/runtime(the subpath the setter is also registered against). The top-level@pleach/coreESM bundle does not currently re-export the setter.
See also
@pleach/recipesoverview — every recipe in one page.SessionRuntime— the substrate every recipe wraps.Adoption paths— when to reach forsimpleChatbotvs constructSessionRuntimedirectly.
Platform & operations recipes
End-to-end implementations for the platform-team patterns — long-running jobs, multi-step interrupts, per-call cost reporting, and OpenTelemetry wiring.
ragChatbot
Chatbot plus a retrieval stage. You supply the Retriever — the recipe is storage-agnostic on purpose. Per turn, top-K chunks are spliced into the prompt as numbered context before delegating to simpleChatbot.