Plugin Lifecycle
Understand Agent plugin registration, unregistration, and when lifecycle.start / lifecycle.stop run
Plugin Lifecycle
Plugins belong to an Agent.
The lifecycle can be simplified to two operations:
- register: the plugin successfully enters
agent.plugins - unregister: the plugin is successfully removed from
agent.plugins
Direct host calls through agent.plugins immediately observe the configured registry. Existing Sessions switch their plugin action and metadata execution view at the next Session step checkpoint. An execution lease keeps the old plugin lifecycle active until the current step and its tool calls finish. If the current Session turn has no later step, the queued view change is applied when the next Session turn starts. A Session fixes its system the first time it is generated, so registry changes do not alter it; newly created Sessions collect plugin system text from the latest registry.
You no longer need a separate start, stop, restart, or project-level enabled switch.
Registration Is Enablement
Plugins passed to the Agent constructor are registered automatically:
import { Agent, Workspace } from "@downcity/agent";
import { PlaywrightBrowserProvider, WebPlugin } from "@downcity/plugins/web";
const agent = new Agent({
id: "agent",
workspace: new Workspace({ path: process.cwd() }),
plugins: [new WebPlugin({
browser: new PlaywrightBrowserProvider({ cdp_url: "http://127.0.0.1:9222" }),
})],
});
await agent.ready();After the Agent is instantiated, you can register more plugins:
await agent.plugins.register(new SkillPlugin());Registering the same plugin name replaces the old instance. The runtime unregisters the old plugin before registering the new one.
Unregistration Is Disablement
await agent.plugins.unregister("skill");After unregistering:
agent.plugins.get("skill")returnsnullagent.plugins.run_action({ plugin: "skill", ... })returns unknown plugin- that plugin's hooks, resolves, and actions no longer participate in future runs; system text already fixed by existing Sessions is not removed retroactively
lifecycle.start / lifecycle.stop
Plugins can still declare lifecycle hooks:
lifecycle.startlifecycle.stoplifecycle.command
But they are no longer a public state machine.
The rules are:
register(plugin)automatically callsplugin.lifecycle?.start(context)unregister(name)removes the plugin from the configured registry immediately;plugin.lifecycle?.stop(context)runs after active Session step leases releaseagent.dispose()unregisters all plugins
Lifecycle is useful for:
- workers
- poll loops
- long-lived connections
- in-memory runtime state
- recoverable runtime engines
Lifecycle command vs action
Use lifecycle.command when the plugin needs a runtime-control command such as:
- reload
- reschedule
- restart
Use actions when the plugin is exposing normal capability work.
task is a good example of a plugin that has both.
Inspecting Registration State
agent.plugins.snapshots();
agent.plugins.status("skill");
agent.plugins.has("skill");States are intentionally small:
readyerror
An unregistered plugin does not need a state because it is no longer in the registry.
ActionSchedule
ActionSchedule is not a plugin.
It is an Agent-level action scheduling loop. Due jobs call actions on currently registered plugins.