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" : {
"id" : 4,
"name" : "Other"
},
"5" : {
"id" : 5,
"name" : "Quote"
},
"6" : {
"id" : 6,
"name" : "Conversation"
},
"7" : {
"id" : 7,
"name" : "CurrentConversation"
}
},
"relations" : {
@ -46,6 +58,18 @@
"name" : "InstanceOf",
"parent" : 3,
"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 org.studiorailgun.conversation.Conversation;
import org.studiorailgun.conversation.evaluators.GreetingEval;
import org.studiorailgun.knowledge.KnowledgeWeb;
/**
@ -23,17 +24,15 @@ public class Globals {
/**
* Initializes the knowledge web
*/
public static void init(){
Globals.loadWeb("web.json");
}
public static void init(String webPath){
//initialize evaluators
GreetingEval.init();
/**
* Loads a web
* @param webPath The web's path
*/
public static void loadWeb(String webPath){
Globals.web = FileUtils.loadObjectFromFile(new File("web.json"), KnowledgeWeb.class);
//init web
Globals.web = FileUtils.loadObjectFromFile(new File(webPath), KnowledgeWeb.class);
Globals.web.initLinks();
//init convo
Globals.conversation = Conversation.parse(Globals.web);
}

View File

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

View File

@ -1,7 +1,9 @@
package org.studiorailgun.conversation;
import org.studiorailgun.conversation.evaluators.GreetingData;
import org.studiorailgun.conversation.evaluators.goal.GoalData;
import org.studiorailgun.knowledge.KnowledgeWeb;
import org.studiorailgun.knowledge.Node;
/**
* A conversation
@ -18,35 +20,51 @@ public class Conversation {
*/
ConvParticipant other;
/**
* The node in the knowledge web representing this conversation
*/
Node data;
/**
* Data on greetings
*/
GreetingData greetingData;
/**
* The goal data
*/
GoalData goalData;
/**
* Parses the current conversation's data from the knowledge web
* @param web The web
* @return The conversation
*/
public static Conversation parse(KnowledgeWeb web){
Node node = web.getNode(7);
//find the self
ConvParticipant self = new ConvParticipant(web.getSelf());
//find the other participant
ConvParticipant other = new ConvParticipant(web.getNode(4));
Conversation rVal = new Conversation(self, other);
Conversation rVal = new Conversation(node, self, other);
return rVal;
}
/**
* Constructor
* @param node The node representing this conversation instance
* @param self The participant representing this bot instance
* @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.other = other;
this.greetingData = new GreetingData();
this.goalData = new GoalData();
}
/**
@ -73,4 +91,14 @@ public class Conversation {
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;
import org.studiorailgun.conversation.Quote;
/**
* Categorizes sentences based on function
*/
@ -10,27 +12,35 @@ public class SentenceFunctionCategorizor {
*/
public static enum SentenceFunction {
/**
* Transfers information to the other party
* ie, declaring facts, declaring perspective of the world (how you feel), etc
* "The ball is red". "I don't like that".
* A sentence whose purpose is to perform some non-informational duty in a conversation.
* An example of this could be a greeting or farewell.
*/
TRANSFER_INFORMATION,
UTILITY,
/**
* Query information from the other party
* ie, asking for a fact or perspective
* "Is that ball red?" "What color is your hat?" "How do you feel about that?"
* Transfers a piece of information to another participant. For instance, describing
* the details of an object.
*/
QUERY_INFORMATION,
TRANSFER,
/**
* Queries a piece of information from another participant.
*/
QUERY,
/**
* Commands a participant to do something.
*/
IMPERATIVE,
}
/**
* Categorizes the sentence by function
* @param input The input sentence
* @param input The input quote
* @return The function of the sentence
*/
public static SentenceFunction categorize(String input){
return SentenceFunction.QUERY_INFORMATION;
public static void categorize(Quote input){
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.util.List;
import org.studiorailgun.conversation.ConvParticipant;
import org.studiorailgun.conversation.Conversation;
import org.studiorailgun.conversation.Quote;
/**
* Evaluates a greeting
@ -32,9 +34,12 @@ public class GreetingEval {
* Evaluates a greeting
* @param input The sentence
*/
public static void evaluate(Conversation conversation, String input){
if(greetingStrings.contains(input)){
System.out.println("Contained!");
public static void evaluate(Conversation conversation, Quote input){
if(greetingStrings.contains(input.getRaw())){
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 java.io.File;
import org.junit.jupiter.api.Test;
import org.studiorailgun.conversation.Conversation;
import org.studiorailgun.knowledge.KnowledgeWeb;
/**
* Tests loading conversations
@ -15,12 +11,9 @@ public class ConvLoadingTests {
@Test
public void testLoadConversation(){
KnowledgeWeb web = FileUtils.loadObjectFromFile(new File("./data/test/webs/web.json"), KnowledgeWeb.class);
web.initLinks();
Globals.web = web;
Conversation convo = Conversation.parse(web);
assertEquals(web.getSelf(), convo.getSelf().getData());
assertNotEquals(web.getSelf(), convo.getOther().getData());
Globals.init("./data/test/webs/web.json");
assertEquals(Globals.web.getSelf(), Globals.conversation.getSelf().getData());
assertNotEquals(Globals.web.getSelf(), Globals.conversation.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" : {
"0" : {
"id" : 0,
@ -18,7 +19,19 @@
},
"4" : {
"id" : 4,
"name" : "ConversationParticipant"
"name" : "Other"
},
"5" : {
"id" : 5,
"name" : "Quote"
},
"6" : {
"id" : 6,
"name" : "Conversation"
},
"7" : {
"id" : 7,
"name" : "CurrentConversation"
}
},
"relations" : {
@ -39,6 +52,24 @@
"name" : "InstanceOf",
"parent" : 1,
"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
}
}
}