> ## Documentation Index
> Fetch the complete documentation index at: https://mantle.rasa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Default skills

> Bundled lifecycle skills and the default wording of packaged responses.

Every agent ships six skills the engine runs itself, plus a few responses that
are not tied to one skill. The model does not pick these skills from the normal
menu. You hear them as the greeting policy, the wrap-up, the resume offer, a
satisfaction question, a decline, or a silence check-in.

Two ways to change them:

* **Replace the wording.** Declare the same response name in your project
  `responses.yml`. See
  [Where the file lives](/reference/responses-yml#where-the-file-lives).
* **Replace the skill.** Add `skills/<skill id>/` with the same id. The project
  skill replaces the bundled one. Keep `routing.engine_managed: true`. Omitting
  the key keeps the bundled value. Setting it to `false` also offers the skill
  on the normal menu; the engine still treats that skill id as the lifecycle
  skill. Training rejects `false` on `default_unsupported_request_handler`.

Each section shows the files that ship with the skill. Skill responses ship
with `rephrase: true`, so the model may paraphrase them. The packaged responses
in [Other packaged responses](#other-packaged-responses) do not, except
`utter_hangup_goodbye`.

## Session start

`default_session_start` runs at the start of a session and does not speak. It
has no bundled greeting to override.

To make the agent speak first, replace this skill and have the channel send
`/session_start`. To let the user speak first, leave the bundled skill as it
is. See [Start a conversation](/mantle/runtime-loop#start-a-conversation).

```markdown skills/default_session_start/skill.md theme={null}
---
name: Session Start
description: "Initialize a new conversation session without speaking."
routing:
  engine_managed: true
---

:::ordered_block id=main
name: default_session_start
description: "Initialize a new conversation session without speaking."
steps:
  - id: start
    noop: true
    next: END
:::
```

This skill has no `memory.yml` and no `responses.yml`.

## Completed

`default_completed` runs when a skill you wrote finishes or is cancelled and
nothing else is left on the stack. It does not run after another default skill.

It asks whether the user wants more help. If they do, the agent asks what they
need and can activate that skill. If they do not, this skill links to
[Customer satisfaction](#customer-satisfaction).

```markdown skills/default_completed/skill.md theme={null}
---
name: Completed
description: "Post-skill wrap-up: ask if the user needs more help."
routing:
  engine_managed: true
---

:::ordered_block id=main
name: default_completed
description: "Post-skill wrap-up: ask if the user needs more help."
steps:
  - id: ask_continue
    collect: wants_to_continue
    utterance: utter_ask_wants_to_continue
    description: >
      Does the user want to continue with another task? If they name a concrete
      task, set the collected memory entry to true and activate the appropriate skill — do
      not only re-ask this question.
    next:
      - if: "session.default_completed.wants_to_continue"
        then: more_help
      - else: csat_link
  - id: more_help
    instructions: >
      Ask what exactly the user needs help with.
      If the user replies with a specific task, activate the appropriate skill.
  - id: csat_link
    link: default_customer_satisfaction
:::
```

```yaml skills/default_completed/memory.yml theme={null}
schema:
  public:
    wants_to_continue:
      type: bool
      description: "Whether the user wants to continue with another task."
```

```yaml skills/default_completed/responses.yml theme={null}
responses:
  utter_ask_wants_to_continue:
    - text: "Is there anything else I can help you with?"
      metadata:
        rephrase: true
```

## Continue interrupted

`default_continue_interrupted` runs after a digression, when a paused task can
be resumed. It asks whether to continue. If the user agrees, the paused skill
continues from the same step. Otherwise it is dropped. See
[Interruptions](/mantle/skills#the-skill-stack).

When this skill activates, the engine writes `interrupted_task_name` with a
readable label for the paused skill (its name, or its name plus description).
If that label cannot be stored, the prompt uses "your previous request". Keep
`interrupted_task_name` in `memory.yml` if you replace this skill.

```markdown skills/default_continue_interrupted/skill.md theme={null}
---
name: Continue Interrupted
description: "After a digression: ask whether to resume the interrupted task."
routing:
  engine_managed: true
---

:::ordered_block id=main
name: default_continue_interrupted
description: "After a digression: ask whether to resume the interrupted task."
steps:
  - id: ask_resume
    collect: wants_to_resume
    utterance: utter_ask_wants_to_resume
    description: "Does the user want to resume the task that was interrupted?"
:::
```

```yaml skills/default_continue_interrupted/memory.yml theme={null}
schema:
  public:
    wants_to_resume:
      type: bool
      description: "Whether the user wants to resume the interrupted task."
    interrupted_task_name:
      type: text
      description: "Display name of the paused skill shown in the resume prompt."
```

```yaml skills/default_continue_interrupted/responses.yml theme={null}
responses:
  utter_ask_wants_to_resume:
    - text: |
        You were in the middle of {session.default_continue_interrupted.interrupted_task_name}.
        Would you like to continue where you left off, or shall I drop it?
      metadata:
        rephrase: true
```

## Customer satisfaction

`default_customer_satisfaction` collects a score and thanks the user. Completed
links here when the user does not want more help. It is not chosen by ordinary
routing.

`conversation.before_end` in [`agent.yml`](/reference/agent-yml#conversation)
is a separate list of skill ids rendered into the routing prompt. An example
there uses this skill's id. That list is not what starts the bundled skill.

```markdown skills/default_customer_satisfaction/skill.md theme={null}
---
name: Customer Satisfaction
description: "Collect customer satisfaction feedback at end of conversation."
routing:
  engine_managed: true
---

:::ordered_block id=main
name: default_customer_satisfaction
description: "Collect customer satisfaction feedback at end of conversation."
steps:
  - id: ask_csat
    collect: csat_score
    utterance: utter_ask_csat_score
    description: "How satisfied was the user (1–5)?"
  - id: thank_you
    action: utter_thank_you_for_feedback
:::
```

```yaml skills/default_customer_satisfaction/memory.yml theme={null}
schema:
  public:
    csat_score:
      type: float
      description: "Customer satisfaction score provided by the user (1–5)."
```

```yaml skills/default_customer_satisfaction/responses.yml theme={null}
responses:
  utter_thank_you_for_feedback:
    - text: "Thank you for your feedback! Have a great day."
      metadata:
        rephrase: true

  utter_ask_csat_score:
    - text: |
        On a scale of 1 to 5, how satisfied are you with the assistance
        you received today?
      metadata:
        rephrase: true
```

## Unsupported request

`default_unsupported_request_handler` runs when the model calls `cannot_help`.
Routing never activates it.

The engine sets `request_type` to `in_domain_out_of_scope` or
`out_of_domain_out_of_scope`. Both are requests the agent will not handle. The
value picks the message.

```markdown skills/default_unsupported_request_handler/skill.md theme={null}
---
name: Unsupported Request Handler
description: >
  Sends a decline when the user asks for something this agent cannot help
  with. Activated by the engine's `cannot_help` tool, not by routing: the model
  decides the request is unsupported and the engine runs this skill to utter the
  decline. The seeded request type (in domain vs out of domain — both out of
  scope) selects the message.
routing:
  engine_managed: true
---

:::ordered_block id=main
name: default_unsupported_request_handler
description: >
  Sends a decline when the user asks for something this agent cannot help
  with. Activated by the engine's `cannot_help` tool; the seeded request type
  (in domain vs out of domain — both out of scope) selects the message.
steps:
  - id: gate_request_type
    noop: true
    next:
      - if: "session.default_unsupported_request_handler.request_type == 'out_of_domain_out_of_scope'"
        then: decline_out_of_domain_out_of_scope
      - else: decline_in_domain_out_of_scope
  - id: decline_in_domain_out_of_scope
    action: utter_decline_in_domain_out_of_scope
    next: END
  - id: decline_out_of_domain_out_of_scope
    action: utter_decline_out_of_domain_out_of_scope
    next: END
:::
```

```yaml skills/default_unsupported_request_handler/memory.yml theme={null}
schema:
  public:
    request_type:
      type: str
      description: "Request type seeded by the cannot_help tool. Both are out-of-scope requests: in_domain_out_of_scope or out_of_domain_out_of_scope."
```

```yaml skills/default_unsupported_request_handler/responses.yml theme={null}
responses:
  utter_decline_in_domain_out_of_scope:
    - text: |
        I'm not able to help with that here. I can assist with the tasks
        this agent supports — let me know if you'd like help with one of those.
      metadata:
        rephrase: true

  utter_decline_out_of_domain_out_of_scope:
    - text: |
        That's outside what I can help with in this channel. If you have a
        question related to what this agent is set up for, I'm happy to try.
      metadata:
        rephrase: true
```

## Silence timeout

`default_silence_timeout` runs when the user has been silent for the configured
timeout. Voice runs the `main` block three times, then on the next timeout runs
the `hangup` block: goodbye, then hang up. Any user speech resets that counter.
The retry count is not configurable. See
[`conversation`](/reference/agent-yml#conversation).

```markdown skills/default_silence_timeout/skill.md theme={null}
---
name: Silence Timeout
description: "Respond when the user has been silent for the configured timeout."
routing:
  engine_managed: true
---

:::ordered_block id=main
name: default_silence_timeout
description: "Check whether the user wants to continue after a silence timeout."
steps:
  - id: check_in
    action: utter_silence_timeout_check_in
    next: END
:::

:::ordered_block id=hangup
name: default_silence_timeout_hangup
description: "End the conversation after the configured silence retries are exhausted."
steps:
  - id: inform_hangup
    action: utter_inform_hangup
  - id: hangup
    action: hangup
    next: END
:::
```

```yaml skills/default_silence_timeout/responses.yml theme={null}
responses:
  utter_silence_timeout_check_in:
    - text: "Are you still there? I'm ready to continue whenever you are."
      metadata:
        rephrase: true
  utter_inform_hangup:
    - text: "I haven't heard from you, so I'll end the call now. Goodbye."
      metadata:
        rephrase: true
```

This skill has no `memory.yml`.

## Other packaged responses

These names live in the packaged defaults, not in one of the skills above.
Override them the same way: declare the name in your own `responses.yml`.

| Name | When it is sent | Default text |
| - | - | - |
| `utter_precondition_unmet` | A precondition resolver finishes once without satisfying the waiting skill, and `unmet_utterance` is not `false`. See [`preconditions`](/reference/agent-yml#preconditions). | I'm sorry, I wasn't able to continue with that request. |
| `utter_hangup_goodbye` | The turn ends the call with hangup and no goodbye was already produced. | Thanks for calling. Goodbye. |
| `utter_set_memory_button_skipped` | A tapped button can no longer be applied. | See [Stale-button default response](/reference/responses-yml#stale-button-default-response). |
| `utter_model_request_hook_error` | A fail-closed `modify_model_request` hook crashes or times out. | See [Turn-error fallbacks](/reference/responses-yml#turn-error-fallbacks). |
| `utter_tool_call_hook_error` | A fail-closed `modify_tool_call` hook crashes or times out. | See [Turn-error fallbacks](/reference/responses-yml#turn-error-fallbacks). |
| `utter_model_call_error` | The main model call fails. | See [Turn-error fallbacks](/reference/responses-yml#turn-error-fallbacks). |

`rephrase` on the three turn-error names is ignored. `utter_hangup_goodbye`
honours `rephrase` when you set it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.