Public Access
82 lines
4.3 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|