Skip to content

Subsystems & Boot Tasks

A Subsystem is a modular component that packages related tools, approval rules, mode instructions, and startup setup tasks into a single unit.

import type { ToolSet } from "ai";
export type AgentMode = "plan" | "act";
export interface SetupContextContract {
signal: AbortSignal;
emitProgress(stage: string, detail?: string): void;
}
export interface SetupTaskContract {
id: string;
name: string;
description: string;
required: boolean;
run(ctx: SetupContextContract): Promise<void>;
onProgress?(stage: string, detail?: string): void;
}
export interface Subsystem {
readonly id: string;
readonly name: string;
registerTools?(): ToolSet;
registerApprovals?(): Record<string, "user-approval">;
registerSetupTasks?(): SetupTaskContract[];
getInstructions?(mode: AgentMode): string | null;
dispose?(): Promise<void>;
}

Boot setup tasks run during application launch (before entering the interactive chat UI). They allow plugins to verify required system binaries, validate credentials, or check service health:

export const redisSubsystem: Subsystem = {
id: "com.myorg.redis",
name: "Redis Cache Subsystem",
registerSetupTasks() {
return [
{
id: "redis:ping",
name: "Redis Server Health Check",
description: "Checks if local Redis instance is responding to PING",
required: false, // Set true if session must not start without this check passing
async run(ctx) {
ctx.emitProgress("Pinging Redis at localhost:6379...");
const response = await pingRedis({ signal: ctx.signal });
if (response !== "PONG") {
throw new Error("Redis failed to respond to PING.");
}
ctx.emitProgress("Redis online and healthy.");
},
},
];
},
};

Plugins can inject contextual guidance into the model’s system prompt based on whether Agento is operating in Plan Mode or Act Mode:

getInstructions(mode: "plan" | "act"): string | null {
if (mode === "plan") {
return "API DESIGN RULES: You are in Plan Mode. Draft API contracts in the plan before writing routes.";
}
return "API DESIGN RULES: You are in Act Mode. Ensure all new endpoints include rate limiting middleware.";
}

When an Agento session closes or resets, Agento calls dispose() on all active subsystems to ensure clean teardown of network sockets, background workers, or child processes:

async dispose(): Promise<void> {
await dbPool.end();
await redisClient.quit();
}