Skip to content
Write an extension

Your first extension

Add one prompt section to every model request.

An extension adds behaviour to an Agent. The smallest useful one adds a named section to the system prompt the model receives on every request. This page builds that, runs it, and shows the prompt the model saw.

The guide is a ladder. Each page adds one idea to the previous page’s code, and by page six you have a complete Bookmarks extension with stored state, a model tool, a command and a client panel.

extension.ts
import { defineExtension } from "@fungi.computer/shiitake/extensions";
/** The smallest extension: one named section in every system prompt. */
export const houseStyle = defineExtension("house-style").define({
prompt: () => [{ name: "voice", text: "Answer in one short sentence." }],
});

defineExtension("house-style") names the extension. .define lists what it contributes; here, one prompt function that returns named sections. Shiitake calls it before each model request, so the text can change between requests.

run.ts
import { echoSystemPrompt, memoryHost } from "@fungi.computer/shiitake/testing";
import { houseStyle } from "./extension.js";
/** Send one prompt to a stand-in model that echoes its system prompt. */
export async function promptSectionRun() {
const host = await memoryHost({
extensions: [houseStyle],
script: [echoSystemPrompt()],
});
try {
await host.agent.session("style").send("Hi", { requestId: "hi" });
return await host.settle("style");
} finally {
await host.close();
}
}

memoryHost is a real Shiitake Agent over an in-memory database, made for tests and examples. Listing the extension adds it to the host and grants it what it asks for, here only prompt. Grants explains why a real host decides that separately.

The script replaces the model. echoSystemPrompt() is a stand-in model that replies with the system prompt it received, so you can see exactly what your extension added. No provider account or API key is involved.

main.ts
import { promptSectionRun } from "./run.js";
const snapshot = await promptSectionRun();
const reply = snapshot.messages.at(-1)?.value;
if (reply?.role === "assistant")
for (const part of reply.content)
if (part.type === "text") console.log(part.text);

Save the three files in an empty folder and run:

TERMINAL
npm init -y
npm pkg set type=module
npm install @fungi.computer/shiitake
npm install --save-dev tsx@4.23.12
node --import tsx main.ts

It prints the system prompt the model received: the test host’s own instructions, then your section, labelled with the extension and section names:

TEXT
Complete this test run.
[extension:house-style.voice]
Answer in one short sentence.

The package’s own tests run this exact code and check that output.

Next: Give the model a tool.