mirror of
https://github.com/soconnor0919/hristudio.git
synced 2026-02-04 23:46:32 -05:00
feat: Implement collapsible left and right panels with dynamic column spanning, updated styling, and integrated a bottom status bar in the DesignerRoot.
This commit is contained in:
@@ -159,6 +159,7 @@ async function main() {
|
||||
status: "ready",
|
||||
robotId: naoRobot!.id,
|
||||
createdBy: adminUser.id,
|
||||
// visualDesign will be auto-generated by designer from DB steps
|
||||
}).returning();
|
||||
|
||||
// 5. Create Steps & Actions (The Interactive Storyteller Protocol)
|
||||
@@ -168,98 +169,116 @@ async function main() {
|
||||
const [step1] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment!.id,
|
||||
name: "The Hook",
|
||||
description: "Initial greeting and engagement",
|
||||
description: "Initial greeting and story introduction",
|
||||
type: "robot",
|
||||
orderIndex: 0,
|
||||
required: true,
|
||||
durationEstimate: 30
|
||||
durationEstimate: 25
|
||||
}).returning();
|
||||
|
||||
await db.insert(schema.actions).values([
|
||||
{
|
||||
stepId: step1!.id,
|
||||
name: "Greet Participant",
|
||||
type: "nao6-ros2.say_with_emotion",
|
||||
name: "Introduce Story",
|
||||
type: "nao6-ros2.say_text",
|
||||
orderIndex: 0,
|
||||
parameters: { text: "Hello there! I have a wonderful story to share with you today.", emotion: "happy", speed: 1.0 },
|
||||
pluginId: naoPlugin!.id,
|
||||
parameters: { text: "Hello. I have a story to tell you about a space traveler. Are you ready?" },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "interaction",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step1!.id,
|
||||
name: "Wave Greeting",
|
||||
name: "Welcome Gesture",
|
||||
type: "nao6-ros2.move_arm",
|
||||
orderIndex: 1,
|
||||
// Raising right arm to wave position
|
||||
// Open hand/welcome position
|
||||
parameters: {
|
||||
arm: "right",
|
||||
shoulder_pitch: -1.0,
|
||||
shoulder_roll: -0.3,
|
||||
elbow_yaw: 1.5,
|
||||
elbow_roll: 0.5,
|
||||
speed: 0.5
|
||||
shoulder_pitch: 1.0,
|
||||
shoulder_roll: -0.2,
|
||||
elbow_yaw: 0.5,
|
||||
elbow_roll: -0.4,
|
||||
speed: 0.4
|
||||
},
|
||||
pluginId: naoPlugin!.id,
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "movement",
|
||||
retryable: true
|
||||
}
|
||||
]);
|
||||
|
||||
// --- Step 2: The Narrative (Part 1) ---
|
||||
// --- Step 2: The Narrative ---
|
||||
const [step2] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment!.id,
|
||||
name: "The Narrative - Part 1",
|
||||
description: "Robot tells the first part of the story",
|
||||
name: "The Narrative",
|
||||
description: "Robot tells the space traveler story with gaze behavior",
|
||||
type: "robot",
|
||||
orderIndex: 1,
|
||||
required: true,
|
||||
durationEstimate: 60
|
||||
}).returning();
|
||||
|
||||
await db.insert(schema.actions).values([
|
||||
{
|
||||
stepId: step2!.id,
|
||||
name: "Tell Story Part 1",
|
||||
type: "nao6-ros2.say_text",
|
||||
orderIndex: 0,
|
||||
parameters: { text: "Once upon a time, in a land far away, there lived a curious robot named Alpha." },
|
||||
pluginId: naoPlugin!.id,
|
||||
category: "interaction"
|
||||
},
|
||||
{
|
||||
stepId: step2!.id,
|
||||
name: "Look at Audience",
|
||||
type: "nao6-ros2.move_head",
|
||||
orderIndex: 1,
|
||||
parameters: { yaw: 0.0, pitch: -0.2, speed: 0.5 },
|
||||
pluginId: naoPlugin!.id,
|
||||
category: "movement"
|
||||
}
|
||||
]);
|
||||
|
||||
// --- Step 3: Comprehension Check (Wizard Decision) ---
|
||||
// Note: In a real visual designer, this would be a Branch/Conditional.
|
||||
// Here we model it as a Wizard Step where they explicitly choose the next robot action.
|
||||
const [step3] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment!.id,
|
||||
name: "Comprehension Check",
|
||||
description: "Wizard verifies participant understanding",
|
||||
type: "wizard",
|
||||
orderIndex: 2,
|
||||
required: true,
|
||||
durationEstimate: 45
|
||||
}).returning();
|
||||
|
||||
await db.insert(schema.actions).values([
|
||||
{
|
||||
stepId: step2!.id,
|
||||
name: "Tell Story",
|
||||
type: "nao6-ros2.say_text",
|
||||
orderIndex: 0,
|
||||
parameters: { text: "The traveler flew to Mars. He found a red rock that glowed in the dark. He put it in his pocket." },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "interaction",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step2!.id,
|
||||
name: "Look Away (Thinking)",
|
||||
type: "nao6-ros2.turn_head",
|
||||
orderIndex: 1,
|
||||
parameters: { yaw: 1.5, pitch: 0.0, speed: 0.3 },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "movement",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step2!.id,
|
||||
name: "Look Back at Participant",
|
||||
type: "nao6-ros2.turn_head",
|
||||
orderIndex: 2,
|
||||
parameters: { yaw: 0.0, pitch: -0.1, speed: 0.4 },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "movement",
|
||||
retryable: true
|
||||
}
|
||||
]);
|
||||
|
||||
// --- Step 3: Comprehension Check (Wizard Decision Point) ---
|
||||
// Note: Wizard will choose to proceed to Step 4a (Correct) or 4b (Incorrect)
|
||||
const [step3] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment!.id,
|
||||
name: "Comprehension Check",
|
||||
description: "Ask participant about rock color and wait for wizard input",
|
||||
type: "wizard",
|
||||
orderIndex: 2,
|
||||
required: true,
|
||||
durationEstimate: 30
|
||||
}).returning();
|
||||
|
||||
await db.insert(schema.actions).values([
|
||||
{
|
||||
stepId: step3!.id,
|
||||
name: "Ask Question",
|
||||
type: "nao6-ros2.say_with_emotion",
|
||||
type: "nao6-ros2.say_text",
|
||||
orderIndex: 0,
|
||||
parameters: { text: "Did you understand the story so far?", emotion: "happy", speed: 1.0 },
|
||||
pluginId: naoPlugin!.id,
|
||||
category: "interaction"
|
||||
parameters: { text: "What color was the rock the traveler found?" },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "interaction",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step3!.id,
|
||||
@@ -267,7 +286,7 @@ async function main() {
|
||||
type: "wizard_wait_for_response",
|
||||
orderIndex: 1,
|
||||
parameters: {
|
||||
prompt_text: "Did participant answer 'Alpha'?",
|
||||
prompt_text: "Did participant answer 'Red' correctly?",
|
||||
response_type: "verbal",
|
||||
timeout: 60
|
||||
},
|
||||
@@ -276,36 +295,108 @@ async function main() {
|
||||
}
|
||||
]);
|
||||
|
||||
// --- Step 4: Feedback (Positive/Negative branches implied) ---
|
||||
// For linear seed, we just add the Positive feedback step
|
||||
const [step4] = await db.insert(schema.steps).values({
|
||||
// --- Step 4a: Correct Response Branch ---
|
||||
const [step4a] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment!.id,
|
||||
name: "Positive Feedback",
|
||||
description: "Correct answer response",
|
||||
name: "Branch A: Correct Response",
|
||||
description: "Response when participant says 'Red'",
|
||||
type: "robot",
|
||||
orderIndex: 3,
|
||||
required: true,
|
||||
durationEstimate: 15
|
||||
required: false,
|
||||
durationEstimate: 20
|
||||
}).returning();
|
||||
|
||||
await db.insert(schema.actions).values([
|
||||
{
|
||||
stepId: step4!.id,
|
||||
name: "Express Agreement",
|
||||
stepId: step4a!.id,
|
||||
name: "Confirm Correct Answer",
|
||||
type: "nao6-ros2.say_with_emotion",
|
||||
orderIndex: 0,
|
||||
parameters: { text: "Yes, exactly!", emotion: "happy", speed: 1.0 },
|
||||
pluginId: naoPlugin!.id,
|
||||
category: "interaction"
|
||||
parameters: { text: "Yes! It was a glowing red rock.", emotion: "happy", speed: 1.0 },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "interaction",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step4!.id,
|
||||
name: "Say Correct",
|
||||
type: "nao6-ros2.say_text",
|
||||
stepId: step4a!.id,
|
||||
name: "Nod Head",
|
||||
type: "nao6-ros2.turn_head",
|
||||
orderIndex: 1,
|
||||
parameters: { text: "That is correct! Well done." },
|
||||
pluginId: naoPlugin!.id,
|
||||
category: "interaction"
|
||||
parameters: { yaw: 0.0, pitch: -0.3, speed: 0.5 },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "movement",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step4a!.id,
|
||||
name: "Return to Neutral",
|
||||
type: "nao6-ros2.turn_head",
|
||||
orderIndex: 2,
|
||||
parameters: { yaw: 0.0, pitch: 0.0, speed: 0.4 },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "movement",
|
||||
retryable: true
|
||||
}
|
||||
]);
|
||||
|
||||
// --- Step 4b: Incorrect Response Branch ---
|
||||
const [step4b] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment!.id,
|
||||
name: "Branch B: Incorrect Response",
|
||||
description: "Response when participant gives wrong answer",
|
||||
type: "robot",
|
||||
orderIndex: 4,
|
||||
required: false,
|
||||
durationEstimate: 20
|
||||
}).returning();
|
||||
|
||||
await db.insert(schema.actions).values([
|
||||
{
|
||||
stepId: step4b!.id,
|
||||
name: "Correct Participant",
|
||||
type: "nao6-ros2.say_text",
|
||||
orderIndex: 0,
|
||||
parameters: { text: "Actually, it was red." },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "interaction",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step4b!.id,
|
||||
name: "Shake Head (Left)",
|
||||
type: "nao6-ros2.turn_head",
|
||||
orderIndex: 1,
|
||||
parameters: { yaw: -0.5, pitch: 0.0, speed: 0.5 },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "movement",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step4b!.id,
|
||||
name: "Shake Head (Right)",
|
||||
type: "nao6-ros2.turn_head",
|
||||
orderIndex: 2,
|
||||
parameters: { yaw: 0.5, pitch: 0.0, speed: 0.5 },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "movement",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step4b!.id,
|
||||
name: "Return to Center",
|
||||
type: "nao6-ros2.turn_head",
|
||||
orderIndex: 3,
|
||||
parameters: { yaw: 0.0, pitch: 0.0, speed: 0.4 },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "movement",
|
||||
retryable: true
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -313,31 +404,42 @@ async function main() {
|
||||
const [step5] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment!.id,
|
||||
name: "Conclusion",
|
||||
description: "Wrap up the story",
|
||||
description: "End the story and thank participant",
|
||||
type: "robot",
|
||||
orderIndex: 4,
|
||||
orderIndex: 5,
|
||||
required: true,
|
||||
durationEstimate: 30
|
||||
durationEstimate: 25
|
||||
}).returning();
|
||||
|
||||
await db.insert(schema.actions).values([
|
||||
{
|
||||
stepId: step5!.id,
|
||||
name: "Finish Story",
|
||||
name: "End Story",
|
||||
type: "nao6-ros2.say_text",
|
||||
orderIndex: 0,
|
||||
parameters: { text: "Alpha explored the world and learned many things. The end." },
|
||||
pluginId: naoPlugin!.id,
|
||||
category: "interaction"
|
||||
parameters: { text: "The End. Thank you for listening." },
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "interaction",
|
||||
retryable: true
|
||||
},
|
||||
{
|
||||
stepId: step5!.id,
|
||||
name: "Say Goodbye",
|
||||
type: "nao6-ros2.say_with_emotion",
|
||||
name: "Bow Gesture",
|
||||
type: "nao6-ros2.move_arm",
|
||||
orderIndex: 1,
|
||||
parameters: { text: "Goodbye everyone!", emotion: "happy", speed: 1.0 },
|
||||
pluginId: naoPlugin!.id,
|
||||
category: "interaction"
|
||||
parameters: {
|
||||
arm: "right",
|
||||
shoulder_pitch: 1.8,
|
||||
shoulder_roll: 0.1,
|
||||
elbow_yaw: 0.0,
|
||||
elbow_roll: -0.3,
|
||||
speed: 0.3
|
||||
},
|
||||
pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
|
||||
pluginVersion: "2.1.0",
|
||||
category: "movement",
|
||||
retryable: true
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -360,7 +462,13 @@ async function main() {
|
||||
console.log(`Summary:`);
|
||||
console.log(`- 1 Admin User (sean@soconnor.dev)`);
|
||||
console.log(`- Study: 'Comparative WoZ Study'`);
|
||||
console.log(`- Experiment: 'The Interactive Storyteller' (${5} steps created)`);
|
||||
console.log(`- Experiment: 'The Interactive Storyteller' (6 steps created)`);
|
||||
console.log(` - Step 1: The Hook (greeting + welcome gesture)`);
|
||||
console.log(` - Step 2: The Narrative (story + gaze sequence)`);
|
||||
console.log(` - Step 3: Comprehension Check (question + wizard wait)`);
|
||||
console.log(` - Step 4a: Branch A - Correct Response (affirmation + nod)`);
|
||||
console.log(` - Step 4b: Branch B - Incorrect Response (correction + head shake)`);
|
||||
console.log(` - Step 5: Conclusion (ending + bow)`);
|
||||
console.log(`- ${insertedParticipants.length} Participants`);
|
||||
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user