Author a Chat Template
Chat templates pin the system prompt, the allowed tool set, and the approval cadence for a specific procedure. This walkthrough takes you from a blank page to a working, version-controlled template callable from any chat in your project. Expected time: 15 minutes.
Prerequisites
- An API key with the
managementscope. - A working
xeroctlinstall on your workstation (runxeroctl --versionto confirm). - At least one operational workspace in the project,
identified by its external id (
ws_<hex>). - Familiarity with workspaces and approvals.
Scenario
Your team drains Kubernetes nodes for maintenance a couple of times a week. The procedure is repetitive: cordon the node, drain gracefully with a short grace period, verify no stuck pods, then proceed to maintenance. We will encode this procedure as a chat template so the next operator runs it with a consistent system prompt and an approval gate.
Step 1: Draft the Template
Create a file drain-node.json on your
workstation.
{
"name": "drain-kubernetes-node",
"scope": "project",
"system_prompt": "You are a Kubernetes operator. When asked to drain a node, cordon it first, drain with grace-period 60, verify no stuck pods, and stop. If the drain fails, do not retry without human input.",
"allowed_tools": [
"k8s_get_nodes",
"k8s_describe_pod",
"k8s_cordon_node",
"k8s_drain_node"
],
"approval_policy": "elevated",
"metadata": {
"description": "Safely drain a node for maintenance",
"tags": ["kubernetes", "node-maintenance"]
}
}
- The system prompt is imperative and bounded: it states what to do, in what order, and what to refuse.
- The
allowed_toolslist is the full set of tools the model may call during a session bound to this template, nothing else. Tool names must match the platform registry exactly (the Kubernetes tool family uses thek8s_*prefix; see the Kubernetes tools reference for the full list). - The
approval_policyiselevated: destructive operations (such ask8s_drain_node) require human approval before dispatch. - The
scopefield in the file is informational only. The effective scope is decided by the upload route: if you pass--workspacetoxeroctl templates createthe template is workspace-scoped, otherwise it is project-scoped. When the two disagree the route wins and the CLI prints a note.
Step 2: Upload the Template
xeroctl templates create --file drain-node.json
Transcript on success:
template drain-kubernetes-node created
version: 1
scope: project
id: tmpl_01HX...
The CLI returns the template ID and the version. Every edit creates a new version; the ID is stable.
Step 3: Test Against a Chat
Apply the template to a new chat:
xeroctl chat new --workspace ws_01HXXXXXXXXXXXXXXXXXXXXXXX \
--template drain-kubernetes-node \
--message "Drain node worker-07 for maintenance"
The --workspace flag takes the workspace
external id (ws_<hex>); a workspace
display name will 404. Find the id with
xeroctl workspaces list.
Watch the SSE output. The model will use the template's
system prompt and work through the drain procedure.
When it reaches k8s_drain_node, the
approval engine pauses the invocation and emits an
x_ask_user.question frame.
Approve it from another terminal. List the open approvals to find the id, then approve it with a short justification (see Approvals for the full decision payload):
xeroctl approvals list
xeroctl approvals approve <approval_id> --decision approve \
--justification "Scheduled maintenance for worker-07"
Step 4: Iterate and Version
You noticed during testing that the system prompt is
not explicit about which namespaces are in scope. Edit
drain-node.json:
{
...
"system_prompt": "You are a Kubernetes operator. When asked to drain a node, cordon it first, drain with grace-period 60, verify no stuck pods in any namespace, and stop. Assume cluster-wide namespace scope unless the operator restricts it.",
...
}
Push the update:
xeroctl templates update drain-kubernetes-node --file drain-node.json
Version 2 replaces version 1 as the active version. New chats pick up version 2 automatically; in-flight chats keep the version they started on.
Step 5: Promote Platform-Wide
Other projects in your organization could use this template too. Promote it from project scope to platform scope:
xeroctl templates promote drain-kubernetes-node --scope platform
Platform-scope templates are visible to every project in the deployment. Promotion is one-way: platform scope cannot be demoted without deleting and recreating at project scope.
Next Steps
- Publish more templates and keep them together in a
git repository; synchronize with
xeroctl templates apply-from-dir <directory>(the directory is a positional argument; add--workspace ws_<hex>for workspace-scoped syncs). The command walks every*.jsonfile in the directory and reports each one as created (new name), updated (existing name with changed fields), or unchanged (existing name with identical fields), no template is ever deleted by this command. - See Approvals for
tuning the
elevatedpolicy's SLA and escalation chain. - Browse the built-in tool catalog -- Cloud, Kubernetes, OpenStack, and Ecosystem, to find tool names your templates can reference.