Interactive Skills Tutorial

From descriptor to executable flow using `.AchillesSkills` repositories. This walkthrough shows how interactive skills gather the right data without losing the conversational tone.

Directory Layout

The interactive skills used in the regression suite live under scenario-specific repositories. Example:

tests/iskills/missing-parameters/
└── .AchillesSkills/
    └── support/
        └── file_incident/
            ├── iskill.md
            └── file_incident.js

The folder name file_incident becomes the short name referenced by the runtime. The Markdown descriptor is mandatory; the JavaScript file is optional and only required when you need to override defaults.

Descriptor: iskill.md

The descriptor captures user-facing context and argument requirements.

# File Incident

Guide warehouse staff through capturing a support incident in business language, while ensuring
all required details are gathered before execution.

## Required Inputs

- Incident title
- Severity level

## Optional Inputs

- Assigned team for follow-up

## Behaviour

- Lists missing information using human-friendly wording.
- Differentiates between required and optional arguments.
- Confirms the action with a natural-language summary before execution.

The skill engine parses these sections and exposes them through prompts, confirmation narratives, and validation hints.

Optional Entry Point

When additional configuration is required, add a JavaScript file named after the skill. The interactive suite reuses the following file verbatim:

// tests/iskills/missing-parameters/.AchillesSkills/support/file_incident/file_incident.js
export const specs = {
    name: 'file_incident',
    humanDescription: 'a support incident record for the warehouse printers',
    description: 'File a support incident so the warehouse printers can be restored.',
    arguments: {
        incident_title: { type: 'string', description: 'Short incident headline' },
        severity: {
            type: 'string',
            description: 'Incident severity level',
            enumerator: () => [
                { label: 'Low', value: 'low' },
                { label: 'Medium', value: 'medium' },
                { label: 'High', value: 'high' },
            ],
            resolver: (value) => (typeof value === 'string' ? value.trim().toLowerCase() : value),
        },
        assigned_team: { type: 'string', description: 'Team that will follow up on the incident' },
    },
    requiredArguments: ['incident_title', 'severity'],
};

export const roles = ['support'];

export const action = (args) => ({ ...args });

Values exported by the entrypoint augment the descriptor. In this case we declare the canonical specs, restrict access to the support role, and simply echo the collected arguments during tests.

Runtime Behaviour

  1. The registry discovers iskill.md, merges specs/roles/action when present, and registers the skill.
  2. During execution the interactive skill prompts for incident_title and severity, showing descriptive hints from the descriptor.
  3. Enumerators and resolvers defined in specs enforce casing, synonyms, and fuzzy matching.
  4. Once all required arguments are present, the skill renders a confirmation narrative using the descriptor title and behaviour notes.

The regression tests (e.g. tests/iskills/missing-parameters/missingParameters.test.mjs) simulate full conversations against this repository, providing concrete reference flows.