parsePromptOverrideMap function
Validates the raw prompts: yaml section into a prompt name → raw source
map (values stay raw: a file path or inline text — classified later, at
file-resolution time).
Strict, like the roles:/ttsr: sections: a non-map section, a
non-string or empty value, an unknown prompt name, or systemPromptAlias
given together with codeModePromptName throws ConfigException instead
of silently dropping the section. A null node (absent section) yields an
empty map.
Implementation
Map<String, String> parsePromptOverrideMap(Object? node) {
if (node == null) return const {};
if (node is! Map) {
throw ConfigException(
'"prompts" must be a map of prompt name → file path or inline text',
);
}
final result = <String, String>{};
for (final entry in node.entries) {
final name = entry.key;
final value = entry.value;
if (name is! String || !overridablePromptNames.containsKey(name)) {
throw ConfigException(
'unknown prompt override "$name" — supported names: '
'${overridablePromptNames.keys.join(', ')}',
);
}
if (value is! String || value.trim().isEmpty) {
throw ConfigException(
'"prompts.$name" must be a non-empty string '
'(a file path or inline text)',
);
}
result[name] = value;
}
if (result.containsKey(systemPromptAlias) &&
result.containsKey(codeModePromptName)) {
throw ConfigException(
'"prompts" maps both "$systemPromptAlias" and "$codeModePromptName" — '
'they are aliases for the same prompt; keep only one',
);
}
return result;
}