YAML Reference

Every project field in one place

Suzumio projects are YAML files. The resolved YAML defines the task, agents, tool registration, scheduler policy, Docker runner, model presets, channels, and local observability defaults.

Resolution Pipeline

suzumio config render path/to/project.yaml prints the same resolved config that suzumio init stores as resolved.yaml.

text
source YAML
  -> quote bare @import(...) markers
  -> substitute environment placeholders in text
  -> parse YAML
  -> resolve whole-field imports recursively
  -> apply extends profiles
  -> apply defaults and validate
  -> write resolved.yaml and SQLite project config

The resolved config is runtime source material. Editing the original YAML after initialization does not mutate an already initialized project until it is rendered and initialized again.

Minimal Shape

yaml
name: demo
task: |
  Demonstrate one non-preemptive activation.

backend:
  runner:
    mode: ai
    model: main
    models:
      providers:
        gateway:
          type: openai-compatible
          baseURLEnv: SUZUMIO_GATEWAY_BASE_URL
          apiKeyEnv: SUZUMIO_GATEWAY_API_KEY
      presets:
        main:
          provider: gateway
          model: gpt-5.5

tools:
  toolpacks:
    - core

agents:
  pm:
    role: project-manager
    displayName: Yuki
    prompt: |
      Handle the user request and stay concise.
    tools:
      - messages.send
      - coordination.wait_for_signal
      - completion.submit

Top-Level Fields

FieldRequiredDefaultDescription
nameYesNoneProject id and runtime directory name under SUZUMIO_ROOT.
taskYesNoneDurable task statement rendered into the first activation prompt and preserved through agent history.
agentsYesNoneMap of agent ids to agent configs. At least one agent is required.
toolsNotoolpacks: [core, web]Project toolpack registration. Agent configs still need per-agent tool allowlists.
platformsNoEmpty listOptional external chat platform bridges such as Feishu.
schedulerNoSignal scheduler defaultsSignal delivery, nudges, and quiet monitor settings.
communicationNoCoordinator pm, no coordinator-only restrictionPrompt-level communication policy rendered into activation prompts.
backendNoDocker chat runner defaultsDocker image, controller URL, mounts, proxy, AI runner, and model registry.
channelsNo#project, #blockedAllowed channel names for channel messages.
extendsNoNoneProfile object or list of profile objects merged before local fields.
observabilityNoHTTP/WebUI enabled on 127.0.0.1:39400Documentation-level server defaults. CLI flags still control the actual bind address.

name And task

yaml
name: theorem-search
task: |
  Produce a concise report.
  Separate proven facts, experiments, failed attempts, and remaining gaps.

name becomes the project id in CLI commands and the directory name under SUZUMIO_ROOT. task is rendered into the first activation prompt for each agent.

agents

yaml
agents:
  pm:
    role: project-manager
    displayName: Yuki
    prompt: @import(prompts/pm.md)
    model: pm-main
    tools:
      - messages.send
      - coordination.wait_for_signal
      - completion.submit

  worker:
    role: researcher
    count: 2
    names: [Akari, Ren]
    prompt: @import(prompts/worker.md)
    model: worker-main
    tools:
      - messages.send
      - coordination.wait_for_signal
      - shell.exec
    mounts:
      - source: ./reference
        target: /mnt/reference
        readonly: true
    env:
      EXPERIMENT_MODE: quick
FieldDefaultDescription
roleAgent idHuman-readable role stored with the agent.
displayNameAgent idHuman-readable display name.
namesNoneOptional names for counted agents, assigned by index.
countNoneExpands one config entry into numbered agents such as worker-1 and worker-2.
promptEmpty stringAgent instructions included in every activation prompt.
modelbackend.runner.modelModel preset for this agent.
toolsEmpty listPer-agent model-visible tool allowlist. Supports exact names, namespace.*, and *.
mountsEmpty listHost files or directories mounted only for this agent.
envEmpty mapExtra environment variables for this agent's runner containers.

