# How the OpenMAIC Two-Stage Lesson Generation Pipeline Works

> Explore the OpenMAIC two stage lesson generation pipeline. Learn how stage-design and slide-craft skills create structured lesson plans and visual slide content.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: internals
- Published: 2026-09-01

---

**The OpenMAIC two-stage lesson generation pipeline uses a skill-based orchestration engine that first generates a structured lesson plan using the `stage-design` skill, then transforms that plan into visual slide content using the `slide-craft` skill.**

The THU-MAIC/OpenMAIC platform implements this pipeline through its **Agent Runtime** to convert natural language prompts into complete educational content. According to the source code in `src/agent-runtime/*`, the system treats lesson creation as a dependent multi-skill task where the output of the first stage becomes the input for the second.

## Pipeline Architecture Overview

The two-stage lesson generation pipeline consists of distinct phases orchestrated by the skill registry and pre-load resolver. Each stage corresponds to a registered skill handler that transforms the lesson state.

| Stage | Skill Name | Primary Output | Description |
|-------|------------|----------------|-------------|
| **1** | `stage-design` | **Lesson Plan** (JSON) | Generates structured outline with goals, sections, and key points |
| **2** | `slide-craft` | **Slide Deck** (HTML/MD) | Converts the lesson plan into visual slide content with media placeholders |

