greeting evaluation

This commit is contained in:
austin 2024-12-29 12:08:46 -05:00
parent d6aa54dbe0
commit 117dd6a1af
15 changed files with 320 additions and 51 deletions

View File

@ -20,6 +20,18 @@
"4" : { "4" : {
"id" : 4, "id" : 4,
"name" : "Other" "name" : "Other"
},
"5" : {
"id" : 5,
"name" : "Quote"
},
"6" : {
"id" : 6,
"name" : "Conversation"
},
"7" : {
"id" : 7,
"name" : "CurrentConversation"
} }
}, },
"relations" : { "relations" : {
@ -46,6 +58,18 @@
"name" : "InstanceOf", "name" : "InstanceOf",
"parent" : 3, "parent" : 3,
"child" : 4 "child" : 4
},
"4" : {
"id" : 4,
"name" : "ParticipantOf",
"parent" : 7,
"child" : 4
},
"5" : {
"id" : 5,
"name" : "ParticipantOf",
"parent" : 7,
"child" : 2
} }
} }
} }

View File

@ -0,0 +1,21 @@
package org.studiorailgun;
import org.studiorailgun.conversation.Quote;
import org.studiorailgun.conversation.evaluators.EvaluationTree;
/**
* The top level ai class
*/
public class AI {
/**
* Simulates a frame of the ai
* @param input The raw input text
*/
public static void simFrame(String input){
Quote playerQuote = new Quote(input);
//handle ai statement
EvaluationTree.evaluate(Globals.conversation, playerQuote);
}
}

View File

@ -3,6 +3,7 @@ package org.studiorailgun;
import java.io.File; import java.io.File;
import org.studiorailgun.conversation.Conversation; import org.studiorailgun.conversation.Conversation;
import org.studiorailgun.conversation.evaluators.GreetingEval;
import org.studiorailgun.knowledge.KnowledgeWeb; import org.studiorailgun.knowledge.KnowledgeWeb;
/** /**
@ -23,17 +24,15 @@ public class Globals {
/** /**
* Initializes the knowledge web * Initializes the knowledge web
*/ */
public static void init(){ public static void init(String webPath){
Globals.loadWeb("web.json"); //initialize evaluators
} GreetingEval.init();
/** //init web
* Loads a web Globals.web = FileUtils.loadObjectFromFile(new File(webPath), KnowledgeWeb.class);
* @param webPath The web's path
*/
public static void loadWeb(String webPath){
Globals.web = FileUtils.loadObjectFromFile(new File("web.json"), KnowledgeWeb.class);
Globals.web.initLinks(); Globals.web.initLinks();
//init convo
Globals.conversation = Conversation.parse(Globals.web); Globals.conversation = Conversation.parse(Globals.web);
} }

View File

