# Built-in skills reference

> Catalog of shipped skills (goal, refine, compact, heartbeat, observe, message, edit, integrations) with entry modules and invocation roles.

- Repository: PrimeIntellect-ai/prime-agent
- GitHub: https://github.com/PrimeIntellect-ai/prime-agent
- Human docs: https://grok-wiki.com/public/docs/primeintellect-ai-prime-agent-3367c32760b1
- Complete Markdown: https://grok-wiki.com/public/docs/primeintellect-ai-prime-agent-3367c32760b1/llms-full.txt

## Source Files

- `packages/coding-agent/skills/goal/SKILL.md`
- `packages/coding-agent/skills/refine/SKILL.md`
- `packages/coding-agent/skills/compact/SKILL.md`
- `packages/coding-agent/skills/rlm-heartbeat/SKILL.md`
- `packages/coding-agent/skills/agent-observe/SKILL.md`
- `packages/coding-agent/skills/agent-message/SKILL.md`

---

---
title: "Built-in skills reference"
description: "Catalog of shipped skills (goal, refine, compact, heartbeat, observe, message, edit, integrations) with entry modules and invocation roles."
---

Prime Agent ships kernel-callable skills as packages under `packages/coding-agent/skills/`. Each skill exposes an async Python surface invoked from the persistent IPython control plane (or kernel), with host-backed behavior for harness, context, goals, and family messaging. Documented here from shipped `SKILL.md` packages: `goal`, `refine`, `compact`, `rlm-heartbeat`, `agent-observe`, and `agent-message`.

