OpenMAIC-React / src /lib /types /action.ts
muthuk1's picture
Convert OpenMAIC from Next.js to React (Vite)
f56a29b verified
raw
history blame
8.46 kB
/**
* Unified Action System
*
* Actions are the sole mechanism for agents to interact with the presentation.
* Two categories:
* - Fire-and-forget: visual effects on slides (spotlight, laser)
* - Synchronous: must wait for completion before next action (speech, whiteboard, discussion)
*
* Both online (streaming) and offline (playback) paths consume the same Action types.
*/
// ==================== Base ====================
export interface ActionBase {
id: string;
title?: string;
description?: string;
}
// ==================== Fire-and-forget actions ====================
/** Spotlight β€” focus on a single element, dim everything else */
export interface SpotlightAction extends ActionBase {
type: 'spotlight';
elementId: string;
dimOpacity?: number; // default 0.5
}
/** Laser β€” point at an element with a laser effect */
export interface LaserAction extends ActionBase {
type: 'laser';
elementId: string;
color?: string; // default '#ff0000'
}
// ==================== Synchronous actions ====================
/** Speech β€” teacher narration (wait for TTS to finish) */
export interface SpeechAction extends ActionBase {
type: 'speech';
text: string;
audioId?: string;
audioUrl?: string; // Server-generated TTS audio URL
voice?: string;
speed?: number; // default 1.0
}
/** Open whiteboard (wait for animation) */
export interface WbOpenAction extends ActionBase {
type: 'wb_open';
}
/** Draw text on whiteboard (wait for render) */
export interface WbDrawTextAction extends ActionBase {
type: 'wb_draw_text';
elementId?: string; // Custom element ID for later reference (e.g. wb_delete)
content: string; // HTML string or plain text
x: number;
y: number;
width?: number; // default 400
height?: number; // default 100
fontSize?: number; // default 18
color?: string; // default '#333333'
}
/** Draw shape on whiteboard (wait for render) */
export interface WbDrawShapeAction extends ActionBase {
type: 'wb_draw_shape';
elementId?: string; // Custom element ID for later reference (e.g. wb_delete)
shape: 'rectangle' | 'circle' | 'triangle';
x: number;
y: number;
width: number;
height: number;
fillColor?: string; // default '#5b9bd5'
}
/** Draw chart on whiteboard (wait for render) */
export interface WbDrawChartAction extends ActionBase {
type: 'wb_draw_chart';
elementId?: string; // Custom element ID for later reference (e.g. wb_delete)
chartType: 'bar' | 'column' | 'line' | 'pie' | 'ring' | 'area' | 'radar' | 'scatter';
x: number;
y: number;
width: number;
height: number;
data: {
labels: string[];
legends: string[];
series: number[][];
};
themeColors?: string[];
}
/** Draw LaTeX formula on whiteboard (wait for render) */
export interface WbDrawLatexAction extends ActionBase {
type: 'wb_draw_latex';
elementId?: string; // Custom element ID for later reference (e.g. wb_delete)
latex: string;
x: number;
y: number;
width?: number; // default 400
height?: number; // auto-calculated based on formula aspect ratio
color?: string; // default '#000000'
}
/** Draw table on whiteboard (wait for render) */
export interface WbDrawTableAction extends ActionBase {
type: 'wb_draw_table';
elementId?: string; // Custom element ID for later reference (e.g. wb_delete)
x: number;
y: number;
width: number;
height: number;
data: string[][]; // Simplified 2D string array, first row is header
outline?: { width: number; style: string; color: string };
theme?: { color: string };
}
/** Draw line/arrow on whiteboard (wait for render) */
export interface WbDrawLineAction extends ActionBase {
type: 'wb_draw_line';
elementId?: string; // Custom element ID for later reference (e.g. wb_delete)
startX: number; // Start X position (0-1000)
startY: number; // Start Y position (0-562)
endX: number; // End X position (0-1000)
endY: number; // End Y position (0-562)
color?: string; // Default '#333333'
width?: number; // Line width, default 2
style?: 'solid' | 'dashed'; // Default 'solid'
points?: ['', 'arrow'] | ['arrow', ''] | ['arrow', 'arrow'] | ['', '']; // Endpoint markers, default ['', '']
}
/** Clear all whiteboard elements */
export interface WbClearAction extends ActionBase {
type: 'wb_clear';
}
/** Delete a specific whiteboard element by ID */
export interface WbDeleteAction extends ActionBase {
type: 'wb_delete';
elementId: string;
}
/** Close whiteboard (wait for animation) */
export interface WbCloseAction extends ActionBase {
type: 'wb_close';
}
/** Draw code block on whiteboard (wait for typing animation) */
export interface WbDrawCodeAction extends ActionBase {
type: 'wb_draw_code';
elementId?: string;
language: string;
code: string; // Raw code text, lines separated by \n
x: number;
y: number;
width?: number; // Default 500
height?: number; // Default 300
fileName?: string;
}
/** Edit code block on whiteboard (line-level operations) */
export interface WbEditCodeAction extends ActionBase {
type: 'wb_edit_code';
elementId: string; // Target code block ID
operation: 'insert_after' | 'insert_before' | 'delete_lines' | 'replace_lines';
lineId?: string; // Reference line ID for insert operations
lineIds?: string[]; // Target line IDs for delete/replace operations
content?: string; // New content for insert/replace, lines separated by \n
}
/** Play video β€” start playback of a video element on the slide */
export interface PlayVideoAction extends ActionBase {
type: 'play_video';
elementId: string;
}
/** Discussion β€” trigger a roundtable discussion */
export interface DiscussionAction extends ActionBase {
type: 'discussion';
topic: string;
prompt?: string;
agentId?: string;
}
// ==================== Widget Interaction Actions ====================
/** Widget Highlight β€” highlight an element in a widget iframe */
export interface WidgetHighlightAction extends ActionBase {
type: 'widget_highlight';
target: string; // CSS selector or element ID in the iframe
content?: string; // Speech text to accompany the highlight
}
/** Widget SetState β€” set widget state (e.g., simulation variables) */
export interface WidgetSetStateAction extends ActionBase {
type: 'widget_setState';
state: Record<string, unknown>;
content?: string; // Speech text to accompany the state change
}
/** Widget Annotation β€” add floating annotation to an element */
export interface WidgetAnnotationAction extends ActionBase {
type: 'widget_annotation';
target: string;
content?: string;
}
/** Widget Reveal β€” reveal hidden content in widget */
export interface WidgetRevealAction extends ActionBase {
type: 'widget_reveal';
target: string;
content?: string;
}
// ==================== Union type ====================
export type Action =
| SpotlightAction
| LaserAction
| PlayVideoAction
| SpeechAction
| WbOpenAction
| WbDrawTextAction
| WbDrawShapeAction
| WbDrawChartAction
| WbDrawLatexAction
| WbDrawTableAction
| WbDrawLineAction
| WbClearAction
| WbDeleteAction
| WbCloseAction
| WbDrawCodeAction
| WbEditCodeAction
| DiscussionAction
| WidgetHighlightAction
| WidgetSetStateAction
| WidgetAnnotationAction
| WidgetRevealAction;
export type ActionType = Action['type'];
/** Action types that fire immediately without blocking */
export const FIRE_AND_FORGET_ACTIONS: ActionType[] = ['spotlight', 'laser'];
/** Action types that only work on slide scenes (require slide canvas elements) */
export const SLIDE_ONLY_ACTIONS: ActionType[] = ['spotlight', 'laser'];
/** Action types that must complete before the next action runs */
export const SYNC_ACTIONS: ActionType[] = [
'speech',
'play_video',
'wb_open',
'wb_draw_text',
'wb_draw_shape',
'wb_draw_chart',
'wb_draw_latex',
'wb_draw_table',
'wb_draw_line',
'wb_draw_code',
'wb_edit_code',
'wb_clear',
'wb_delete',
'wb_close',
'discussion',
'widget_highlight',
'widget_setState',
'widget_annotation',
'widget_reveal',
];
// ==================== Canvas utility types (non-action) ====================
/**
* Percentage-based geometry (0-100 coordinate system)
* Used by spotlight/laser overlays for responsive positioning.
*/
export interface PercentageGeometry {
x: number; // 0-100
y: number; // 0-100
w: number; // 0-100
h: number; // 0-100
centerX: number; // 0-100
centerY: number; // 0-100
}