How the OpenMAIC Two-Stage Lesson Generation Pipeline Works

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), 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:

// 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:

{
  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:

{
  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

  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:

const result = await preload('/stage-design /slide-craft build a lesson', {
  // …options…
});
expect(result.requested).toEqual(['stage-design', 'slide-craft']);
  1. 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), 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. This specification demonstrates the full flow from user prompt to rendered slide deck:

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), 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, 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 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →