Public Access
Add attendee transformation workflows
This commit is contained in:
@@ -17,6 +17,14 @@ public interface IMeetingWorkflowEngine
|
||||
MeetingWorkflowEvent workflowEvent,
|
||||
MeetingAssistantOptions options,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
Task<string> TransformAttendeeAsync(
|
||||
MeetingWorkflowEvent workflowEvent,
|
||||
MeetingAssistantOptions options,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(workflowEvent.AttendeeName ?? "");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class NoopMeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
@@ -38,6 +46,14 @@ public sealed class NoopMeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
{
|
||||
return Task.FromResult(workflowEvent.TranscriptLineText ?? "");
|
||||
}
|
||||
|
||||
public Task<string> TransformAttendeeAsync(
|
||||
MeetingWorkflowEvent workflowEvent,
|
||||
MeetingAssistantOptions options,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(workflowEvent.AttendeeName ?? "");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
@@ -54,7 +70,8 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
"state.to",
|
||||
"speaker.name",
|
||||
MeetingWorkflowRuleSchema.PropertyTranscriptLine,
|
||||
MeetingWorkflowRuleSchema.ParameterTranscriptSpeaker
|
||||
MeetingWorkflowRuleSchema.ParameterTranscriptSpeaker,
|
||||
MeetingWorkflowRuleSchema.PropertyAttendeeName
|
||||
];
|
||||
|
||||
private readonly IMeetingWorkflowRulesProvider rulesProvider;
|
||||
@@ -98,6 +115,21 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
?? "";
|
||||
}
|
||||
|
||||
public async Task<string> TransformAttendeeAsync(
|
||||
MeetingWorkflowEvent workflowEvent,
|
||||
MeetingAssistantOptions options,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (workflowEvent.Type != MeetingWorkflowEventType.AttendeeAdded)
|
||||
{
|
||||
throw new ArgumentException("Workflow event must be an attendee added event.", nameof(workflowEvent));
|
||||
}
|
||||
|
||||
return await RunCoreAsync(workflowEvent, options, cancellationToken)
|
||||
?? workflowEvent.AttendeeName
|
||||
?? "";
|
||||
}
|
||||
|
||||
private async Task<string?> RunCoreAsync(
|
||||
MeetingWorkflowEvent workflowEvent,
|
||||
MeetingAssistantOptions options,
|
||||
@@ -107,7 +139,7 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
var context = new MeetingWorkflowExecutionContext(workflowEvent);
|
||||
if (rules.Count == 0)
|
||||
{
|
||||
return context.TranscriptLine;
|
||||
return context.ResultValue;
|
||||
}
|
||||
|
||||
var meeting = await meetingNoteStore.ReadAsync(
|
||||
@@ -134,10 +166,18 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
var model = CreateTemplateModel(meeting, context);
|
||||
foreach (var step in rule.Steps)
|
||||
{
|
||||
if (workflowEvent.Type == MeetingWorkflowEventType.AttendeeAdded &&
|
||||
!IsAttendeeTransformStep(step))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"attendee_added workflow rules can only transform attendee.name with set_property.");
|
||||
}
|
||||
|
||||
var stepChanged = await ApplyStepAsync(
|
||||
step,
|
||||
meeting,
|
||||
context,
|
||||
options,
|
||||
model,
|
||||
cancellationToken);
|
||||
ruleNoteChanged |= stepChanged;
|
||||
@@ -176,7 +216,7 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
return context.TranscriptLine;
|
||||
return context.ResultValue;
|
||||
}
|
||||
|
||||
private static bool MatchesTrigger(
|
||||
@@ -229,9 +269,41 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
if (trigger.AttendeeAdded is not null)
|
||||
{
|
||||
return workflowEvent.Type == MeetingWorkflowEventType.AttendeeAdded &&
|
||||
MatchesAttendeeAddedTrigger(trigger.AttendeeAdded, workflowEvent.AttendeeName);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool MatchesAttendeeAddedTrigger(
|
||||
MeetingWorkflowAttendeeAddedTrigger trigger,
|
||||
string? attendeeName)
|
||||
{
|
||||
var attendee = attendeeName ?? "";
|
||||
if (!string.IsNullOrWhiteSpace(trigger.EqualsValue) &&
|
||||
!string.Equals(attendee, trigger.EqualsValue.Trim(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(trigger.Contains) &&
|
||||
!attendee.Contains(trigger.Contains.Trim(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(trigger.Regex) &&
|
||||
!Regex.IsMatch(attendee, trigger.Regex, RegexOptions.IgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool EvaluateConditions(
|
||||
IReadOnlyList<MeetingWorkflowCondition> conditions,
|
||||
MeetingNote meeting,
|
||||
@@ -298,6 +370,7 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
MeetingWorkflowStep step,
|
||||
MeetingNote meeting,
|
||||
MeetingWorkflowExecutionContext context,
|
||||
MeetingAssistantOptions options,
|
||||
MeetingWorkflowTemplateModel model,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -305,7 +378,11 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
switch (step.Uses.Trim().ToLowerInvariant())
|
||||
{
|
||||
case MeetingWorkflowRuleSchema.StepAddAttendee:
|
||||
return AddUnique(meeting.Frontmatter.Attendees, value, MeetingAttendeeNames.NormalizeDisplayName);
|
||||
var attendee = await TransformAttendeeAsync(
|
||||
MeetingWorkflowEvent.AttendeeAdded(context.Event.Artifacts, value),
|
||||
options,
|
||||
cancellationToken);
|
||||
return AddUnique(meeting.Frontmatter.Attendees, attendee, MeetingAttendeeNames.NormalizeDisplayName);
|
||||
case MeetingWorkflowRuleSchema.StepRemoveAttendee:
|
||||
return RemoveValue(meeting.Frontmatter.Attendees, value);
|
||||
case MeetingWorkflowRuleSchema.StepAddProject:
|
||||
@@ -319,6 +396,9 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
case MeetingWorkflowRuleSchema.StepSetProperty when IsTranscriptLineProperty(step.Property ?? step.Name):
|
||||
SetTranscriptLine(context, value);
|
||||
return false;
|
||||
case MeetingWorkflowRuleSchema.StepSetProperty when IsAttendeeNameProperty(step.Property ?? step.Name):
|
||||
SetAttendeeName(context, value);
|
||||
return false;
|
||||
case MeetingWorkflowRuleSchema.StepSetProperty:
|
||||
return SetProperty(meeting, step.Property ?? step.Name, value);
|
||||
default:
|
||||
@@ -370,11 +450,39 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
context.TranscriptLine = value;
|
||||
}
|
||||
|
||||
private static void SetAttendeeName(
|
||||
MeetingWorkflowExecutionContext context,
|
||||
string value)
|
||||
{
|
||||
if (context.Event.Type != MeetingWorkflowEventType.AttendeeAdded)
|
||||
{
|
||||
throw new InvalidOperationException("The attendee.name property can only be set during attendee_added events.");
|
||||
}
|
||||
|
||||
if (string.Equals(context.AttendeeName, value, StringComparison.Ordinal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
context.AttendeeName = value;
|
||||
}
|
||||
|
||||
private static bool IsTranscriptLineProperty(string? property)
|
||||
{
|
||||
return MeetingWorkflowRuleSchema.IsProperty(property, MeetingWorkflowRuleSchema.PropertyTranscriptLine);
|
||||
}
|
||||
|
||||
private static bool IsAttendeeNameProperty(string? property)
|
||||
{
|
||||
return MeetingWorkflowRuleSchema.IsProperty(property, MeetingWorkflowRuleSchema.PropertyAttendeeName);
|
||||
}
|
||||
|
||||
private static bool IsAttendeeTransformStep(MeetingWorkflowStep step)
|
||||
{
|
||||
return MeetingWorkflowRuleSchema.IsStep(step.Uses, MeetingWorkflowRuleSchema.StepSetProperty) &&
|
||||
IsAttendeeNameProperty(step.Property ?? step.Name);
|
||||
}
|
||||
|
||||
private static bool AddUnique(
|
||||
List<string> values,
|
||||
string value,
|
||||
@@ -456,7 +564,8 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
["state.to"] = workflowEvent.ToState is { } to ? MeetingWorkflowStateNames.ToRuleName(to) : "",
|
||||
["speaker.name"] = workflowEvent.SpeakerName,
|
||||
[MeetingWorkflowRuleSchema.PropertyTranscriptLine] = context.TranscriptLine ?? "",
|
||||
[MeetingWorkflowRuleSchema.ParameterTranscriptSpeaker] = workflowEvent.SpeakerName ?? ""
|
||||
[MeetingWorkflowRuleSchema.ParameterTranscriptSpeaker] = workflowEvent.SpeakerName ?? "",
|
||||
[MeetingWorkflowRuleSchema.PropertyAttendeeName] = context.AttendeeName ?? ""
|
||||
};
|
||||
}
|
||||
|
||||
@@ -480,7 +589,10 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
: new MeetingWorkflowSpeakerModel(workflowEvent.SpeakerName),
|
||||
new MeetingWorkflowTranscriptModel(
|
||||
context.TranscriptLine ?? "",
|
||||
workflowEvent.SpeakerName ?? ""));
|
||||
workflowEvent.SpeakerName ?? ""),
|
||||
string.IsNullOrWhiteSpace(context.AttendeeName)
|
||||
? null
|
||||
: new MeetingWorkflowAttendeeModel(context.AttendeeName));
|
||||
}
|
||||
|
||||
private sealed class MeetingWorkflowExecutionContext
|
||||
@@ -489,10 +601,23 @@ public sealed class MeetingWorkflowEngine : IMeetingWorkflowEngine
|
||||
{
|
||||
Event = workflowEvent;
|
||||
TranscriptLine = workflowEvent.TranscriptLineText;
|
||||
AttendeeName = workflowEvent.AttendeeName;
|
||||
}
|
||||
|
||||
public MeetingWorkflowEvent Event { get; }
|
||||
|
||||
public string? TranscriptLine { get; set; }
|
||||
|
||||
public string? AttendeeName { get; set; }
|
||||
|
||||
public string? ResultValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return Event.Type == MeetingWorkflowEventType.AttendeeAdded
|
||||
? AttendeeName
|
||||
: TranscriptLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user