Counted agents use generated ids. The example above creates worker-1 and worker-2; their configured display names are Akari and Ren.

tools

yaml
tools:
  toolpacks:
    - core
    - shell
    - web
    - path: ./toolpacks/scheduler
      id: scheduler
    - path: ./toolpacks/plan
      id: plan
    - path: ./toolpacks/review
      id: review-tools
EntryRegistered tools
coremessages.send, coordination.wait_for_signal, completion.submit, file.read, file.write, file.patch
shellshell.exec
webweb.fetch
Local toolpacks/schedulerschedule.once, schedule.recurring, schedule.list, schedule.cancel, plus scheduled-message WebUI controls and a scheduler hook.
Local toolpacks/planplan.create, plan.status, plan.update, plan.set_item_status, plan.close, plus active-plan WebUI controls and a continuation scheduler hook.
Local { path, id }Model-facing tools and optional WebUI entries declared by suzumio.toolpack.json in that directory.

tools.toolpacks registers definitions for the project. agents.<id>.tools allowlists which registered tools a model can see. Built-in file tools can be granted with file.* or exact names such as file.read and file.patch. Toolpack WebUI entries are user-facing controls and do not use the per-agent model allowlist.

Custom toolpack details live in Custom Tools.

platforms

yaml
platforms:
  - id: feishu-main
    kind: feishu
    appIdEnv: FEISHU_APP_ID
    appSecretEnv: FEISHU_APP_SECRET
    inbound:
      recipient: pm
      priority: P2
      allowedChatTypes: [group]
      groupMessageMode: bot_mentions
      reactionAck:
        enabled: true
        emojiType: Typing
    outbound:
      recipient: user
      replyToLastInbound: true

Platforms are optional bridges between Suzumio messages and external chat systems. suzumio serve starts enabled platforms by default; use suzumio serve --no-platforms to run the local HTTP/WebUI server without external connections.

The Feishu platform uses the Feishu Node SDK persistent connection to receive im.message.receive_v1 events. By default, only group messages that mention the current bot become Suzumio messages from sender to inbound.recipient; private p2p messages and ordinary group messages are ignored. Before handing an accepted message to Suzumio, the bridge adds a Typing reaction to the Feishu message as a best-effort acknowledgement. Suzumio messages whose recipient equals outbound.recipient are sent back to Feishu, preferably as replies to the latest inbound Feishu message for that project/platform.

FieldDefaultDescription
idRequiredPlatform id used in audit events and dedupe.
kindRequiredCurrently only feishu.
enabledtrueEnables the bridge when suzumio serve starts.
appId / appIdEnvFEISHU_APP_ID envFeishu app id. Prefer appIdEnv for secrets hygiene.
appSecret / appSecretEnvFEISHU_APP_SECRET envFeishu app secret. Prefer appSecretEnv.
inbound.enabledtrueReceives Feishu events through persistent connection.
inbound.recipientpmSuzumio agent that receives external user messages.
inbound.priorityP2Priority for created Suzumio messages.
inbound.senderuserSuzumio sender id for external messages.
inbound.includeMetadatatrueAppends Feishu ids to the message body for traceability.
inbound.allowedChatTypes[group]Feishu chat types accepted inbound. Add p2p only if private messages should enter Suzumio.
inbound.groupMessageModebot_mentionsFor group chats, accept only messages that mention this bot. Set all only if ordinary group messages should enter Suzumio.
inbound.botOpenId / botOpenIdEnvFEISHU_BOT_OPEN_ID env, then auto lookupBot open_id used to verify group mentions. When unset, the bridge fetches /open-apis/bot/v3/info.
inbound.reactionAck.enabledtrueAdds a reaction to accepted inbound Feishu messages before waking the PM. Reaction failures are audited but do not block PM handling.
inbound.reactionAck.emojiTypeTypingFeishu reaction emoji_type used for inbound acknowledgement. Values are case-sensitive.
outbound.enabledtruePolls Suzumio events and sends messages to Feishu.
outbound.recipientuserSuzumio recipient treated as external user-facing output.
outbound.replyToLastInboundtrueReply to the latest inbound Feishu message when possible.
outbound.defaultReceiveId / defaultReceiveIdEnvNoneOptional fallback receive id when no inbound route is known.
outbound.defaultReceiveIdTypechat_idFeishu id type for the fallback route.
outbound.pollIntervalMs2000Poll interval for new Suzumio user-facing messages.

