Add relation model. Add calculate score initial version

This commit is contained in:
William Jeynes
2026-02-12 23:26:59 +00:00
parent c89f73e138
commit b06c08daab
5 changed files with 60 additions and 18 deletions
+5 -1
View File
@@ -15,13 +15,13 @@ const triggerEventToolNode = createToolNode(triggerEventToolsByName);
const normalisationModel = createModelNode([], "normalization.txt"); const normalisationModel = createModelNode([], "normalization.txt");
const triggerEventModel = createModelNode(triggerEventToolsByName, "trigger.txt"); const triggerEventModel = createModelNode(triggerEventToolsByName, "trigger.txt");
const verificationModel = createModelNode([], "verify.txt"); const verificationModel = createModelNode([], "verify.txt");
const relationModel = createModelNode([], "relation.txt");
const triggerEventToolConditional = createToolConditional("triggerEventToolNode", verificationSetup.name); const triggerEventToolConditional = createToolConditional("triggerEventToolNode", verificationSetup.name);
const agent = new StateGraph(MessagesState) const agent = new StateGraph(MessagesState)
//NODES //NODES
.addNode(normalizationSetup.name, normalizationSetup) .addNode(normalizationSetup.name, normalizationSetup)
.addNode("normalisationModel", normalisationModel) .addNode("normalisationModel", normalisationModel)
@@ -31,6 +31,8 @@ const agent = new StateGraph(MessagesState)
.addNode(verificationSetup.name, verificationSetup) .addNode(verificationSetup.name, verificationSetup)
.addNode("verificationModel", verificationModel) .addNode("verificationModel", verificationModel)
.addNode(ragasMetrics.name, ragasMetrics) .addNode(ragasMetrics.name, ragasMetrics)
.addNode("relationModel", relationModel)
.addNode(produceRanking.name, produceRanking) .addNode(produceRanking.name, produceRanking)
.addEdge(START, normalizationSetup.name) .addEdge(START, normalizationSetup.name)
@@ -43,9 +45,11 @@ const agent = new StateGraph(MessagesState)
.addEdge(verificationSetup.name, "verificationModel") .addEdge(verificationSetup.name, "verificationModel")
.addEdge(verificationSetup.name, ragasMetrics.name) .addEdge(verificationSetup.name, ragasMetrics.name)
.addEdge(verificationSetup.name, "relationModel")
.addEdge(ragasMetrics.name, produceRanking.name) .addEdge(ragasMetrics.name, produceRanking.name)
.addEdge("verificationModel", produceRanking.name) .addEdge("verificationModel", produceRanking.name)
.addEdge("relationModel", produceRanking.name)
// @ts-expect-error // @ts-expect-error
.addConditionalEdges(produceRanking.name, loopEndConditional, [verificationSetup.name, END]) .addConditionalEdges(produceRanking.name, loopEndConditional, [verificationSetup.name, END])
-13
View File
@@ -1,13 +0,0 @@
import { GraphNode } from "@langchain/langgraph";
import { MessagesState } from "../state";
import { AIMessage } from "@langchain/core/messages";
export function createDummyModelNode(addition): GraphNode<typeof MessagesState> {
return async (state) => {
//TODO: call AI model with collected data
return {
messages: [new AIMessage(addition + " : " + state.messages.at(-1)?.content)]
};
};
}
+44 -3
View File
@@ -1,9 +1,50 @@
import { GraphNode } from "@langchain/langgraph"; import { GraphNode } from "@langchain/langgraph";
import { MessagesState } from "../state"; import { MessagesState } from "../state";
import { AIMessage, HumanMessage } from "@langchain/core/messages"; import { BaseMessage } from "@langchain/core/messages";
type Priority = keyof typeof mapping;
const mapping = {
VERYHIGH: 1.0,
HIGH: 0.75,
MEDIUM: 0.5,
LOW: 0.25,
VERYLOW: 0.0
} as const;
function mapResponse(value: string): number {
const upper = value.toUpperCase() as Priority;
if (upper in mapping) {
return mapping[upper];
}
return 0;
}
function getLastMessageContaining(
messages: BaseMessage[],
searchString: string
): string {
for (let i = messages.length - 1; i >= 0; i--) {
const content = messages[i].content;
if (typeof content === "string" && content.includes(searchString)) {
return content;
}
}
return "";
}
export const produceRanking: GraphNode<typeof MessagesState> = async (state) => { export const produceRanking: GraphNode<typeof MessagesState> = async (state) => {
//TODO: produce ranking here //TODO: what should these weights be
let conf = getLastMessageContaining(state.messages, "CONFIDENCE")?.split(":")[1] //TODO: we can better error handle here
let ragas = getLastMessageContaining(state.messages, "RAGAS")?.split(":")[1] //TODO: we can genericify this too surely
let rel = getLastMessageContaining(state.messages, "RELATION")?.split(":")[1]
return { messages: [ new AIMessage(state.messages?.length.toString() ?? "0")] }; let result = mapResponse(conf) * Number.parseFloat(ragas) * mapResponse(rel)
let current = state.proposedTriggerEvent;
current[state.proposedTriggerEventIndex].score = result;
return { proposedTriggerEvent: current };
}; };
+9
View File
@@ -0,0 +1,9 @@
Could the following real-world event:
###TECLAIM###
Be a trigger for the following disinformation:
###TITLE###
Respond with "RELATION", followed by : followed by a confidence score (VERYHIGH, HIGH, MEDIUM, LOW, VERYLOW) followed by : followed by the reason. Use no other words, just return the score and reason in format.
Ignore wether the event happened or not, purely consider the likiness of causation
+2 -1
View File
@@ -16,7 +16,8 @@ export const ProposedTriggerEvent = z.object({
SearchQuery: z.string(), SearchQuery: z.string(),
Url: z.url(), Url: z.url(),
IsItselfDisinformation: z.boolean(), IsItselfDisinformation: z.boolean(),
context: z.string().optional() context: z.string().optional(),
score: z.number().optional
}) })
export const ProposedTriggerEventArray = z.array(ProposedTriggerEvent); export const ProposedTriggerEventArray = z.array(ProposedTriggerEvent);