AimdRecorder
Use AimdRecorder when you want AIMD inputs rendered inline inside the protocol flow.
Example
<script setup lang="ts">
import { ref } from "vue"
import {
AimdRecorder,
createEmptyProtocolRecordData,
type AimdProtocolRecordData,
} from "@airalogy/aimd-recorder"
import "@airalogy/aimd-recorder/styles"
const content = ref(`# Protocol
Sample: {{var|sample_name: str}}
Operator: {{var|operator: UserName}}
Record Time: {{var|current_time: CurrentTime}}
Temperature: {{var|temperature: float = 25.0}}
Notes: {{var|notes: AiralogyMarkdown}}
Plasmid: {{var|plasmid: DNASequence}}`)
const record = ref<AimdProtocolRecordData>(createEmptyProtocolRecordData())
</script>
<template>
<AimdRecorder
v-model="record"
:content="content"
locale="en-US"
current-user-name="Alice"
/>
</template>record shape:
{
"var": {},
"step": {},
"check": {},
"quiz": {}
}Built-In Recorder Behaviors
CurrentTimeandUserNamecan fill recorder values automatically from runtime context.AiralogyMarkdownrenders as a full-width embedded AIMD/Markdown editor, opens inSourcemode by default, keeps the full top toolbar, and still supports switching toWYSIWYG.DNASequencerenders a dedicated sequence widget with interactive and raw-structure modes, file import/export, topology switching, feature editing, andSeqViz-based visualization.ref_varreferences display current var values as readonly inline content when available.choice,true_false,blank,open, andscalequiz types all have built-in recorder inputs.- Numeric
varinputs honor Pydantic-style constraints such asgt,ge,lt,le, andmultiple_of; these constraints apply toint,integer,float, andnumbervar types. - Client assigners use the same numeric constraints for dependency readiness and skip execution while a dependent numeric field violates its declared bounds.
Client Assigner
Frontend-only client assigners run locally inside recorder mode.
Water: {{var|water_volume_ml: float}}
Lemon: {{var|lemon_juice_ml: float}}
Total: {{var|total_liquid_ml: float}}
```assigner runtime=client
assigner(
{
mode: "auto",
dependent_fields: ["water_volume_ml", "lemon_juice_ml"],
assigned_fields: ["total_liquid_ml"],
},
function calculate_total_liquid_ml({ water_volume_ml, lemon_juice_ml }) {
return {
total_liquid_ml: Math.round((water_volume_ml + lemon_juice_ml) * 100) / 100,
};
}
);
```For mode: "manual", AimdRecorder exposes explicit trigger methods through the component ref:
recorderRef.value?.runClientAssigner("calculate_total_liquid_ml")
recorderRef.value?.runManualClientAssigners()Locale And Quiz Recorder
Both AimdRecorder and AimdQuizRecorder accept locale to switch built-in recorder labels:
<AimdRecorder locale="zh-CN" />
<AimdQuizRecorder :quiz="quiz" locale="zh-CN" />Standalone quiz usage:
<script setup lang="ts">
import { ref } from "vue"
import { AimdQuizRecorder } from "@airalogy/aimd-recorder"
import "@airalogy/aimd-recorder/styles"
const answer = ref("")
const quiz = {
id: "quiz_single_1",
type: "choice",
mode: "single",
stem: "Choose one option",
options: [
{ key: "A", text: "Option A" },
{ key: "B", text: "Option B" },
],
}
</script>
<template>
<AimdQuizRecorder v-model="answer" :quiz="quiz" />
</template>If a choice or true_false option defines followups, the recorder shows those inputs only after the option is selected. For these quizzes the answer value is structured as { selected, followups }, while ordinary choice quizzes continue to use the legacy string or string-array shape and ordinary true/false quizzes continue to use booleans.
Showing Grade Results
If the host has already graded the answers elsewhere, pass the result back into AimdRecorder or AimdQuizRecorder for inline display. Deterministic scale quizzes can also compute a local score/classification inside the recorder.
Whole recorder:
<AimdRecorder
v-model="record"
:content="content"
:quiz-grades="quizGrades"
choice-option-explanation-mode="selected"
scale-grade-display-mode="submitted"
/>Standalone quiz:
<AimdQuizRecorder
v-model="answer"
:quiz="quiz"
choice-option-explanation-mode="graded"
:grade="{
quiz_id: 'quiz_single_1',
earned_score: 4,
max_score: 5,
status: 'partial',
method: 'keyword_rubric',
feedback: 'The answer is mostly correct but still misses one point.',
review_required: true,
}"
/>Recommended usage:
- grade
choiceand standardblankitems locally - grade deterministic
scaleitems locally, then usescaleGradeDisplayModeto control whether the result appears on completion or only after submit - use a backend provider for
openitems or highly flexible blanks - for practice, pass
quizGradesin real time so learners can immediately see status, score, and feedback - if a
choiceoption definesexplanation, usechoiceOptionExplanationMode="selected"to show that explanation immediately after the learner selects the option - if option explanations should appear only after the learner submits, combine
:submitted="isSubmitted"withchoiceOptionExplanationMode="submitted" - if a
scaleresult should appear only after submit, combine:submitted="isSubmitted"withscaleGradeDisplayMode="submitted" - if you want option explanations to appear only after grading is available, use
choiceOptionExplanationMode="graded" - for exams, omit
quizGradesuntil grading is finalized - unanswered quizzes with status
ungradeddo not show a grading panel by default - do not expose real model secrets in the browser for formal assessment flows
Homework / reveal-after-submit example:
<AimdRecorder
v-model="record"
:content="content"
:submitted="isSubmitted"
choice-option-explanation-mode="submitted"
/>submitted is controlled by the host app. AimdRecorder does not infer submission state on its own and does not include a built-in submit button.