Feishu setup requirements: create an enterprise self-built app, enable Bot capability, configure Receive events through persistent connection, subscribe to im.message.receive_v1, add message send and receive scopes, publish a version, and add the bot to the target chat. For group messages, im:message.group_at_msg:readonly receives @mentions; im:message.group_msg:readonly receives all messages in associated group chats when approved. The default reaction acknowledgement needs either im:message or im:message.reactions:write_only. Suzumio still applies inbound.allowedChatTypes and inbound.groupMessageMode before creating local messages.

scheduler

yaml
scheduler:
  kind: nonpreemptive-signals
  maxSignalsPerActivation: 20
  noEffectNudge:
    enabled: true
    priority: P2
    maxConsecutive: 0
    initialDelayMs: 30000
    backoffFactor: 2
    maxDelayMs: 300000
  failedNudge:
    enabled: false
    priority: P2
    maxConsecutive: 3
    initialDelayMs: 60000
    backoffFactor: 2
    maxDelayMs: 900000
  allQuietNudge:
    enabled: false
    targetAgent: pm
    priority: P2
    cooldownMs: 300000
  quietAgentMonitor:
    enabled: true
    rules:
      - id: worker-watch
        agent: worker-1
        recipient: pm
        sender: monitor
        priority: P2
        initialDelayMs: 1800000
        repeatDelayMs: 900000
        message: "{{agent}} has been quiet for {{quietMinutes}} minutes."
  failedAgentMonitor:
    enabled: true
    rules:
      - id: worker-failed-watch
        agent: worker-1
        recipient: pm
        sender: monitor
        priority: P2
        initialDelayMs: 300000
        repeatDelayMs: 900000
        message: "{{agent}} has been failed for {{failedMinutes}} minutes after {{activationId}}."
FieldDefaultDescription
kindnonpreemptive-signalsSignal-driven scheduler. nonpreemptive-mailbox is accepted as an alias.
maxSignalsPerActivation20Maximum pending signals included at activation start.
noEffectNudge.enabledtrueCreates a follow-up nudge when an activation completes with no useful effect.
noEffectNudge.priorityP2Priority for no-effect nudge signals.
noEffectNudge.maxConsecutive0Maximum consecutive nudges after no-effect activations. 0 means no limit.
noEffectNudge.initialDelayMs30000Initial nudge delay.
noEffectNudge.backoffFactor2Exponential backoff multiplier.
noEffectNudge.maxDelayMs300000Maximum nudge delay.
failedNudge.enabledfalseCreates a delayed self-directed retry signal when an agent remains failed with no pending signal.
failedNudge.priorityP2Priority for failed retry signals.
failedNudge.maxConsecutive3Maximum consecutive automatic retries after failed activations. 0 means no limit.
failedNudge.initialDelayMs60000Delay before the first failed retry signal.
failedNudge.backoffFactor2Exponential backoff multiplier for later failed retry signals.
failedNudge.maxDelayMs900000Maximum failed retry delay.
failedNudge.messageBuilt-in textNudge body rendered to the failed agent.
allQuietNudge.enabledfalseCreates a scheduler signal when all agents are quiet and no pending signals exist.
allQuietNudge.targetAgentpmAgent that receives the all-quiet nudge.
allQuietNudge.priorityP2Priority for all-quiet nudge signals.
allQuietNudge.cooldownMs300000Minimum time between all-quiet nudges.
allQuietNudge.messageBuilt-in textNudge body rendered into the scheduler signal.
quietAgentMonitor.enabledfalseEnables quiet-agent monitor rules.
quietAgentMonitor.rulesEmpty listList of quiet-agent monitor rules.
failedAgentMonitor.enabledfalseEnables failed-agent monitor rules.
failedAgentMonitor.rulesEmpty listList of failed-agent monitor rules.

