fix(compiler): Preserve TTS data in agent frontmatter

**Problem:**
Agent compiler was stripping TTS data (intro and voices) when converting
.agent.yaml files to .md files. This caused all agents to use fallback
voice (en_US-lessac-medium) and generic intros in party mode.

**Root Cause:**
buildFrontmatter() only included name and description fields, omitting
the tts section from source YAML.

**Fix:**
- Modified buildFrontmatter() to accept and include TTS data
- Updated compileToXml() to extract TTS from parsed YAML
- TTS data now preserved in compiled .md frontmatter

**Impact:**
- Each agent now gets unique voice (ryan-high, kristin-medium, etc.)
- Personalized intros ("Hi! I'm John..." instead of "Hi! I'm Pm...")
- Party mode agents now distinguishable by voice

**Testing:**
 Tested with pm.agent.yaml → correct voice: en_US-ryan-high
 Tested with analyst.agent.yaml → correct voice: en_US-kristin-medium
 Verified TTS frontmatter structure matches manifest-generator expectations

**Related:**
- Fixes voice assignment issue in PR #987
- Enables proper multi-agent party mode experience
- Manifest generator already handles TTS correctly (no changes needed)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Paul Preibisch 2025-12-17 18:18:59 -07:00
parent 7f36711e6c
commit 555e77016c
1 changed files with 33 additions and 6 deletions

View File

@ -29,20 +29,44 @@ function escapeXml(text) {
* Build frontmatter for agent
* @param {Object} metadata - Agent metadata
* @param {string} agentName - Final agent name
* @param {Object} ttsData - TTS data (intro and voices)
* @returns {string} YAML frontmatter
*/
function buildFrontmatter(metadata, agentName) {
function buildFrontmatter(metadata, agentName, ttsData = null) {
const nameFromFile = agentName.replaceAll('-', ' ');
const description = metadata.title || 'BMAD Agent';
return `---
let frontmatter = `---
name: "${nameFromFile}"
description: "${description}"
---
description: "${description}"`;
// Include TTS data if available
if (ttsData) {
frontmatter += `\ntts:`;
if (ttsData.intro) {
// Escape double quotes in intro
const escapedIntro = ttsData.intro.replaceAll('"', String.raw`\"`);
frontmatter += `\n intro: "${escapedIntro}"`;
}
if (ttsData.voices && Array.isArray(ttsData.voices)) {
frontmatter += `\n voices:`;
for (const voice of ttsData.voices) {
frontmatter += `\n -`;
if (voice.piper) frontmatter += ` piper: "${voice.piper}"`;
if (voice.mac) frontmatter += ` mac: "${voice.mac}"`;
}
}
}
frontmatter += `\n---
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
`;
return frontmatter;
}
/**
@ -393,8 +417,11 @@ function compileToXml(agentYaml, agentName = '', targetPath = '') {
let xml = '';
// Build frontmatter
xml += buildFrontmatter(meta, agentName || meta.name || 'agent');
// Extract TTS data from root level or agent level
const ttsData = agentYaml.tts || agent.tts || null;
// Build frontmatter with TTS data
xml += buildFrontmatter(meta, agentName || meta.name || 'agent', ttsData);
// Start code fence
xml += '```xml\n';