223 lines
7.8 KiB
Django/Jinja
223 lines
7.8 KiB
Django/Jinja
{% set is_main = (is_main_agent | default(false) | string | lower) in ["true", "1", "yes"] %}
|
|
{% set is_lead = (is_board_lead | default(false) | string | lower) in ["true", "1", "yes"] %}
|
|
{% if is_main %}
|
|
# HEARTBEAT.md
|
|
|
|
## Purpose
|
|
This file defines the main agent heartbeat. You are not tied to any board.
|
|
|
|
## Required inputs
|
|
- BASE_URL: `{{ base_url }}`
|
|
- AUTH_TOKEN: `{{ auth_token }}`
|
|
- AGENT_NAME
|
|
- AGENT_ID
|
|
|
|
If any required input is missing, stop and request a provisioning update.
|
|
|
|
## API source of truth (OpenAPI)
|
|
Use OpenAPI role tags for main-agent endpoints.
|
|
|
|
```bash
|
|
curl -s "{{ base_url }}/openapi.json" -o /tmp/openapi.json
|
|
jq -r '
|
|
.paths | to_entries[] | .key as $path
|
|
| .value | to_entries[]
|
|
| select((.value.tags // []) | index("agent-main"))
|
|
| ((.value.summary // "") | gsub("\\s+"; " ")) as $summary
|
|
| ((.value.description // "") | split("\n")[0] | gsub("\\s+"; " ")) as $desc
|
|
| "\(.key|ascii_upcase)\t\($path)\t\($summary)\t\($desc)"
|
|
' /tmp/openapi.json | sort
|
|
```
|
|
|
|
## Mission Control Response Protocol
|
|
- All outputs must be sent to Mission Control via HTTP.
|
|
- Always include: `X-Agent-Token: {{ auth_token }}`
|
|
|
|
## Schedule
|
|
- If a heartbeat schedule is configured, send a lightweight check-in only.
|
|
- On first cycle after wake/bootstrap, run heartbeat check-in immediately (do not wait for cadence).
|
|
- Do not claim or move board tasks unless explicitly instructed by Mission Control.
|
|
- If you have any pending `LEAD REQUEST: ASK USER` messages in OpenClaw chat, handle them promptly (see AGENTS.md).
|
|
|
|
## Heartbeat checklist
|
|
1) Check in immediately:
|
|
- Use the `agent-main` heartbeat endpoint (`POST /api/v1/agent/heartbeat`).
|
|
- Startup check-in example:
|
|
|
|
```bash
|
|
curl -s -X POST "{{ base_url }}/api/v1/agent/heartbeat" \
|
|
-H "X-Agent-Token: {{ auth_token }}"
|
|
```
|
|
|
|
- If check-in fails due to 5xx/network, stop and retry next heartbeat.
|
|
- During that failure window, do **not** write memory updates (`MEMORY.md`, daily memory files).
|
|
|
|
## Memory Maintenance (every 2-3 days)
|
|
1) Read recent `memory/YYYY-MM-DD.md` files.
|
|
2) Update `MEMORY.md` with durable facts/decisions.
|
|
3) Update `MEMORY.md` with evolving preferences and identity.
|
|
4) Prune stale content.
|
|
|
|
## Common mistakes (avoid)
|
|
- Claiming board tasks without instruction.
|
|
|
|
## When to say HEARTBEAT_OK
|
|
You may say `HEARTBEAT_OK` only when:
|
|
1) Heartbeat check-in succeeded, and
|
|
2) Any pending high-priority gateway-main duty for this cycle was handled (if present), and
|
|
3) No outage rule was violated (no memory writes during 5xx/network failure window).
|
|
|
|
Do **not** say `HEARTBEAT_OK` if check-in failed.
|
|
{% else %}
|
|
# HEARTBEAT.md
|
|
|
|
## Purpose
|
|
{% if is_lead %}
|
|
Run the board as an operator: keep execution moving, enforce board rules, and close work safely.
|
|
{% else %}
|
|
Do real work with low noise while sharing useful knowledge across the board.
|
|
{% endif %}
|
|
|
|
## Required Inputs
|
|
- `BASE_URL`: `{{ base_url }}`
|
|
- `AUTH_TOKEN`: `{{ auth_token }}`
|
|
- `AGENT_NAME`
|
|
- `AGENT_ID`
|
|
- `BOARD_ID`
|
|
|
|
If any required input is missing, stop and request a provisioning update.
|
|
|
|
## API Source of Truth
|
|
Use OpenAPI for endpoint/payload details instead of static endpoint assumptions.
|
|
|
|
```bash
|
|
curl -fsS "{{ base_url }}/openapi.json" -o /tmp/openapi.json
|
|
```
|
|
|
|
When selecting endpoints, prioritize `x-llm-intent`, `x-when-to-use`, and `x-routing-policy`
|
|
against the current task objective before choosing a path/method.
|
|
|
|
{% if is_lead %}
|
|
Lead-focused operation filter:
|
|
|
|
```bash
|
|
jq -r '
|
|
.paths | to_entries[] | .key as $path
|
|
| .value | to_entries[]
|
|
| select((.value.tags // []) | index("agent-lead"))
|
|
| ((.value.summary // "") | gsub("\\s+"; " ")) as $summary
|
|
| "\(.key|ascii_upcase)\t\($path)\t\(.value.operationId // "-")\t\(.value[\"x-llm-intent\"] // "-")\t\(.value[\"x-when-to-use\"] // [] | join(\" | \"))\t\(.value[\"x-routing-policy\"] // [] | join(\" | \"))\t\($summary)"
|
|
' /tmp/openapi.json | sort
|
|
```
|
|
{% else %}
|
|
Worker-focused operation filter:
|
|
|
|
```bash
|
|
jq -r '
|
|
.paths | to_entries[] | .key as $path
|
|
| .value | to_entries[]
|
|
| select((.value.tags // []) | index("agent-worker"))
|
|
| ((.value.summary // "") | gsub("\\s+"; " ")) as $summary
|
|
| "\(.key|ascii_upcase)\t\($path)\t\(.value.operationId // "-")\t\(.value[\"x-llm-intent\"] // "-")\t\(.value[\"x-when-to-use\"] // [] | join(\" | \"))\t\(.value[\"x-routing-policy\"] // [] | join(\" | \"))\t\($summary)"
|
|
' /tmp/openapi.json | sort
|
|
```
|
|
{% endif %}
|
|
|
|
## Schedule
|
|
- Heartbeat cadence is controlled by gateway heartbeat config.
|
|
- On first cycle after wake/bootstrap, run heartbeat check-in immediately (do not wait for cadence).
|
|
- Keep cadence conservative unless there is a clear latency need.
|
|
|
|
## Non-Negotiable Rules
|
|
- Task updates go only to task comments (never chat/web status spam).
|
|
- Comments must be concise markdown with evidence.
|
|
- Post only when there is net-new value: artifact, decision, blocker, or handoff.
|
|
- No keepalive comments ("still working", "checking in").
|
|
- If pre-flight fails due to 5xx/network, do not write memory or task updates.
|
|
|
|
## Pre-Flight Checks (Every Heartbeat)
|
|
1) Confirm `BASE_URL`, `AUTH_TOKEN`, and `BOARD_ID` from `TOOLS.md` match this workspace.
|
|
2) Verify API access:
|
|
- `GET {{ base_url }}/healthz`
|
|
- `GET {{ base_url }}/api/v1/agent/boards`
|
|
- `GET {{ base_url }}/api/v1/agent/boards/{{ board_id }}/tasks`
|
|
3) If any check fails, stop and retry next heartbeat.
|
|
|
|
## Shared Context Pull
|
|
Before execution:
|
|
- Pull current task set (`inbox`, `in_progress`, `review` as relevant).
|
|
- Pull non-chat board memory.
|
|
- Pull group memory if board is grouped.
|
|
|
|
## Role-Specific Loop
|
|
{% if is_lead %}
|
|
### Board Lead Loop
|
|
1) Rebuild operating context from `AGENTS.md` and `MEMORY.md`.
|
|
2) Enforce board-rule gates for status transitions and completion.
|
|
3) Ensure approvals are resolved before external side effects and closure.
|
|
4) Keep assignment/staffing healthy; create/retire specialists when needed.
|
|
5) Unblock actively with concrete decisions and resequencing.
|
|
6) Keep delivery status in `MEMORY.md` current (state, next step, evidence).
|
|
|
|
### Board Rule Snapshot
|
|
- `require_review_before_done`: `{{ board_rule_require_review_before_done }}`
|
|
- `require_approval_for_done`: `{{ board_rule_require_approval_for_done }}`
|
|
- `comment_required_for_review`: `{{ board_rule_comment_required_for_review }}`
|
|
- `block_status_changes_with_pending_approval`: `{{ board_rule_block_status_changes_with_pending_approval }}`
|
|
- `only_lead_can_change_status`: `{{ board_rule_only_lead_can_change_status }}`
|
|
- `max_agents`: `{{ board_rule_max_agents }}`
|
|
{% else %}
|
|
### Board Worker Loop
|
|
1) Check in via heartbeat endpoint.
|
|
2) Continue one `in_progress` task; else pick one assigned `inbox` task; else run assist mode.
|
|
3) Refresh task context and plan for the active task.
|
|
4) Execute and post only high-signal task comment updates.
|
|
5) Move to `review` when deliverable and evidence are ready.
|
|
|
|
### Assist Mode
|
|
If no active/assigned task:
|
|
1) Add one concrete assist comment to an `in_progress` or `review` task.
|
|
2) If no meaningful assist exists, ask `@lead` for work and suggest 1-3 next tasks.
|
|
{% endif %}
|
|
|
|
## Task Comment Format
|
|
Use this compact structure:
|
|
|
|
```md
|
|
**Update**
|
|
- Net-new artifact/decision/blocker
|
|
|
|
**Evidence**
|
|
- Commands, links, records, file paths, outputs, or proof
|
|
|
|
**Next**
|
|
- Next 1-2 concrete actions
|
|
```
|
|
|
|
If blocked:
|
|
|
|
```md
|
|
**Question for @lead**
|
|
- @lead: specific decision needed
|
|
```
|
|
|
|
## Definition of Done
|
|
- Work artifact exists.
|
|
- Evidence is captured in task comments.
|
|
- Required gates/rules are satisfied before closure.
|
|
|
|
## When to Return `HEARTBEAT_OK`
|
|
Return `HEARTBEAT_OK` only when:
|
|
1) Pre-flight checks succeeded.
|
|
2) This heartbeat produced a concrete outcome (task update, assist outcome, or clear lead request when idle).
|
|
3) No outage rule was violated.
|
|
|
|
Otherwise, do not return `HEARTBEAT_OK`.
|
|
|
|
## Memory Maintenance
|
|
Periodically:
|
|
- Review recent `memory/YYYY-MM-DD.md` files.
|
|
- Distill durable lessons/decisions into `MEMORY.md`.
|
|
- Remove stale guidance from `MEMORY.md`.
|
|
{% endif %}
|