@ -2,10 +2,9 @@ package org.studiorailgun.conversation;
import java.util.Scanner; import java.util.Scanner;
import org.studiorailgun.AI;
import org.studiorailgun.Globals; import org.studiorailgun.Globals;
import org.studiorailgun.conversation.llm.Actor; import org.studiorailgun.conversation.evaluators.EvaluationTree;
import org.studiorailgun.conversation.llm.LLMConversation;
import org.studiorailgun.conversation.llm.Statement;
import org.studiorailgun.conversation.parser.CommandParser; import org.studiorailgun.conversation.parser.CommandParser;
public class AgentLoop { public class AgentLoop {
@ -24,18 +23,11 @@ public class AgentLoop {
* The main method * The main method
*/ */
public static void main(){ public static void main(){
Globals.init(); Globals.init("web.json");
try (Scanner scan = new Scanner(System.in)) { try (Scanner scan = new Scanner(System.in)) {
String prompt = ""; String prompt = "";
//setup conversation tracking
LLMConversation convo = new LLMConversation();
Actor player = new Actor("John");
Actor ai = new Actor("Dave");
convo.addParticipant(player);
convo.addParticipant(ai);
//actual main loop //actual main loop
while(running){ while(running){
@ -44,10 +36,7 @@ public class AgentLoop {
if(CommandParser.parseCommands(prompt)){ if(CommandParser.parseCommands(prompt)){
continue; continue;
} }
convo.addStatement(new Statement(player, prompt)); AI.simFrame(prompt);
//handle ai statement
throw new UnsupportedOperationException("asdf");
} }
} }
} }

View File

@ -1,7 +1,9 @@
package org.studiorailgun.conversation; package org.studiorailgun.conversation;
import org.studiorailgun.conversation.evaluators.GreetingData; import org.studiorailgun.conversation.evaluators.GreetingData;
import org.studiorailgun.conversation.evaluators.goal.GoalData;
import org.studiorailgun.knowledge.KnowledgeWeb; import org.studiorailgun.knowledge.KnowledgeWeb;
import org.studiorailgun.knowledge.Node;
/** /**
* A conversation * A conversation
@ -18,35 +20,51 @@ public class Conversation {
*/ */
ConvParticipant other; ConvParticipant other;
/**
* The node in the knowledge web representing this conversation
*/
Node data;
/** /**
* Data on greetings * Data on greetings
*/ */
GreetingData greetingData; GreetingData greetingData;
/**
* The goal data
*/
GoalData goalData;
/** /**
* Parses the current conversation's data from the knowledge web * Parses the current conversation's data from the knowledge web
* @param web The web * @param web The web
* @return The conversation * @return The conversation
*/ */
public static Conversation parse(KnowledgeWeb web){ public static Conversation parse(KnowledgeWeb web){
Node node = web.getNode(7);
//find the self //find the self
ConvParticipant self = new ConvParticipant(web.getSelf()); ConvParticipant self = new ConvParticipant(web.getSelf());
//find the other participant //find the other participant
ConvParticipant other = new ConvParticipant(web.getNode(4)); ConvParticipant other = new ConvParticipant(web.getNode(4));
Conversation rVal = new Conversation(self, other); Conversation rVal = new Conversation(node, self, other);
return rVal; return rVal;
} }
/** /**
* Constructor * Constructor
* @param node The node representing this conversation instance
* @param self The participant representing this bot instance * @param self The participant representing this bot instance
* @param other The participant representing the other party in the conversation * @param other The participant representing the other party in the conversation
*/ */
public Conversation(ConvParticipant self, ConvParticipant other){ public Conversation(Node node, ConvParticipant self, ConvParticipant other){
this.data = node;
this.self = self; this.self = self;
this.other = other; this.other = other;
this.greetingData = new GreetingData();
this.goalData = new GoalData();
} }
/** /**
@ -73,4 +91,14 @@ public class Conversation {
return other; return other;
} }
public GoalData getGoalData() {
return goalData;
}
public void setGoalData(GoalData goalData) {
this.goalData = goalData;
}
} }

View File

@ -0,0 +1,48 @@
package org.studiorailgun.conversation;
import org.studiorailgun.conversation.categorization.SentenceFunctionCategorizor.SentenceFunction;
/**
* A quote stated during the conversation
*/
public class Quote {
/**
* The raw text of the quote
*/
String raw;
/**
* The function of the sentence
*/
SentenceFunction function;
/**
* Constructor
* @param input The raw text of the quote
*/
public Quote(String input){
this.raw = input;
}
/**
* Gets the raw text of the quote
* @return The raw text of the quote
*/
public String getRaw(){
return raw;
}
/**
* Gets the function of the quote
* @return The function
*/
public SentenceFunction getFunction(){
return function;
}
public void setFunction(SentenceFunction function){
this.function = function;
}
}

View File

@ -1,5 +1,7 @@
package org.studiorailgun.conversation.categorization; package org.studiorailgun.conversation.categorization;
import org.studiorailgun.conversation.Quote;
/** /**
* Categorizes sentences based on function * Categorizes sentences based on function
*/ */
@ -10,27 +12,35 @@ public class SentenceFunctionCategorizor {
*/ */
public static enum SentenceFunction { public static enum SentenceFunction {
/** /**
* Transfers information to the other party * A sentence whose purpose is to perform some non-informational duty in a conversation.
* ie, declaring facts, declaring perspective of the world (how you feel), etc * An example of this could be a greeting or farewell.
* "The ball is red". "I don't like that".
*/ */
TRANSFER_INFORMATION, UTILITY,
/** /**
* Query information from the other party * Transfers a piece of information to another participant. For instance, describing
* ie, asking for a fact or perspective * the details of an object.
* "Is that ball red?" "What color is your hat?" "How do you feel about that?"
*/ */
QUERY_INFORMATION, TRANSFER,
/**
* Queries a piece of information from another participant.
*/
QUERY,
/**
* Commands a participant to do something.
*/
IMPERATIVE,
} }
/** /**
* Categorizes the sentence by function * Categorizes the sentence by function
* @param input The input sentence * @param input The input quote
* @return The function of the sentence * @return The function of the sentence
*/ */
public static SentenceFunction categorize(String input){ public static void categorize(Quote input){
return SentenceFunction.QUERY_INFORMATION; input.setFunction(SentenceFunction.UTILITY);
} }
} }

View File

@ -0,0 +1,38 @@
package org.studiorailgun.conversation.evaluators;
import org.studiorailgun.conversation.Conversation;
import org.studiorailgun.conversation.Quote;
import org.studiorailgun.conversation.categorization.SentenceFunctionCategorizor;
import org.studiorailgun.conversation.evaluators.goal.GoalEval;
/**
* Evaluates a sentence based on data about the sentence
*/
public class EvaluationTree {
/**
* Evaluates a quote
* @param quote The quote
*/
public static void evaluate(Conversation conversation, Quote quote){
//parse data about the quote
SentenceFunctionCategorizor.categorize(quote);
//perform actions based on the tree
switch(quote.getFunction()){
case UTILITY: {
GreetingEval.evaluate(conversation, quote);
} break;
default: {
} break;
}
//evaluate the AI's current goal in the conversation
GoalEval.evaluate(conversation);
//synthesize language based on the results of the actions performed
//TODO
}
}

View File

@ -5,7 +5,9 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.List; import java.util.List;
import org.studiorailgun.conversation.ConvParticipant;
import org.studiorailgun.conversation.Conversation; import org.studiorailgun.conversation.Conversation;
import org.studiorailgun.conversation.Quote;
/** /**
* Evaluates a greeting * Evaluates a greeting
@ -32,9 +34,12 @@ public class GreetingEval {
* Evaluates a greeting * Evaluates a greeting
* @param input The sentence * @param input The sentence
*/ */
public static void evaluate(Conversation conversation, String input){ public static void evaluate(Conversation conversation, Quote input){
if(greetingStrings.contains(input)){ if(greetingStrings.contains(input.getRaw())){
System.out.println("Contained!"); ConvParticipant other = conversation.getOther();
if(!conversation.getGreetingData().getHaveGreeted().contains(other)){
conversation.getGreetingData().getHaveGreeted().add(other);
}
} }
} }

View File

@ -0,0 +1,34 @@
package org.studiorailgun.conversation.evaluators.goal;
/**
* Data about the AI's goal in the conversation
*/
public class GoalData {
/**
* A goal the ai can have for the conversation
*/
public static enum ConversationGoal {
/**
* Say a greeting
*/
GREET,
}
/**
* The goal of the conversation
*/
ConversationGoal goal;
public ConversationGoal getGoal() {
return goal;
}
public void setGoal(ConversationGoal goal) {
this.goal = goal;
}
}

View File

@ -0,0 +1,28 @@
package org.studiorailgun.conversation.evaluators.goal;
import org.studiorailgun.conversation.ConvParticipant;
import org.studiorailgun.conversation.Conversation;
import org.studiorailgun.conversation.evaluators.GreetingData;
import org.studiorailgun.conversation.evaluators.goal.GoalData.ConversationGoal;
/**
* Evaluates the AI's goal in the conversation
*/
public class GoalEval {
/**
* Evaluates the goal of the ai in the given conversation
* @param conversation The conversation
*/
public static void evaluate(Conversation conversation){
GreetingData greetingData = conversation.getGreetingData();
ConvParticipant selfParticipant = conversation.getSelf();
if(!greetingData.getHaveGreeted().contains(selfParticipant)){
conversation.getGoalData().setGoal(ConversationGoal.GREET);
} else {
conversation.getGoalData().setGoal(null);
}
}
}

View File

@ -2,11 +2,7 @@ package org.studiorailgun;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import java.io.File;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.studiorailgun.conversation.Conversation;
import org.studiorailgun.knowledge.KnowledgeWeb;
/** /**
* Tests loading conversations * Tests loading conversations
@ -15,12 +11,9 @@ public class ConvLoadingTests {
@Test @Test
public void testLoadConversation(){ public void testLoadConversation(){
KnowledgeWeb web = FileUtils.loadObjectFromFile(new File("./data/test/webs/web.json"), KnowledgeWeb.class); Globals.init("./data/test/webs/web.json");
web.initLinks(); assertEquals(Globals.web.getSelf(), Globals.conversation.getSelf().getData());
Globals.web = web; assertNotEquals(Globals.web.getSelf(), Globals.conversation.getOther().getData());
Conversation convo = Conversation.parse(web);
assertEquals(web.getSelf(), convo.getSelf().getData());
assertNotEquals(web.getSelf(), convo.getOther().getData());
} }

View File

@ -0,0 +1,21 @@
package org.studiorailgun;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
/**
* Tests greeting
*/
public class GreetingTests {
@Test
public void testOtherGreeting(){
Globals.init("./data/test/webs/web.json");
AI.simFrame("Hello");
assertEquals(Globals.conversation.getGreetingData().getHaveGreeted().size(), 1);
}
}

View File

@ -1,4 +1,5 @@
{ {
"selfId": 2,
"nodes" : { "nodes" : {
"0" : { "0" : {
"id" : 0, "id" : 0,
@ -18,7 +19,19 @@
}, },
"4" : { "4" : {
"id" : 4, "id" : 4,
"name" : "ConversationParticipant" "name" : "Other"
},
"5" : {
"id" : 5,
"name" : "Quote"
},
"6" : {
"id" : 6,
"name" : "Conversation"
},
"7" : {
"id" : 7,
"name" : "CurrentConversation"
} }
}, },
"relations" : { "relations" : {
@ -39,6 +52,24 @@
"name" : "InstanceOf", "name" : "InstanceOf",
"parent" : 1, "parent" : 1,
"child" : 0 "child" : 0
},
"3" : {
"id" : 3,
"name" : "InstanceOf",
"parent" : 3,
"child" : 4
},
"4" : {
"id" : 4,
"name" : "ParticipantOf",
"parent" : 7,
"child" : 4
},
"5" : {
"id" : 5,
"name" : "ParticipantOf",
"parent" : 7,
"child" : 2
} }
} }
} }