Downcity
Plugins

Plugin Overview

Understand what plugins are in Downcity, how they differ from services, and what they are responsible for in the runtime

Plugin Overview

In Downcity, a plugin is closer to an extension layer or enhancement layer.

You can think of it as a package that can:

  • add explicit actions
  • register hooks or resolve points into the runtime
  • provide system text
  • expose setup and usage protocols to Console
  • inject runtime HTTP routes when needed

One-sentence mental model

  • a service is closer to a long-lived runtime instance
  • a plugin is closer to an extension package and capability layer

How plugins attach in the local SDK

The local Agent now supports explicit plugin registration:

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();

The important part is:

  • plugins is a registry owned by this specific Agent
  • the SDK does not auto-register every built-in plugin
  • you can use agent.plugins.list(), availability(), and runAction() directly
  • context.plugins inside services and plugin hooks points to the same registry

What plugins are good for

Plugins are especially good for:

  • adding explicit commands and actions for one domain
  • inserting logic into existing runtime chains
  • providing system prompt augmentation
  • exposing setup or usage protocols to UI
  • injecting runtime HTTP routes

What plugins are not

Plugins should not automatically be treated as:

  • a long-lived background instance
  • a synonym for a service
  • a project-local lifecycle pool of stateful runtime objects

If you really need:

  • a queue worker
  • a shell session pool
  • long-lived connections
  • cron runtime

you should usually think about a service first.

The main pieces a plugin can include

A full plugin may contain:

  • config
  • actions
  • setup
  • usage
  • hooks
  • resolves
  • system
  • availability
  • http

Not every plugin needs all of them.

Plugin enablement is not the same as project config

This distinction is important.

Enablement

Whether a plugin is enabled is currently a city-level fact.

That means:

  • plugin enable or disable is not primarily a downcity.json concern
  • static catalog views read city-level lifecycle state first

Project-side config

Runtime options for how an agent uses a plugin can still live under:

  • downcity.json.plugins.*

So keep these two layers separate:

  • city-level: is the plugin enabled at all
  • project-level: how does this agent use it

In the SDK, there is one more layer to keep in mind:

  • agent-level: which plugin definitions did this local Agent register

In practice, a plugin usually becomes active only when:

  • you registered it into the current Agent
  • it was not explicitly disabled in the city-level lifecycle config
  • its own availability() check still reports usable

auth is a special plugin

auth is currently a built-in required plugin.

It does not behave like a normal optional enable-or-disable plugin.

Current built-in plugins

The built-in plugin set currently includes:

  • auth
  • skill
  • web
  • asr
  • tts
  • workboard
  1. Which built-in plugins exist today
  2. Plugin configuration
  3. Plugin actions
  4. Plugin hooks
  5. Custom plugin