<Note>
User-facing slash commands such as `/compact`, `/refine`, and `/heartbeat` are host surfaces. The skills below are the agent-side IPython interfaces to related behavior (or, for RLM heartbeats, a separate agent-owned surface that does not control the user's `/heartbeat`).
</Note>

## Catalog

| Skill name | Package path | Kernel entry | Role |
|---|---|---|---|
| `goal` | `packages/coding-agent/skills/goal/` | `goal` | Persistent thread objective: read status/budget, create when explicitly requested, complete when achieved |
| `refine` | `packages/coding-agent/skills/refine/` | `refine` | Schedule continual-harness refinement from trajectory (session-local or global) |
| `compact` | `packages/coding-agent/skills/compact/` | `compact` | Report context usage; schedule conversation compaction |
| `rlm-heartbeat` | `packages/coding-agent/skills/rlm-heartbeat/` | `rlm_heartbeat` | Agent-owned recurring prompts for the current session |
| `agent-observe` | `packages/coding-agent/skills/agent-observe/` | `agent_observe` | Read-only nuclear-family session inspection |
| `agent-message` | `packages/coding-agent/skills/agent-message/` | `agent_message` | Direct messages to parent, siblings, or children via the daemon |

```text
packages/coding-agent/skills/
├── goal/SKILL.md              → await goal.*
├── refine/SKILL.md            → await refine.*
├── compact/SKILL.md           → await compact.*
├── rlm-heartbeat/SKILL.md     → await rlm_heartbeat.*
├── agent-observe/SKILL.md     → await agent_observe.*
└── agent-message/SKILL.md     → await agent_message.*
```

## Invocation model

| Concern | Behavior |
|---|---|
| Call site | IPython / kernel: `await <entry>.<method>(...)` |
| Host-backed skills | `goal`, `refine`, `compact` — implementation lives in the host; skill is the kernel-side interface |
| Deferred apply | `refine.run` and `compact.run` schedule work; it runs when the **current turn ends**, not mid-cell |
| Immediate return | Scheduling APIs return `{"scheduled": True}` or `{"scheduled": False, "reason": ...}` |
| One request per turn | Re-calling `run` before the turn ends updates instructions only |
| Family graph | `agent_observe` / `agent_message` operate on the nuclear family (self, parent, siblings, direct children) through the local daemon |
| Related RLM APIs | Subagent lifecycle uses `rlm.list_subagents()`, `rlm.delete_subagent(...)` (parent-owned); not part of observe |

```mermaid
flowchart TB
  subgraph kernel["IPython / kernel"]
    G["goal"]
    R["refine"]
    C["compact"]
    H["rlm_heartbeat"]
    O["agent_observe"]
    M["agent_message"]
  end
  subgraph host["Host"]
    HG["Goal state"]
    HR["/refine + harness apply"]
    HC["/compact + summary"]
  end
  subgraph daemon["Local daemon"]
    FAM["Nuclear family sessions"]
    MSG["Message delivery"]
  end
  G --> HG
  R --> HR
  C --> HC
  H --> FAM
  O --> FAM
  M --> MSG
  MSG --> FAM
```

---

## `goal` — thread goal

**Frontmatter:** `name: goal`  
**Description:** Manage the persistent thread goal from IPython. Use to read goal status and budget usage, to start a goal when the user explicitly asks for one, or to mark the active goal complete once its objective is fully achieved.

The harness keeps re-prompting the agent toward the objective across turns until completion. Goal state (status, token budget, usage) lives in the host.

### API

| Call | Returns / effect |
|---|---|
| `await goal.get()` | Dict: `goal` (`None` if unset), `remaining_tokens`, `completion_budget_report` |
| `await goal.create(objective, token_budget=None)` | Start active goal |
| `await goal.complete()` | Mark existing goal achieved |

**`goal` object fields (when set):** `objective`, `status`, `token_budget`, `tokens_used`, `time_used_seconds`, timestamps.

### Constraints

- `create` fails while a goal is still pending (active, paused, or budget-limited). Completed or errored goals are replaced.
- Create only when the user or system/developer instructions **explicitly** request a persistent long-running goal; do not infer goals from ordinary tasks.
- Set `token_budget` only when an explicit budget is requested.
- Pause, resume, clear, and budget-limiting are host/user-controlled — not exposed on this skill.
- Completion must call `await goal.complete()`; saying the work is done does not stop harness continuation.
- When `complete` returns a `completion_budget_report`, report final usage to the user.

### Example

```python
await goal.get()
await goal.create("ship the release notes", token_budget=200000)
await goal.complete()
```

---

## `refine` — continual harness refinement

**Frontmatter:** `name: refine`  
**Description:** Trigger continual harness refinement from IPython. Use when you notice a repeated failure, reusable tactic, delegation role, or behavior policy that should be persisted as a harness entry. Returns immediately; refinement runs when the current turn ends.

Refinement analyzes the conversation trajectory and applies small, evidence-backed updates to the continual harness (prompts, memories, skills, subagent specs). Same host path as the user's `/refine` command.

### API

| Call | Returns / effect |
|---|---|
| `await refine.status()` | `pending` (queued this turn), `in_flight` (planning or applying) |
| `await refine.run(instructions=None, global_=False)` | `{"scheduled": True}` or `{"scheduled": False, "reason": ...}` |

### Parameters

<ParamField body="instructions" type="string | None">
Focus refinement on a specific observation. Optional.
</ParamField>

<ParamField body="global_" type="bool" default="False">
`True` targets the global harness store (cross-session). Omit/`False` for session-scoped (local) refinement.
</ParamField>

### Constraints

- Never runs mid-cell; applies at turn end, rebuilds the system prompt, then resumes the agent.
- Prefer focused memories, skills, prompt notes, or subagent specs over rewriting the whole harness.
- Use after repeated failures, reusable tactics, repeated delegation roles, or persistable behavior policies.

### Example

```python
await refine.status()
await refine.run()
await refine.run("create a memory about always checking git status before committing")
await refine.run("promote the error-handling pattern to a global skill", global_=True)
```

---

## `compact` — context compaction

**Frontmatter:** `name: compact`  
**Description:** Check context usage and compact the conversation from IPython. Use when context is filling up and substantial work remains, so the session is summarized and you keep working instead of stopping early.

Compaction replaces older history with a dense summary. Host implementation matches the user's `/compact` command.

### API

| Call | Returns / effect |
|---|---|
| `await compact.status()` | `tokens`, `context_window`, `percent` (`None` right after compaction until the next model response), `scheduled` |
| `await compact.run(instructions=None)` | `{"scheduled": True}` or `{"scheduled": False, "reason": ...}` when nothing to compact yet |

### Constraints

- Never runs mid-cell; runs when the turn ends; harness resumes with summary plus recent messages.
- IPython kernel **persists** through compaction: variables, imports, and helpers remain available.
- Compact at a natural boundary when usage is high and substantial work remains.
- One `run` per turn; later calls only update instructions.

### Example

```python
await compact.status()
await compact.run()
await compact.run("keep the failing test names and the migration checklist")
```

---

## `rlm-heartbeat` — agent-owned heartbeats

**Frontmatter:** `name: rlm-heartbeat`  
**Kernel entry:** `rlm_heartbeat`  
**Description:** Manage agent-owned RLM heartbeats from IPython. Use when the user asks the agent to start, create, schedule, or manage a heartbeat, unless they explicitly request the user's `/heartbeat`.

RLM heartbeats are **internal** recurring prompts for the current agent session. They are separate from the user's visible `/heartbeat`. This skill cannot read, replace, pause, resume, or clear the user-level heartbeat.

### API

| Call | Behavior |
|---|---|
| `await rlm_heartbeat.list(include_inactive=False)` | List this session's internal RLM heartbeats (default: active + paused) |
| `await rlm_heartbeat.create(instruction, interval=None, label=None, delivery_mode=None)` | Create recurring heartbeat |
| `await rlm_heartbeat.update(id, instruction=None, interval=None, label=None, status=None, delivery_mode=None)` | Update by id |
| `await rlm_heartbeat.delete(id)` | Cancel by id |

### Defaults and enums

| Field | Values / default |
|---|---|
| `interval` | Default every **5 minutes** when omitted |
| `label` | Optional; distinguish concurrent heartbeats |
| `delivery_mode` | `"steer"` (default) or `"follow_up"` |
| `status` (update) | `"pause"` or `"resume"` |

### Delivery mode

| Mode | Behavior when session is busy |
|---|---|
| `steer` (default) | Interrupt the current turn so the heartbeat runs promptly |
| `follow_up` | Wait for the current turn to finish before running |

### Constraints

- Use for agent-internal recurring checks and long-running task coordination.
- Do **not** use this skill to configure the user's `/heartbeat`.
- Keep instructions specific and actionable per tick.
- Multiple RLM heartbeats may run at once.

### Example

```python
await rlm_heartbeat.create("check test progress", interval="5m", label="tests")
await rlm_heartbeat.create("watch build", delivery_mode="follow_up")
await rlm_heartbeat.list()
await rlm_heartbeat.update("job-id", status="pause")
await rlm_heartbeat.delete("job-id")
```

---

## `agent-observe` — family observation (read-only)

**Frontmatter:** `name: agent-observe`  
**Kernel entry:** `agent_observe`  
**Description:** Read-only observation of an agent's parent, siblings, and direct children. Use to inspect family status and bounded recent-message previews without mutating sessions.

Observes the nuclear family through the local daemon: parent, siblings, direct children, and self. Limited to family members in the **same worker**; root siblings in other workers are not observable yet.

**Not allowed:** prompt, steer, clear, kill, rename, or any other mutation of another session. Deletion of subagents is parent-owned RLM (`await rlm.delete_subagent(...)`), not observe.

### API

| Call | Returns |
|---|---|
| `await agent_observe.list_agents()` | `current` and `agents` |
| `await agent_observe.get_agent(target)` | `{ "agent": <summary> }` |
| `await agent_observe.recent_messages(target, limit=8, max_chars=800)` | Bounded recent message previews |

### Agent summary fields

Active session id, session id, optional name, runtime kind, cwd, status, streaming state, message count, pending count, latest message preview.

### Selectors and bounds

| Item | Rule |
|---|---|
| `target` | Active id, session id/name, or unambiguous suffix |
| `limit` | 1–50 (default 8) |
| `max_chars` | 80–2000 (default 800) |
| Scope | Self, parent, siblings, direct children only; outside family rejected |

### Example

```python
children = await rlm.list_subagents()
child = next((item for item in children if item.active_session_id), None)
if child is not None:
    worker = await agent_observe.get_agent(child.session_name)
    recent = await agent_observe.recent_messages(child.session_name, limit=6)
    # Deletion is parent-owned RLM, not observe:
    await rlm.delete_subagent(child)
```

---

## `agent-message` — family messaging

**Frontmatter:** `name: agent-message`  
**Kernel entry:** `agent_message`  
**Description:** Message an agent's parent, siblings, or direct children through the daemon. Use the family roster to discover reachable agents and send direct text without spoofing sender identity.

Send direct messages within the current agent's nuclear family: parent, siblings, and direct children only. Roots are siblings. Sender identity is **daemon-derived** from the current session — do not include a `from` field.

### API

| Call | Behavior |
|---|---|
| `await agent_message.list_agents()` | `current` (`name`, `id`, `depth`) and family-scoped `entries` (`relationship`, `name`, `id`, `depth`, `status`) |
| `await agent_message.send(message, receiver_role=..., receiver_name=None)` | One direct text message to an active session |
| `send("all", message)` | Broadcast to family roster only; returns `{receipts: [...]}` |

### `list_agents` details

- Includes inactive family members.
- Sort order: parent, then siblings by name, then children by name.
- Does **not** expose a global daemon session list.

### `send` details

| Item | Rule |
|---|---|
| `receiver_role` | `"parent"` \| `"sibling"` \| `"child"` (resolved within current family) |
| `receiver_name` | Required for siblings and children; omit for the unique parent |
| Idle completed subagent | Starts an ordinary follow-up turn in that same child session/context |
| Child lifetime | Child remains available only until its parent session closes |
| Delivery | Always **steering** so a busy target sees messages during its active run |
| Broadcast failures | One failed delivery does not reject successful deliveries; failed entries include target id and short `error` |

### Receipts

| `deliveryStatus` | Meaning |
|---|---|
| `"delivered"` | Message reached an idle target's context (`deliveredAt`) |
| `"queued"` | Steering accepted; delivers when target's current work allows (`queuedAt`). `send` does not block waiting |

### Safety

- Do not delete a child immediately after `send`; wait until observation shows idle and context is no longer needed before `await rlm.delete_subagent(child)`.
- Reach is parent / siblings / direct children only; relay via an intermediate for grandchildren or cousins.
- Sender identity cannot be spoofed from Python.
- Daemon enforces message size, rate, and pending-queue limits before accepting delivery.

### Example

```python
children = await rlm.list_subagents()
child = next((item for item in children if item.active_session_id), None)
if child is not None:
    receipt = await agent_message.send(
        "Please inspect the latest result.",
        receiver_role="child",
        receiver_name=child.session_name,
    )
    # Keep the child until this follow-up finishes so its result remains observable.
```

---

## Cross-skill coordination patterns

### Long-running work

| Need | Skill |
|---|---|
| Explicit multi-turn objective + budget | `goal.create` / `goal.complete` |
| Context pressure mid-task | `compact.status` → `compact.run` |
| Periodic agent-owned checks | `rlm_heartbeat.create` with `steer` or `follow_up` |
| Persist a learned policy | `refine.run` (local or `global_=True`) |

### Multi-agent family

| Need | Skill |
|---|---|
| Discover / inspect family | `agent_observe.list_agents` / `get_agent` / `recent_messages` |
| Parent-owned child handles | `rlm.list_subagents()` |
| Direct instruction to family member | `agent_message.send` |
| Broadcast to roster | `agent_message.send("all", message)` |
| Remove child after work | `rlm.delete_subagent` only when idle and no longer needed |

```text
                  parent session
                       │
         ┌─────────────┼─────────────┐
         │             │             │
      sibling       (self)        sibling
                       │
              ┌────────┴────────┐
           child A           child B
              ▲                 │
   agent_message.send      agent_observe.*
   (steer delivery)        (read-only)
```

---

## User-level vs agent-level surfaces

| Concern | User / host | Agent skill |
|---|---|---|
| Compaction | `/compact` | `compact` |
| Harness refine | `/refine` | `refine` |
| Heartbeat | `/heartbeat` (user-visible) | `rlm_heartbeat` (agent-internal only; does not control user heartbeat) |
| Goal lifecycle (pause/resume/clear) | User + host | `goal` only get/create/complete |
| Family message delivery limits | Daemon enforcement | `agent_message` subject to those limits |

---

## Error and boundary signals

| Signal | Meaning |
|---|---|
| `{"scheduled": False, "reason": ...}` | `refine.run` or `compact.run` could not start |
| `goal.create` fails while pending | Active, paused, or budget-limited goal still exists |
| `percent: None` on `compact.status` | Immediately after compaction, until next model response |
| Observe/message outside family | Rejected; transcript reads follow the same family rule |
| Message receipt `"queued"` | Accepted for later delivery; not yet in idle context |
| Broadcast partial failure | Successful receipts still delivered; failed entries carry `error` |

---

## Related pages

<CardGroup>
  <Card title="Skills model" href="/skills-model">
    Skills as importable packages, SKILL.md frontmatter, collision precedence, and scope.
  </Card>
  <Card title="Create and install skills" href="/create-skills">
    Author packages with skill-creator, required fields, layout, and load-path checks.
  </Card>
  <Card title="Refine harness state" href="/refine-harness">
    Run refine against the trajectory, apply harness updates, and use snapshots for rollback.
  </Card>
  <Card title="Continual Harness" href="/continual-harness">
    Durable prompts, memories, skill specs, subagent specs, and refine boundaries.
  </Card>
  <Card title="Long-running tasks" href="/long-running-tasks">
    Goals, compaction, heartbeats, and retained subagents across disconnects.
  </Card>
  <Card title="Subagents and messaging" href="/subagents-messaging">
    rlm-spawned children, agent-message surface, and multi-agent constraints.
  </Card>
  <Card title="RLM control plane" href="/rlm-control-plane">
    Persistent IPython as control tool, prompt-as-variable context, and rlm(...) calls.
  </Card>
</CardGroup>