The runtime stores intermediate artifacts in a **ledger** system ([`tests/lib/orchestration/whiteboard-ledger.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/lib/orchestration/whiteboard-ledger.test.ts)), allowing the second stage to access the first stage's output without direct coupling between skill implementations.

## Stage 1: Stage-Design Skill

The `stage-design` skill executes first when the Agent Runtime detects a lesson generation request. Implemented in `src/skills/stage-design/*`, this skill handler calls the LLM to produce a structured lesson plan.

The skill inference logic identifies `stage-design` as the primary handler through the `leadingSkillHandle` function. When a user submits a prompt like `/stage-design /slide-craft build a lesson`, the runtime extracts the leading skill from the command:

```typescript
// tests/agent-runtime/skill-handle-inference.test.ts
// Detect the first skill keyword in a user prompt
expect(leadingSkillHandle('/stage-design /slide-craft build a lesson')).toBe('stage-design');

```

The expected output shape follows the lesson plan schema validated in [`tests/lib/orchestration/whiteboard-ledger.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/lib/orchestration/whiteboard-ledger.test.ts):

```typescript
{
  kind: 'lesson-plan',
  sections: [
    { title: 'Introduction', points: ['Goal 1', 'Goal 2'] },
    { title: 'Main Concept', points: ['Explain X', 'Show example'] },
    // …
  ]
}

```

Once generated, the runtime commits this plan to the ledger, making it available for the subsequent slide generation phase.

## Stage 2: Slide-Craft Skill

The `slide-craft` skill, implemented in `src/skills/slide-craft/*`, receives the lesson plan JSON from the ledger and generates the final presentation assets. This skill produces markdown or HTML content for each section defined in the plan.

The output format follows the slide deck structure defined in [`tests/lib/orchestration/state-context.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/lib/orchestration/state-context.test.ts):

```typescript
{
  kind: 'slide-deck',
  slides: [
    { title: 'Introduction', markdown: '# Intro\n…' },

    { title: 'Main Concept', markdown: '# Concept\n…' },

    // …
  ]
}

```

The skill handler processes each section of the lesson plan sequentially, generating visual content with appropriate titles, text blocks, and media placeholders. The resulting slides are stored as **assets** and attached to the lesson ledger, completing the transformation from outline to visual presentation.

## Orchestration and Execution Flow

The **Agent Runtime** manages the execution sequence through a pre-load phase that resolves skill dependencies. When processing a lesson generation request, the runtime performs four distinct operations:

1. **Prompt Parsing**: Extracts skill commands from the user input using the inference logic in [`agent-runtime/skill-handle-inference.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/agent-runtime/skill-handle-inference.test.ts)

2. **Skill Registration**: Validates that both `stage-design` and `slide-craft` handlers exist in the global skill registry under `agent-runtime/skills/*`

3. **Pre-load Resolution**: Determines the execution order via the preload mechanism demonstrated in [`tests/agent-runtime/skill-preload.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/agent-runtime/skill-preload.test.ts):

```typescript
const result = await preload('/stage-design /slide-craft build a lesson', {
  // …options…
});
expect(result.requested).toEqual(['stage-design', 'slide-craft']);

```

4. **Sequential Execution**: Iterates over the resolved skill list, passing the ledger state between stages

The orchestrator ensures that `slide-craft` only begins after `stage-design` completes successfully and writes to the ledger. This dependency chain prevents race conditions and guarantees data availability.

## Data Flow and Ledger Management

The **ledger** serves as the state management layer for the two-stage lesson generation pipeline. Located in the orchestration layer ([`tests/lib/orchestration/whiteboard-ledger.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/lib/orchestration/whiteboard-ledger.test.ts)), this system persists intermediate artifacts between skill executions.

When `stage-design` completes, it writes the lesson plan JSON to the ledger with the kind identifier `'lesson-plan'`. The `slide-craft` skill then queries the ledger for this specific artifact type, using the sections array to generate corresponding slides.

This architecture decouples the skills from direct data passing, allowing the runtime to inject additional processing steps or handle failures at specific stages without losing the overall lesson state.

## End-to-End Implementation Example

The complete pipeline execution is validated through the end-to-end test suite in [`e2e/tests/generation-flow.spec.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/e2e/tests/generation-flow.spec.ts). This specification demonstrates the full flow from user prompt to rendered slide deck:

```typescript
await page.goto('/');                         // OpenMAIC UI
await page.getByPlaceholder('Ask OpenMAIC').fill('Build a lesson');
await page.getByRole('button', { name: /Send/ }).click();

// Stage-Design finishes → a lesson plan appears in the ledger
await expect(page.locator('.ledger-item')).toContainText('Lesson Plan');

// Slide-Craft finishes → generated slides are displayed
await expect(page.locator('.slide')).toHaveCount(> 0);

```

After both skills finish execution, the runtime aggregates the plan and slides into a single **lesson artifact** that the front-end workbench loads. The final output includes both the structured lesson plan metadata and the rendered slide content accessible via a generated URL.

## Summary

- The OpenMAIC two-stage lesson generation pipeline separates content planning from visual presentation through distinct `stage-design` and `slide-craft` skills.
- The Agent Runtime orchestrates execution using a pre-load resolver that determines skill ordering based on the prompt input.
- Intermediate data persists in a ledger system ([`whiteboard-ledger.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/whiteboard-ledger.test.ts)), enabling state transfer between dependent pipeline stages.
- Each skill implementation resides in `src/skills/stage-design/*` and `src/skills/slide-craft/*`, registering handlers in the global skill registry.
- The complete workflow is validated through E2E tests in [`generation-flow.spec.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/generation-flow.spec.ts), ensuring reliable transformation from natural language prompts to structured lesson content.

## Frequently Asked Questions

### What distinguishes the stage-design skill from the slide-craft skill in the OpenMAIC pipeline?

The `stage-design` skill focuses on pedagogical structure, generating a JSON lesson plan that defines sections, learning goals, and key points. The `slide-craft` skill handles presentation logic, transforming that structured plan into visual slide decks with markdown formatting and media placeholders. According to the source code in `src/skills/`, these represent distinct concerns: content architecture versus visual rendering.

### How does the Agent Runtime determine the correct execution order for lesson generation skills?

The runtime uses the preload mechanism defined in [`tests/agent-runtime/skill-preload.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/agent-runtime/skill-preload.test.ts) to resolve an ordered array of skills from the user prompt. When it detects `/stage-design /slide-craft` commands, the resolver returns `["stage-design", "slide-craft"]`, ensuring sequential execution. The orchestrator then iterates through this array, executing each skill handler only after the previous skill completes and writes to the ledger.

### What happens if the slide-craft skill fails after stage-design completes successfully?

The ledger architecture in [`tests/lib/orchestration/whiteboard-ledger.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/lib/orchestration/whiteboard-ledger.test.ts) preserves the lesson plan output from the completed `stage-design` stage. This allows the runtime to retry the `slide-craft` execution without regenerating the plan, or to resume the pipeline from the failed stage. The decoupled design ensures that partial failures do not invalidate completed work in the two-stage lesson generation pipeline.

### Can additional skills be inserted between stage-design and slide-craft?

Yes, the skill registry architecture in `src/agent-runtime/skills/*` supports extending the pipeline. The preload resolver can accommodate additional skills in the ordered list, such as content review or translation skills, by registering new handlers and including them in the prompt command sequence (e.g., `/stage-design /review /slide-craft`). The ledger system facilitates data passing between any number of sequential stages.