Skip to content

Commit a8f98e4

Browse files
jeremymanningclaude
andcommitted
feat(demo-15): Enhance ALICE breakdown with detailed AIML explanations
- Add describeNormalization helper to explain preprocessing steps - Improve step descriptions to teach AIML concepts: - Input Normalization: Explain lowercase, punctuation, whitespace handling - Context Check: Explain <that> and <topic> constraint matching - Category Matching: Explain priority-based pattern search - Wildcard Extraction: Explain <star/> variable capture - SRAI: Explain recursive pattern matching for normalization - Template Expansion: List AIML features like <random>, <get/set> - Context Update: Explain how <that> enables follow-up responses - Add SRAI visualization to timeline-app.js with styled display - Use dynamic details messages based on actual transformations This helps students understand how ALICE's AIML approach differs from ELIZA's simple pattern matching through step-by-step visualization. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent b818890 commit a8f98e4

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

demos/15-chatbot-evolution/js/alice.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -695,29 +695,51 @@ export class Alice {
695695
this.context.topic = topic;
696696
}
697697

698+
/**
699+
* Describe what normalization was applied to input
700+
*/
701+
describeNormalization(original, normalized) {
702+
const changes = [];
703+
if (original !== original.toLowerCase()) {
704+
changes.push("lowercase");
705+
}
706+
if (/[?!.,:;]+$/.test(original)) {
707+
changes.push("removed punctuation");
708+
}
709+
if (/\\s{2,}/.test(original)) {
710+
changes.push("normalized whitespace");
711+
}
712+
if (original !== original.trim()) {
713+
changes.push("trimmed");
714+
}
715+
return changes.length > 0 ? changes.join(", ") : "minor cleanup";
716+
}
717+
698718
/**
699719
* Get detailed breakdown of response processing for visualization
720+
* Shows step-by-step how AIML processes input to generate responses
700721
*/
701722
getDetailedBreakdown(input) {
702723
const steps = [];
703724

704725
// Capture initial context
705726
const initialContext = { ...this.context };
706727

707-
// Step 1: Input normalization
728+
// Step 1: Input normalization (AIML preprocessing)
708729
const normalizedInput = this.normalize(input);
730+
const normChanged = input.toLowerCase().trim().replace(/[?!.,:;]+$/, "").replace(/\s+/g, " ") !== input;
709731
steps.push({
710732
name: 'Input Normalization',
711-
description: 'AIML normalizes input: lowercase, removes punctuation, collapses whitespace',
733+
description: 'AIML preprocessing: converts to lowercase, strips trailing punctuation, normalizes whitespace. This standardizes input for pattern matching.',
712734
input: input,
713735
output: normalizedInput,
714-
details: 'Standard AIML preprocessing applied'
736+
details: normChanged ? 'Transformations applied: ' + this.describeNormalization(input, normalizedInput) : 'No transformations needed'
715737
});
716738

717739
// Step 2: Context check
718740
steps.push({
719741
name: 'Context Check',
720-
description: 'Checking conversation context for <that> and <topic> constraints',
742+
description: 'AIML uses <that> (bot\'s last response) and <topic> tags to constrain pattern matching. Categories with matching constraints take priority.',
721743
contextInfo: {
722744
topic: this.context.topic,
723745
that: this.context.that || '(none)',
@@ -780,7 +802,7 @@ export class Alice {
780802

781803
steps.push({
782804
name: 'Category Matching',
783-
description: 'Testing input against AIML categories (sorted by priority)',
805+
description: 'AIML searches categories by priority: _ wildcards (highest) > exact patterns > * wildcards (lowest). First matching category wins.',
784806
patternTests: patternTests.slice(0, 10),
785807
details: matchedPattern
786808
? `Matched category with pattern: ${matchedPattern.pattern.toString()} (priority: ${matchedPattern.priority || 0})`
@@ -792,7 +814,7 @@ export class Alice {
792814
if (wildcards.length > 0) {
793815
steps.push({
794816
name: 'Wildcard Extraction',
795-
description: 'Extracting captured text from pattern wildcards (*)',
817+
description: 'AIML wildcards (* and _) capture matched text. These values are accessed via <star/>, <star index="2"/>, etc. in templates.',
796818
wildcards: wildcards.map((w, i) => ({
797819
index: i + 1,
798820
captured: w || '(empty)'
@@ -820,7 +842,7 @@ export class Alice {
820842
if (usedSRAI) {
821843
steps.push({
822844
name: 'SRAI (Symbolic Reduction)',
823-
description: 'Pattern redirects to another pattern via SRAI',
845+
description: 'AIML\'s <srai> tag enables recursive pattern matching. The input is transformed and re-matched against all categories.',
824846
sraiTarget: sraiTarget,
825847
details: `Recursively matching: "${sraiTarget}"`
826848
});
@@ -836,7 +858,7 @@ export class Alice {
836858

837859
steps.push({
838860
name: 'Template Expansion',
839-
description: 'Expanding template with captured wildcards and context variables',
861+
description: 'AIML <template> tags contain the response. They can include: <star/> (wildcards), <get/><set/> (variables), <random> (randomization), <srai> (recursion), and more.',
840862
templateInfo: matchedPattern ? {
841863
hasFunction: typeof matchedPattern.template === 'function',
842864
usesContext: matchedPattern.template.toString().includes('this.context')
@@ -861,7 +883,7 @@ export class Alice {
861883

862884
steps.push({
863885
name: 'Context Update',
864-
description: 'Updating conversation context for future <that> matching',
886+
description: 'AIML stores the response as <that> for future pattern matching. Some patterns only match when the previous response meets certain criteria.',
865887
contextInfo: {
866888
before: {
867889
topic: initialContext.topic,

demos/15-chatbot-evolution/js/timeline-app.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,17 @@ class TimelineApp {
353353
stepDiv.appendChild(contentDiv);
354354
}
355355

356+
// Add SRAI display for ALICE
357+
if (step.sraiTarget) {
358+
const cd = document.createElement("div");
359+
cd.className = "step-content";
360+
const sd = document.createElement("div");
361+
sd.style.cssText = "background:#e0f2fe;padding:12px;border-radius:8px;border-left:4px solid #0284c7;";
362+
sd.innerHTML = '<div style="font-weight:600;color:#0369a1;margin-bottom:8px;">SRAI REDIRECT</div><code>\"' + (step.input || "") + '\" -> \"' + step.sraiTarget + '\"</code>';
363+
cd.appendChild(sd);
364+
stepDiv.appendChild(cd);
365+
}
366+
356367
// Add pattern tests
357368
if (step.patternTests && step.patternTests.length > 0) {
358369
const contentDiv = document.createElement('div');

0 commit comments

Comments
 (0)