tools, services, and plugins
How to inject tools, explicit service instances, and plugin definitions into a local Agent
tools, services, and plugins
tools
A local Agent can receive a tool collection directly:
const agent = new Agent({
id: "repo-helper",
path: "/path/to/project",
tools: {
my_tool: myTool,
},
});Those tools become available during session execution.
If your app needs a long-lived default tool set, agent-level injection is usually the cleanest choice.
services
If you want the local Agent to own services, pass explicit instances:
import { Agent, ChatService } from "@downcity/agent";
const agent = new Agent({
id: "repo-helper",
path: "/path/to/project",
tools: {},
services: [
new ChatService({
telegram: {
botToken: process.env.TELEGRAM_BOT_TOKEN!,
},
}),
],
});When explicit services are useful
- you want the SDK process itself to start chat channels
- you want service lifecycle to be controlled by your application code
You can think of this as: the caller explicitly decides which services are permanent capabilities of this local agent.
If those services implement system(context), the local SDK injects their system text into the session prompt.
plugins
If you want the local Agent to own plugins, pass explicit plugin definitions:
import { Agent, skillPlugin, webPlugin } from "@downcity/agent";
const agent = new Agent({
id: "repo-helper",
path: "/path/to/project",
tools: {},
plugins: [skillPlugin, webPlugin],
});
const plugins = agent.plugins.list();Those plugins are registered into the current Agent's own registry.
That means:
- plugin actions can be called through
agent.plugins.runAction(...) context.pluginsinside services and plugin hooks points to the same registry- duplicate plugin names throw immediately
- the SDK does not register every built-in plugin by default
The local SDK currently wires the plugin registry, AgentContext.plugins, and the registered plugins' system(context) text into the session prompt.
It does not automatically mount plugin.http.runtime onto the SDK HTTP server started by agent.start({ http: { ... } }).
Important boundary
The SDK services field is the set of instances you hand to Agent yourself. It is not a mirror of some automatic project-runtime registry.
The SDK plugins field is also the set of definitions you hand to Agent yourself. It is not a mirror of the global plugin manager.
So do not think of SDK mode as "import everything from the project automatically." It is intentionally explicit assembly.
If you want the next layer of detail:
- which services exist today
- where
ChatServicefits - how to build a custom service
- how plugins attach to a local Agent
continue with: