From 7fe63d6a9881f7a18f4d1a7d17fbc18cabfb50a7 Mon Sep 17 00:00:00 2001 From: William Jeynes Date: Thu, 12 Feb 2026 23:46:00 +0000 Subject: [PATCH] Refactor calculating score. Add sort node for vanity --- agent/agent.ts | 6 ++++- agent/conditionals/loop_end.ts | 2 +- agent/nodes/produceRanking.ts | 48 ++++++++++++++++++++-------------- agent/nodes/ragasMetrics.ts | 2 -- agent/nodes/sort.ts | 20 ++++++++++++++ agent/state.ts | 8 +----- 6 files changed, 56 insertions(+), 30 deletions(-) create mode 100644 agent/nodes/sort.ts diff --git a/agent/agent.ts b/agent/agent.ts index 475bfce..897b718 100644 --- a/agent/agent.ts +++ b/agent/agent.ts @@ -9,6 +9,7 @@ import { ragasMetrics } from "./nodes/ragasMetrics"; import { produceRanking } from "./nodes/produceRanking"; import { createModelNode } from "./nodes/model"; import { loopEndConditional } from "./conditionals/loop_end"; +import { sort } from "./nodes/sort"; const triggerEventToolNode = createToolNode(triggerEventToolsByName); @@ -34,6 +35,7 @@ const agent = new StateGraph(MessagesState) .addNode("relationModel", relationModel) .addNode(produceRanking.name, produceRanking) + .addNode(sort.name, sort) .addEdge(START, normalizationSetup.name) .addEdge(normalizationSetup.name, "normalisationModel") @@ -52,8 +54,10 @@ const agent = new StateGraph(MessagesState) .addEdge("relationModel", produceRanking.name) // @ts-expect-error - .addConditionalEdges(produceRanking.name, loopEndConditional, [verificationSetup.name, END]) + .addConditionalEdges(produceRanking.name, loopEndConditional, [verificationSetup.name, sort.name]) + .addEdge(sort.name, END) + .compile(); export {agent} \ No newline at end of file diff --git a/agent/conditionals/loop_end.ts b/agent/conditionals/loop_end.ts index 553d3f1..56ee6d8 100644 --- a/agent/conditionals/loop_end.ts +++ b/agent/conditionals/loop_end.ts @@ -7,7 +7,7 @@ export const loopEndConditional: ConditionalEdgeRouter= 0; i--) { const content = messages[i].content; if (typeof content === "string" && content.includes(searchString)) { return content; } } - return ""; + return null; } export const produceRanking: GraphNode = async (state) => { - //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] + // Extract and map values + const values = keys.map((key) => { + const msg = getLastMessageContaining(state.messages, key); + const part = msg?.split(":").at(1); + return mapResponse(part); + }); - let result = mapResponse(conf) * Number.parseFloat(ragas) * mapResponse(rel) - - let current = state.proposedTriggerEvent; + // Multiply! + const result = values.reduce((acc, val) => acc * val, 1); + + const current = state.proposedTriggerEvent; current[state.proposedTriggerEventIndex].score = result; - return { proposedTriggerEvent: current }; -}; \ No newline at end of file + return { proposedTriggerEvent: current }; +}; diff --git a/agent/nodes/ragasMetrics.ts b/agent/nodes/ragasMetrics.ts index ee72693..d380fdb 100644 --- a/agent/nodes/ragasMetrics.ts +++ b/agent/nodes/ragasMetrics.ts @@ -8,8 +8,6 @@ export const ragasMetrics: GraphNode = async (state) => { const answer = state.proposedTriggerEvent[state.proposedTriggerEventIndex].Event const contexts = state.proposedTriggerEvent[state.proposedTriggerEventIndex].context?.split("^^^") ?? [] - console.log(contexts) - const results = await evaluateWithRagas({question, answer, contexts}) return { diff --git a/agent/nodes/sort.ts b/agent/nodes/sort.ts new file mode 100644 index 0000000..6366a71 --- /dev/null +++ b/agent/nodes/sort.ts @@ -0,0 +1,20 @@ +import { GraphNode } from "@langchain/langgraph"; +import { MessagesState } from "../state"; +import { AIMessage } from "@langchain/core/messages"; +export const sort: GraphNode = async (state) => { + //not sure which will be better from API, just do both + + let current = state.proposedTriggerEvent; + current.sort((a, b) => ((b.score as number) ?? 0) - ((a.score as number) ?? 0)); + + + const displayVersion = current.map((item) => ({ + event: item.Event, + reasoningWhyRelevant: item.ReasoningWhyRelevant, + score: item.score ?? 0, + })); + + let message = new AIMessage(JSON.stringify(displayVersion)) + + return { proposedTriggerEvent: current, messages: [message] }; +}; diff --git a/agent/state.ts b/agent/state.ts index d9e5cb1..d98bcc9 100644 --- a/agent/state.ts +++ b/agent/state.ts @@ -1,12 +1,6 @@ import { - StateGraph, StateSchema, MessagesValue, - ReducedValue, - GraphNode, - ConditionalEdgeRouter, - START, - END, } from "@langchain/langgraph"; import { z } from "zod/v4"; @@ -17,7 +11,7 @@ export const ProposedTriggerEvent = z.object({ Url: z.url(), IsItselfDisinformation: z.boolean(), context: z.string().optional(), - score: z.number().optional + score: z.number().optional() }) export const ProposedTriggerEventArray = z.array(ProposedTriggerEvent);