11package com .embabel .grouper .agent ;
22
3+ import com .embabel .common .ai .model .LlmOptions ;
34import com .embabel .common .ai .prompt .PromptContributor ;
45
56import java .time .Instant ;
6- import java .util .HashMap ;
7- import java .util .LinkedList ;
8- import java .util .List ;
9- import java .util .Map ;
7+ import java .util .*;
108
119public abstract class Domain {
1210
1311 /**
1412 * A message to be evaluated
1513 *
16- * @param id id of the message, in case we have variants
17- * @param content content of this instance of the message
14+ * @param id id of the message, in case we have variants
15+ * @param detail detail of this instance of the message
16+ * @param objective objective
1817 */
1918 public record Message (
2019 String id ,
21- String content ) {
20+ String detail ,
21+ String objective ) {
2222 }
2323
2424 /**
25- * Map from id to Message
25+ * Expression of a message
2626 *
27- * @param messaging
27+ * @param message
28+ * @param expression
2829 */
29- public record Positioning (Map <String , List <Message >> messaging ) {
30+ public record MessageExpression (
31+ Message message ,
32+ String expression
33+ ) {
34+ }
35+
36+ public record MessageTest (
37+ Message message ,
38+ List <MessageExpression > expressions
39+ ) {
40+
41+ public MessageTest (Message message , String ... expressions ) {
42+ this (message ,
43+ Arrays .stream (expressions ).map (e -> new MessageExpression (message , e )).toList ());
44+ }
45+ }
46+
47+ /**
48+ * Map from name to Message
49+ * This allows us to test multiple variants of the same
50+ * message name
51+ *
52+ */
53+ public record Positioning (List <MessageTest > messageTests ) {
3054 }
3155
3256 public enum Gender {
@@ -40,15 +64,17 @@ public interface Participant extends PromptContributor {
4064
4165 String name ();
4266
43- /***
44- * A participant may run on multiple models
45- */
46- String model ();
67+ LlmOptions llm ();
4768 }
4869
4970 public record FocusGroup (
50- List <Participant > participants ,
51- Instant timestamp
71+ List <Participant > participants
72+ ) {
73+ }
74+
75+ public record FocusGroupSubmission (
76+ FocusGroup focusGroup ,
77+ Positioning positioning
5278 ) {
5379 }
5480
@@ -67,11 +93,17 @@ public record Reaction(
6793 ) {
6894 }
6995
96+ // public record MessageSubmission(
97+ // Message message,
98+ // Participant participant
99+ // ) {
100+ // }
101+
70102 /**
71103 * Reaction of one participant to a given message
72104 */
73105 public record SpecificReaction (
74- Message message ,
106+ MessageExpression message ,
75107 Participant participant ,
76108 Reaction reaction ,
77109 Instant timestamp
@@ -87,30 +119,111 @@ public record MessageScore(
87119 ) {
88120 }
89121
122+ /**
123+ * Represents a combination of a participant and a message expression
124+ */
125+ public record ParticipantMessagePresentation (
126+ Participant participant ,
127+ MessageExpression messageExpression
128+ ) {
129+ }
130+
131+ /**
132+ * Matrix tracking completion status for all participant/message expression combinations
133+ */
134+ public record CompletionMatrix (
135+ Map <ParticipantMessagePresentation , Boolean > completionStatus
136+ ) {
137+ public boolean isComplete () {
138+ return completionStatus .values ().stream ().allMatch (Boolean ::booleanValue );
139+ }
140+
141+ public boolean hasReaction (Participant participant , MessageExpression messageExpression ) {
142+ return completionStatus .getOrDefault (
143+ new ParticipantMessagePresentation (participant , messageExpression ),
144+ false
145+ );
146+ }
147+
148+ public List <ParticipantMessagePresentation > getAllCombinations () {
149+ return List .copyOf (completionStatus .keySet ());
150+ }
151+
152+ public List <ParticipantMessagePresentation > getCompletedCombinations () {
153+ return completionStatus .entrySet ().stream ()
154+ .filter (Map .Entry ::getValue )
155+ .map (Map .Entry ::getKey )
156+ .toList ();
157+ }
158+
159+ public List <ParticipantMessagePresentation > getIncompleteCombinations () {
160+ return completionStatus .entrySet ().stream ()
161+ .filter (e -> !e .getValue ())
162+ .map (Map .Entry ::getKey )
163+ .toList ();
164+ }
165+ }
166+
167+ /**
168+ * Built up as we return results
169+ */
90170 public static class FocusGroupRun {
91171
92172 public final FocusGroup focusGroup ;
93173
174+ public final Positioning positioning ;
175+
94176 private final Map <Participant , List <SpecificReaction >> reactionsByParticipant = new HashMap <>();
95177
96- public FocusGroupRun (FocusGroup focusGroup ) {
178+ private final Map <ParticipantMessagePresentation , Boolean > matrixData = new HashMap <>();
179+
180+ public FocusGroupRun (
181+ FocusGroup focusGroup ,
182+ Positioning positioning ) {
97183 this .focusGroup = focusGroup ;
184+ this .positioning = positioning ;
185+
186+ // Initialize matrix with all combinations set to false
187+ var allMessageExpressions = positioning .messageTests ().stream ()
188+ .flatMap (mt -> mt .expressions ().stream ())
189+ .toList ();
190+
191+ for (var participant : focusGroup .participants ()) {
192+ for (MessageExpression messageExpression : allMessageExpressions ) {
193+ matrixData .put (new ParticipantMessagePresentation (participant , messageExpression ), false );
194+ }
195+ }
196+ }
197+
198+ public CompletionMatrix getCompletionMatrix () {
199+ return new CompletionMatrix (Map .copyOf (matrixData ));
200+ }
201+
202+ public boolean isComplete () {
203+ return getCompletionMatrix ().isComplete ();
98204 }
99205
100206 public void record (SpecificReaction reaction ) {
101207 reactionsByParticipant
102208 .computeIfAbsent (reaction .participant (), k -> new LinkedList <>())
103209 .add (reaction );
210+
211+ // Update matrix
212+ ParticipantMessagePresentation key = new ParticipantMessagePresentation (
213+ reaction .participant (),
214+ reaction .message ()
215+ );
216+ matrixData .put (key , true );
104217 }
105218
106219 public List <SpecificReaction > getReactionsForParticipant (Participant participant ) {
107220 return reactionsByParticipant .getOrDefault (participant , List .of ());
108221 }
109222
110- public MessageScore getAverageScoreForMessage (Message message ) {
223+ public MessageScore getAverageScoreForMessage (MessageExpression messageExpression ) {
111224 var reactions = reactionsByParticipant .values ().stream ()
112225 .flatMap (List ::stream )
113- .filter (r -> r .message ().equals (message ))
226+ .filter (r -> r .message ().equals (messageExpression ))
114227 .toList ();
115228
116229 long count = reactions .size ();
0 commit comments