Files
meeting-assistant/MeetingAssistant/Workflow/WorkflowRulesEditorInstructionBuilder.cs
T
codex 7ff93b73b3
PR and Push Build/Test / build-and-test (push) Failing after 6m36s
Make agent file writes append by default
2026-05-28 12:36:23 +02:00

82 lines
4.3 KiB
C#

using Microsoft.Extensions.Options;
namespace MeetingAssistant.Workflow;
public interface IWorkflowRulesEditorInstructionBuilder
{
Task<string> BuildAsync(MeetingAssistantOptions options, CancellationToken cancellationToken);
}
public sealed class WorkflowRulesEditorInstructionBuilder : IWorkflowRulesEditorInstructionBuilder
{
private const string DefaultPrompt = """
You are the Meeting Assistant workflow rules and identities editor.
Your purpose is to help edit the configured local workflow rules YAML file and manage the local speaker identity database for Meeting Assistant.
Use the read_rules, search, and write_rules tools for workflow rules. Do not ask for or modify unrelated files.
Read the existing rules before making changes unless the user explicitly asks to replace the whole file.
write_rules appends by default. Pass replace_file=true only when you intentionally replace the complete rules file.
Preserve valid YAML, keep personal/local rules in the configured ignored rules file, and keep changes minimal.
When writing rules, prefer existing rule style and names.
Use search_identities and read_identity before changing identities unless the user gives an exact identity id.
Prefer updating identities by id, not by guessed name. If a user asks about names, search first and confirm ambiguity in your final response.
For identity merges, merge the duplicate/source identity into the identity that should remain as target.
Use list_identity_samples before playing, reading, or deleting samples. Use queue_play_identity_sample to let the user hear a sample; do not claim you heard it yourself.
Use read_identity_sample only when the raw base64 WAV is actually useful; prefer list_identity_samples for ordinary inspection.
Delete identities or samples only when the user clearly asked for deletion or cleanup.
Explain the final change briefly after the tools finish.
""";
private readonly ILogger<WorkflowRulesEditorInstructionBuilder> logger;
public WorkflowRulesEditorInstructionBuilder(ILogger<WorkflowRulesEditorInstructionBuilder> logger)
{
this.logger = logger;
}
public async Task<string> BuildAsync(MeetingAssistantOptions options, CancellationToken cancellationToken)
{
var editorOptions = options.WorkflowRulesEditor.ToEffectiveAgentOptions(options.Agent);
var configuredPrompt = string.IsNullOrWhiteSpace(editorOptions.InitialPrompt)
? DefaultPrompt
: editorOptions.InitialPrompt!;
var rulesPath = WorkflowRulesPathResolver.Resolve(options.Automation.RulesPath) ?? "<not configured>";
var docs = await ReadWorkflowDocsAsync(cancellationToken);
return configuredPrompt.Trim() + Environment.NewLine + Environment.NewLine +
$"Configured workflow rules file: {rulesPath}" + Environment.NewLine + Environment.NewLine +
"Speaker identity tools can search/list/read/create/update/delete/merge identities, list/read/delete identity samples, and queue a sample for local playback." + Environment.NewLine + Environment.NewLine +
"Workflow rules reference documentation:" + Environment.NewLine +
"```markdown" + Environment.NewLine +
docs.Trim() + Environment.NewLine +
"```";
}
private async Task<string> ReadWorkflowDocsAsync(CancellationToken cancellationToken)
{
foreach (var path in CandidateDocumentationPaths())
{
if (File.Exists(path))
{
return await File.ReadAllTextAsync(path, cancellationToken);
}
}
logger.LogWarning("Workflow rules editor could not find docs/meeting-workflow-engine.md for its prompt");
return "Workflow documentation file docs/meeting-workflow-engine.md was not available at runtime.";
}
private static IEnumerable<string> CandidateDocumentationPaths()
{
var baseDirectory = AppContext.BaseDirectory;
yield return Path.Combine(baseDirectory, "docs", "meeting-workflow-engine.md");
var current = new DirectoryInfo(baseDirectory);
for (var i = 0; i < 8 && current is not null; i++)
{
yield return Path.Combine(current.FullName, "docs", "meeting-workflow-engine.md");
current = current.Parent;
}
}
}