Portal Community

FindMatchAsync Implementation

public class ProceduralMemoryService : IProceduralMemoryStore
{
    public async Task<Procedure?> FindMatchAsync(
        string taskDescription, Guid agentId, string tenantId,
        CancellationToken ct = default)
    {
        // Load all approved procedures for this agent (+ shared)
        var procedures = await _db.Procedures
            .Where(p => (p.AgentId == agentId || p.IsShared)
                     && p.TenantId == tenantId)
            .ToListAsync(ct);

        if (!procedures.Any()) return null;

        // 1. Try exact pattern match first (fastest)
        var patternMatch = procedures.FirstOrDefault(p =>
            Regex.IsMatch(taskDescription, p.TriggerPattern,
                RegexOptions.IgnoreCase));

        if (patternMatch != null) return MapToDomain(patternMatch);

        // 2. Fallback: embedding similarity match
        if (_config.UseEmbeddingMatch)
        {
            var queryEmbedding = await _embeddingProvider.EmbedAsync(taskDescription, ct);
            var bestMatch = procedures
                .Select(p => new { Procedure = p, Score = CosineSimilarity(queryEmbedding, p.TriggerEmbedding) })
                .Where(x => x.Score >= _config.ProcedureMatchThreshold)
                .MaxBy(x => x.Score);

            return bestMatch != null ? MapToDomain(bestMatch.Procedure) : null;
        }

        return null;
    }
}

Trigger Pattern Examples

PatternMatchesType
onboard.*vendor"onboard new vendor", "onboard the vendor TechCorp"Regex
reset.*password"reset password for user", "help me reset my password"Regex
generate.*report"generate monthly report", "generate expense report"Regex
create.*expense.*report"create an expense report for Q1"Regex

Procedure Injection into System Prompt

When a procedure is recalled, it is injected into the system prompt before the LLM call:

// SystemPromptBuilder adds the procedure as structured instructions
private string FormatProcedureForPrompt(Procedure procedure)
{
    var sb = new StringBuilder();
    sb.AppendLine($"[Procedure: {procedure.Name}]");
    sb.AppendLine(procedure.Description);
    sb.AppendLine("Follow these steps exactly:");

    foreach (var step in procedure.Steps.OrderBy(s => s.Order))
    {
        var prefix = step.IsOptional ? "(Optional) " : "";
        var condition = step.Condition != null ? $" [Only if: {step.Condition}]" : "";
        sb.AppendLine($"Step {step.Order}: {prefix}{step.Instruction}{condition}");
        if (step.ToolName != null)
            sb.AppendLine($"  → Use tool: {step.ToolName}");
    }

    return sb.ToString();
}