Downcity
Local Agent

Agent Constructor Options

Detailed explanation of the local Agent id, path, instruction, tools, services, and plugins options

Agent Constructor Options

The local Agent is constructed like this:

new Agent({
  id,
  path,
  model,
  instruction,
  tools,
  services,
  plugins,
})

id

The stable identifier of the agent.

It affects the SDK session storage path:

<projectRoot>/.downcity/agents/<agentId>/...

Recommended properties:

  • stable
  • URL-safe
  • not changed casually

That is because it directly controls the session storage partition.

path

The project root directory bound to the current agent.

The SDK uses it to:

  • load project config
  • organize session storage

If path is wrong, many later behaviors will feel confusing because the agent will read config and write data in the wrong context.

instruction

Static caller-provided instructions for the local SDK Agent.

new Agent({
  id: "repo-helper",
  path: "/path/to/project",
  instruction: [
    "You are a concise code assistant.",
    "Prefer direct file references when explaining code.",
  ],
});

Key points:

  • instruction is static and cache-friendly
  • the SDK does not render dynamic variables inside it
  • the SDK does not read PROFILE.md or SOUL.md by itself
  • if you omit instruction, the SDK uses its minimal core instruction fallback

If a host such as city wants project markdown files to affect the agent, that host should read those files and pass their final text through instruction.

model

The default LanguageModel instance for sessions created under this agent.

new Agent({
  id: "repo-helper",
  path: "/path/to/project",
  model: openai.responses("gpt-5"),
});

Key points:

  • the SDK does not resolve provider or model IDs for you
  • the host must still create the LanguageModel instance first
  • this becomes the default model for session execution
  • session.set({ model }) can still override it for one specific session

tools

The default tool set at the agent level.

Key points:

  • it belongs to the agent, not the session
  • sessions created by this agent reuse the same tool collection

This is a good fit when multiple sessions should share a stable default tool set.

services

This accepts already-instantiated service objects.

For example:

services: [new ChatService(...)]

You do not pass the class itself, and you do not pass a raw config object.

If two services with the same name are registered, the current implementation throws instead of silently overriding one of them.

plugins

This accepts complete plugin definition objects.

For example:

import { Agent, skillPlugin, webPlugin } from "@downcity/agent";

const agent = new Agent({
  id: "repo-helper",
  path: "/path/to/project",
  tools: {},
  plugins: [skillPlugin, webPlugin],
});

The SDK creates an independent plugin registry for the current Agent.

Key points:

  • it does not register every built-in plugin by default
  • it does not reuse the global runtime plugin manager
  • duplicate plugin names throw immediately
  • agent.plugins and AgentContext.plugins use this registry