Priorities are P0, P1, P2, and P3. P2 is intended for control-flow or continuation signals that should run before routine backlog. Routine queued messages default to P3.

Quiet-agent monitor rule fields:

FieldDefaultDescription
idDerived from index, agent, sender, recipientStable rule key for dedupe.
enabledtrueEnables this rule.
agentRequiredAgent id to monitor while it is quiet.
recipientpmMessage recipient. Must be user or an existing agent.
sendermonitorVirtual message sender. No real sender agent is created.
priorityP2Message priority.
initialDelayMs1800000Quiet duration before the first message.
repeatDelayMs900000Repeat interval while the same quiet state continues.
messageBuilt-in textTemplate body for the monitor message.

Monitor templates support , , , , , , , , , , , and .

Failed-agent monitor rules use the same fields, but trigger while the agent is failed. Their templates also support , , , , and .

communication

yaml
communication:
  coordinatorAgent: pm
  restrictNonCoordinatorToCoordinator: true
  nonCoordinatorMaxPriority: P2
  pmRoutineVerifierPriority: P3
FieldDefaultDescription
coordinatorAgentpmAgent treated as the coordinator in rendered prompts.
restrictNonCoordinatorToCoordinatorfalsePrompt contract that directs non-coordinators to message only the coordinator.
nonCoordinatorMaxPriorityP2Prompt-level max priority for non-coordinator routine messages.
pmRoutineVerifierPriorityP3Prompt-level default for routine PM review/delegation messages.

This section shapes activation instructions. Tool authorization still comes from agents.<id>.tools.

backend

yaml
backend:
  kind: docker-chat
  image: suzumio-runner:dev
  controllerUrl: http://host.docker.internal:39400
  docker:
    network: bridge
    proxy:
      inheritEnv: true
      rewriteLocalhost: true
      https: ${HTTPS_PROXY}
      http: ${HTTP_PROXY}
      all: ${ALL_PROXY}
      noProxy: ${NO_PROXY}
    mounts:
      - source: ./reference
        target: /mnt/reference
        readonly: true
        description: Project reference material.
  runner:
    mode: ai
    model: worker-main
FieldDefaultDescription
kinddocker-chatCurrent backend implementation.
imagesuzumio-runner:devDocker image used for activation containers.
controllerUrlhttp://host.docker.internal:39400URL used by containers to call Suzumio support routes and submit output.
docker.networkNoneDocker network mode. Linux host networking uses host.
docker.mountsEmpty listHost files or directories mounted into every activation container.
docker.proxyInherit env, rewrite localhostProxy config passed into runner containers.
runnermode: aiAI runner config.

Mount fields:

FieldDefaultDescription
sourceRequiredHost path. Relative paths resolve against the top-level project YAML during render.
targetRequiredContainer path. Use non-reserved paths such as /mnt/reference.
readonlytrueMount access.
descriptionNoneText included in activation prompts.

Proxy fields are inheritEnv, http, https, all, noProxy, and rewriteLocalhost. With bridge networking, loopback proxy hosts are rewritten to host.docker.internal when rewriteLocalhost is true. With network: host, host-loopback proxy URLs remain reachable directly from the container.

backend.runner And Models

yaml
backend:
  runner:
    mode: ai
    model: worker-with-fallback
    maxIterations: 20
    maxToolCalls: 80
    models:
      providers:
        gateway:
          type: openai-compatible
          baseURLEnv: SUZUMIO_GATEWAY_BASE_URL
          apiKeyEnv: SUZUMIO_GATEWAY_API_KEY
          timeoutMs: 300000
          chunkTimeoutMs: 60000
          headers: {}
          options: {}
      presets:
        worker-main:
          provider: gateway
          model: gpt-5.5
          apiModel: gpt-5.5
          reasoningEffort: high
          temperature: 0.2
          topP: 1
          maxOutputTokens: 8000
          contextLimit: 260000
          toolChoice: auto
        worker-with-fallback:
          model-list:
            - worker-main
            - backup-main

Runner fields:

FieldDefaultDescription
modeaiOnly ai is supported.
modelNoneProject-level model preset name. Agents can override with agents.<id>.model.
maxIterationsProvider/runtime defaultOptional cap on model loop iterations.
maxToolCallsProvider/runtime defaultOptional cap on tool calls in one activation.
models.providersEmpty mapProvider registry.
models.presetsEmpty mapNamed model presets and fallback lists.

Provider fields:

FieldDefaultDescription
typeRequiredopenai, anthropic, google, or openai-compatible.
apiKeyNoneInline API key. Kept out of committed examples.
apiKeyEnvNoneEnvironment variable name for API key.
baseURLNoneInline provider base URL. Kept out of committed examples when private.
baseURLEnvNoneEnvironment variable name for provider base URL.
headers{}Extra provider headers.
timeoutMsProvider defaultTotal request timeout, or false.
chunkTimeoutMsProvider defaultStreaming chunk timeout.
options{}Provider-specific options.

Preset fields:

FieldDefaultDescription
providerRequired for concrete presetProvider registry key.
modelRequired for concrete presetLocal and provider-facing model id unless apiModel is set.
apiModelNoneProvider-facing model id when different from local preset model.
model-listNoneOrdered fallback list. Cannot be combined with concrete provider/model fields.
reasoningEffortNoneProvider-facing reasoning effort.
temperatureNoneProvider-facing temperature.
topPNoneProvider-facing top-p.
topKNoneProvider-facing top-k.
maxOutputTokensNoneProvider-facing output token cap.
contextLimit260000Metadata for context overflow handling.
toolChoiceNoneauto, required, or none.
providerOptions{}Preset-level provider-specific options.
headers{}Preset-level headers.

Committed examples use baseURLEnv and apiKeyEnv. Real provider endpoints and keys stay in environment variables.

channels

yaml
channels:
  - "#project"
  - "#blocked"
  - "#reviews"

Channel messages to undeclared channels fail. Defaults are #project and #blocked.

observability

yaml
observability:
  http:
    enabled: true
    host: 127.0.0.1
    port: 39400
  webui:
    enabled: true

These values document intended server defaults in YAML. The suzumio serve command flags control the actual bind address and port for a running process.

YAML Conventions

PatternTypical valueExample
Block scalarMulti-line task and prompt text.`task:
Quoted stringsChannel names and punctuation-heavy strings."#project"
ArraysTools, channels, profiles.- messages.send
MapsAgents, providers, presets, Docker options.agents: { ... }

Whole-Field Imports

A field whose entire value is @import(path) is replaced by the imported file. The import marker must occupy the whole field value.

yaml
task: @import(tasks/main.md)
agents:
  pm: @import(agents/pm.yaml)
  worker:
    prompt: @import(prompts/worker.md)
Imported fileResolution
.yaml or .ymlParsed as YAML, then imports inside it are resolved.
.jsonParsed as JSON, then imports inside it are resolved.
Other extensionImported as raw UTF-8 text.

Import paths are resolved relative to the file containing the import. HTTP imports are rejected. Import loops and excessive import depth are rejected.

extends And Merge Rules

yaml
extends:
  - @import(profiles/base.yaml)
  - @import(profiles/ai.yaml)

name: theorem-project
task: @import(tasks/theorem.md)

Each extends entry resolves to an object. Suzumio merges profile objects from first to last, then merges the local file on top.

Merge caseBehavior
Object into objectDeep-merged recursively.
Array into arrayLater array replaces earlier array.
Scalar into any valueLater scalar replaces earlier value.
Local file vs profileLocal file wins.

Validation Workflow

bash
suzumio config render path/to/project.yaml
suzumio init path/to/project.yaml
suzumio status project-name

The rendered output shows defaults, imports, array replacement, inherited model settings, provider endpoint/key environment-variable names, and normalized local toolpack paths.