# How the @openmaic/dsl Package Defines Course and Slide Data Contracts

> Discover how the @openmaic/dsl package uses TypeScript interfaces to define course and slide data contracts, ensuring runtime validation and versioned serialization for educational content.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: api-reference
- Published: 2026-09-02

---

**The @openmaic/dsl package defines typed contracts for courses (Stage) and slides through TypeScript interfaces in [`src/stage.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/stage.ts) and [`src/slides.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/slides.ts), providing runtime validation and versioned serialization for OpenMAIC's educational content.**

The `@openmaic/dsl` package serves as the foundational schema layer for the OpenMAIC platform, establishing strict data contracts that govern how courses and slides are structured, validated, and persisted. These contracts enable seamless exchange between content authoring tools, the runtime engine, and storage systems while maintaining backward compatibility through semantic versioning. Understanding these data models is essential for developers integrating with the OpenMAIC ecosystem or extending its functionality.

## The Stage Contract: Course Metadata and Configuration

The primary data contract for a course in OpenMAIC is the **Stage** interface, defined in [[`src/stage.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/stage.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/stage.ts#L141-L150). This contract represents the complete metadata container for a learning unit, encompassing both presentation data and behavioral configuration.

The Stage interface requires core identification fields including `id`, `name`, and `description`, alongside timestamp fields (`createdAt`, `updatedAt`) for tracking modifications. Beyond basic metadata, the contract supports:

- **Localization directives** via the optional `language` field
- **Visual styling** through customizable theme configurations
- **Whiteboard initialization data** for collaborative drawing surfaces
- **Video manifest references** for synchronized media playback
- **Agent orchestration** through `agentIds` and `generatedAgentConfigs` arrays
- **Mode flags** including `interactiveMode` and `taskEngineMode` for controlling runtime behavior

This pure data model acts as the single source of truth that the runtime engine consumes to instantiate classroom environments, while DSL exporters serialize the structure for persistent storage or network transport.

## The Slide Contract: Content Structure and Presentation

Individual learning units are defined by the **Slide** interface, located in [[`src/slides.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/slides.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/slides.ts#L53-L70). This contract describes PPT-style content with precise viewport and element specifications necessary for consistent rendering across devices.

### Core Slide Properties

Every slide requires a unique `id` and dimensional constraints specified through `viewportSize` and `viewportRatio` parameters. The visual foundation is established via the `theme` property, which controls background colors, theme palettes, and typography defaults. The content layer is defined through an `elements` array containing shape primitives, text nodes, and media embeds typed as `PPTElement`.

### Advanced Presentation Features

The Slide contract supports sophisticated presentation behaviors through optional fields:

- **SlideBackground** objects for complex backdrop configurations
- **PPTAnimation** arrays declaring entrance, emphasis, and exit sequences
- **Turning modes** specifying click or auto-advance transition behaviors
- **Section tags** for organizational grouping within longer courses
- **Speaker scripts** containing narration notes or instructor guidance

All element types—including `SlideBackground`, `PPTAnimation`, and specialized shape primitives—are exhaustively documented within the same source file, creating a rich, extensible type system for educational content description.

## Content Wrappers and Schema Versioning

To facilitate safe serialization and future-proof the data model, the DSL package implements the **SlideContent** wrapper interface in [[`src/stage.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/stage.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/stage.ts#L84-L88). This discriminated union structure requires a `type: 'slide'` discriminator property and encapsulates the raw `Slide` object within a `canvas` property.

The wrapper includes an optional `schemaVersion` field enabling forward-compatible migrations. When the OpenMAIC platform introduces structural changes to the data contracts, version identifiers allow the normalization utilities in [`src/normalize.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/normalize.ts) to transform legacy payloads automatically without breaking existing course archives.

## Legacy Support: The Deprecated SlideData Interface

For backward compatibility with earlier OpenMAIC releases, the package maintains the **SlideData** interface in [[`src/slides.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/slides.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/slides.ts#L78-L92). This deprecated contract remains available exclusively for migration purposes. New implementations should strictly utilize the `Slide` and `SlideContent` contracts, as `SlideData` support will be removed in future major versions.

## Practical Implementation: Creating and Validating Courses

Developers interact with these contracts through standard TypeScript instantiation and the validation utilities provided by the package.

### Instantiating a Course with Slides

```typescript
import { Stage, Slide, SlideContent } from '@openmaic/dsl';

// Define a slide with viewport dimensions and empty element canvas
const slide: Slide = {
  id: 'slide-01',
  viewportSize: 1024,
  viewportRatio: 16 / 9,
  theme: {
    backgroundColor: '#ffffff',
    themeColors: ['#0066ff'],
    fontColor: '#000000',
    fontName: 'Helvetica',
  },
  elements: [],
  turningMode: 'click',
};

// Wrap with content discriminator and version metadata
const slideContent: SlideContent = {
  type: 'slide',
  schemaVersion: 1,
  canvas: slide,
};

// Assemble the complete Stage (course) contract
const course: Stage = {
  id: 'course-123',
  name: 'Intro to OpenMAIC',
  createdAt: Date.now(),
  updatedAt: Date.now(),
  languageDirective: 'en',
  whiteboard: [],
  videoManifest: undefined,
  agentIds: ['assistant'],
  generatedAgentConfigs: [],
  interactiveMode: true,
  taskEngineMode: false,
};

```

### Runtime Validation

The package exposes validation functions to ensure contract compliance before persistence:

```typescript
import { validate } from '@openmaic/dsl';

const payload = {
  stage: course,
  slides: [slideContent],
};

const issues = validate(payload);
if (issues.length) {
  console.error('Validation failed:', issues);
} else {
  console.log('Payload conforms to DSL schema');
}

```

## Summary

- The **Stage** interface in [`src/stage.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/stage.ts) defines complete course metadata including agent configurations, interactive flags, and whiteboard initialization data.
- The **Slide** interface in [`src/slides.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/slides.ts) specifies content structure through viewport dimensions, theme definitions, and typed element arrays.
- **SlideContent** wrappers in [`src/stage.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/stage.ts) provide discriminated union typing and `schemaVersion` fields for migration safety.
- The deprecated **SlideData** interface remains available in [`src/slides.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/slides.ts) solely for backward compatibility with legacy systems.
- Runtime validation utilities ensure that all persisted or transmitted objects conform strictly to the established data contracts.

## Frequently Asked Questions

### What is the difference between Slide and SlideContent in @openmaic/dsl?

The **Slide** interface defines the raw content and presentation properties including elements, themes, and viewport settings. **SlideContent** acts as a transport wrapper that adds a `type` discriminator and `schemaVersion` metadata. As implemented in the OpenMAIC source code, you should wrap Slide instances in SlideContent objects before serialization to ensure proper schema validation and version tracking.

### How does the Stage contract handle multiple languages or internationalization?

The Stage contract includes an optional `languageDirective` field that specifies the primary language for course content. While the interface does not enforce translation bundles directly, this metadata field enables runtime engines to select appropriate agent voices, UI localizations, and content adaptations. The contract remains agnostic to specific localization implementations, allowing platforms to layer their own i18n strategies atop the base schema.

### Can I extend the Slide contract with custom element types?

The current DSL architecture supports extensibility through the **PPTElement** union type defined in [`src/slides.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/slides.ts). While the base package provides standard primitive types, the element array structure accepts any object conforming to the basic element interface. For production extensions, implementers should maintain custom type guards and validation logic alongside the core DSL validators to ensure runtime safety when introducing non-standard element types.

### What happens when schemaVersion changes in existing course data?

The `@openmaic/dsl` package includes normalization utilities in [`src/normalize.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/normalize.ts) that handle schema migrations transparently. When loading content with an older `schemaVersion`, the runtime applies transformation functions to upgrade the payload to the current contract version. This forward-compatible approach ensures that courses created with earlier OpenMAIC releases continue functioning without manual intervention while allowing the platform to evolve its data models.