Declarative Agents
Define your agent in YAML instead of code, and switch the active agent at runtime
from the web app -- no code change and no restart. ChatWalaʻau uses the Microsoft Agent
Framework declarative format (agent-framework-declarative,
AgentFactory.create_agent_from_yaml / create_agent_from_yaml_path).
The important rule: the YAML is a specification, and ChatWalaʻau owns construction. A
field that ChatWalaʻau cannot map is ignored with a warning; a field that conflicts with the
product's design (for example temperature) is rejected when you try to activate the agent.
100% compatibility with the Microsoft schema is intentionally not a goal.
What you get
- A built-in CORE agent. The default ChatWalaʻau agent is registered as the CORE agent and is active out of the box -- it reproduces the standard behavior exactly. You never have to configure anything to keep using ChatWalaʻau as before.
- Custom agents from a folder. Point
DECLARATIVE_AGENTS_DIRat a folder of YAML files (nested folders allowed) and each one becomes a selectable agent. - One active agent, switched from the web app. A management modal (the sidebar-footer robot icon, next to the File Explorer icon) lists the CORE agent plus your custom agents as a folder tree. Pick one and activate it; ChatWalaʻau rebuilds the agents and shows a "rebuilding" indicator until the switch is complete.
- Compose agents in a GUI -- no hand-written YAML. A Create button (and per-agent Edit / Delete) in the Declarative Agents modal opens a full-screen editor: form panels for the name, description, and instructions; a visual canvas for attaching a model and tools; and a live YAML preview you can also edit directly. Saving writes the YAML for you and registers the agent immediately.
- Per-agent tools. An agent can carry its own tool surface -- pick exactly the built-in tools, MCP servers/tools, and Skills it should have, and it runs with only those. Leave it out and the agent inherits every enabled tool, exactly as before.
- Mistakes are visible. A YAML that fails to map is flagged in the list with its error and cannot be activated.
Turn it on
# .env
DECLARATIVE_AGENTS_DIR=.agents
Create the folder and drop one or more YAML files in it (nested folders are fine):
.agents/
pirate.yaml
support/
triage.yaml
The CORE agent is always present even when DECLARATIVE_AGENTS_DIR is unset.
A ChatWalaʻau-compatible sample
This sample exercises every supported field. It maps cleanly with no warnings, so
it activates as-is on a default deployment (it pins gpt-5.5).
kind: Prompt # required by the declarative schema
name: Support Triage Assistant # shown in the Declarative Agents manager
displayName: Support Triage # optional; used as the name if `name` is absent
description: >- # shown in the manager detail pane
Triages an incoming support question and returns a structured summary.
# Persona -> Identity (the first block of the system prompt). Use the literal
# "=Identity" (or omit `instructions`) to keep the global .agent/IDENTITY.md persona
# instead of overriding it.
instructions: >-
You are a concise customer-support triage assistant. Classify the request,
summarize it, and recommend the next action. Be brief and practical.
model:
# Preferred default model. It MUST be one of your configured models
# (AZURE_OPENAI_MODELS / ANTHROPIC_MODELS) or activation is blocked. The other
# configured models stay selectable. Omit `id` to use the deployment default.
id: gpt-5.5
options:
# Only reasoning effort and (gpt-5.x) text verbosity are supported.
# effort: low | medium | high | xhigh | max
# verbosity: low | medium | high
effort: high
verbosity: medium
# Optional. Restrict this agent to a SUBSET of the available tools. Omit the whole
# block to inherit every enabled tool. Each entry references a tool that already
# exists -- you can never introduce a new tool here. An unrecognized name is a
# warning that blocks activation.
tools:
- kind: function # a built-in tool, by name
name: rag_search
- kind: mcp # a whole MCP server...
name: microsoft_learn
allowedTools: # ...or just some of its tools
- microsoft_docs_search
- kind: skill # an Agent Skill, by name
name: pptx
# Optional. Constrain every answer to this JSON shape by DEFAULT (you can still turn
# structured output off, or edit the schema, per message in the chat). Remove this
# whole block for a normal conversational agent. Under strict JSON mode every listed
# property is required and no extra properties are allowed.
outputSchema:
properties:
category:
type: string
required: true
description: One of billing, technical, account, other.
summary:
type: string
required: true
description: A one-sentence summary of the request.
next_action:
type: string
required: true
description: The recommended next step for the support team.
Save it, open the Declarative Agents modal (the robot icon in the sidebar footer), select the agent, and click Activate. The model picker, the reasoning-effort / verbosity controls, and the JSON-schema editor all update to reflect the agent.
Compose an agent visually
Prefer not to write YAML? When DECLARATIVE_AGENTS_DIR points at a writable folder, the
Declarative Agents modal shows a Create button (and Edit / Delete on each of your
custom agents). It opens a full-screen editor with three panels:
- Left -- the basics. Name, description, and the instructions (persona).
- Center -- the canvas. A node for the agent with a toolbar to pick the model (and its reasoning effort / verbosity, straight from your configured models) and to add tools from a searchable list of every built-in tool, MCP server/tool, and Skill. Each attached tool shows as a connected node you can remove.
- Right -- the YAML. A live, canonical preview of exactly what will be saved. Flip Edit raw YAML to hand-edit it instead; validation runs continuously and shows any warnings inline.
Model selection is driven by your configured models -- the editor never asks for a provider, endpoint, or credentials, because ChatWalaʻau resolves those itself. Save writes the YAML and the new agent appears in the list right away, ready to activate.
What maps, what is ignored, what is rejected
| YAML field | ChatWalaʻau behavior |
|---|---|
instructions | Becomes the agent persona (the first block of the system prompt). Use "=Identity" or omit it to keep your global .agent/IDENTITY.md. |
model.id | Sets the agent's preferred default model. The other configured models stay selectable (the model picker does not disappear); a model you have not configured is ignored with a warning. |
model.options.effort | Maps to the reasoning effort. |
model.options.verbosity | Maps to text verbosity (gpt-5.x). |
tools | Restricts the agent to a subset of the available tools (kind: function / mcp / skill). Omit it to inherit every enabled tool. An unrecognized name is a warning that blocks activation; it can never add a tool that does not already exist. |
outputSchema | Becomes the default structured-output schema; you can still override it per message. |
model.connection, credentials, =Env.* | Ignored (a warning is shown). ChatWalaʻau resolves credentials and endpoints itself; they never come from the YAML. |
temperature, top_p, top_k, seed, ... | Rejected at activation. The supported models (Azure gpt-5.5 / gpt-5.4, Anthropic Opus 4.7 / 4.8) are reasoning-only and do not accept classic sampling parameters. |
an invalid effort / verbosity value | A warning is shown (and activation is blocked) so the typo is fixed rather than silently ignored. |
| anything else | Ignored with a warning. |
Warnings block activation
An agent that maps with any warning cannot be activated until you fix the YAML. The
manager flags the agent, lists the warnings, and disables the Activate button. This keeps
the active agent a clean, fully-supported definition. Things that produce a warning:
ignored model.connection / credentials, an unknown model.options key, an invalid
effort / verbosity value, or a model.id that is not one of your configured models.
A malformed YAML or a rejected sampling parameter (e.g. temperature) is a hard error.
Good to know
- The agent's options apply as defaults. The agent's reasoning effort, verbosity, and output schema take effect when you switch to it, and the chat's model picker and options panel update to reflect them. You can still override any of them per message; the agent's value is used wherever you have not explicitly changed the panel.
- Switching is web-app only. The OpenAI-compatible API and Microsoft Teams always use whichever agent is currently active -- they follow your selection, they do not switch it.
- The selection is not saved across restarts. A restart re-activates the CORE agent. This keeps a switch easy to undo and avoids surprising a fresh process.
- A switch affects everyone. Activation is process-wide, like the MCP and Skills managers.
- The active agent is logged. ChatWalaʻau prints one line naming the active agent at startup and on every switch, so you can confirm which YAML is in effect.