Updated router to persist across transactions
This commit is contained in:
parent
a00fb4f133
commit
ac688019ca
@ -1,27 +1,125 @@
|
|||||||
const { recognizedObject: r = {} } = this;
|
const { conversationData: c = {}, recognizedObject: r = {} } = this;
|
||||||
|
|
||||||
class Router {
|
class Router {
|
||||||
constructor() {
|
constructor() {
|
||||||
r.router = {
|
r.router = { logs: [] };
|
||||||
agents: [],
|
if (c.router) {
|
||||||
};
|
r.router.logs.push("Router Already Initialized");
|
||||||
|
} else {
|
||||||
|
r.router.logs.push("Initializing Router");
|
||||||
|
c.router = {
|
||||||
|
agents: [],
|
||||||
|
nextAction: "Next",
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setAgents(agents) {
|
setNextAction(action) {
|
||||||
r.router.agents = agents;
|
c.router.nextAction = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
getNextAction() {
|
||||||
|
return c.router.nextAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasNext() {
|
hasNext() {
|
||||||
return r.router.agents.some((agent) => agent.state === "submitted");
|
return c.router.agents.some((agent) => agent.state === "submitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
next() {
|
next() {
|
||||||
return r.router.agents.find((agent) => agent.state === "submitted");
|
return c.router.agents.find((agent) => agent.state === "submitted");
|
||||||
|
}
|
||||||
|
|
||||||
|
getActiveAgent() {
|
||||||
|
return c.router.agents.find((agent) => agent.state === "active");
|
||||||
|
}
|
||||||
|
|
||||||
|
log(message) {
|
||||||
|
if (typeof message === "string" || message instanceof String) {
|
||||||
|
r.router.logs.push("" + message);
|
||||||
|
} else {
|
||||||
|
r.router.logs.push(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async assignAgents() {
|
||||||
|
const intents = [
|
||||||
|
{
|
||||||
|
name: "Invoice_Agent",
|
||||||
|
description: "Answers Questions about Invoices and Orders",
|
||||||
|
priority: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Device_Agent",
|
||||||
|
description: "Answers Questions about Devices, Models and Setup",
|
||||||
|
priority: 1,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const { data } = await request.post("/test", {
|
||||||
|
modelId: "us.anthropic.claude-3-7-sonnet-20250219-v1:0",
|
||||||
|
body: {
|
||||||
|
max_tokens: 1024,
|
||||||
|
anthropic_version: "bedrock-2023-05-31",
|
||||||
|
system: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `You are a helpful assistant, designed to classify user utterances and return all matched intents based on their descriptions.\nClassify the following user utterance and return **all matched intents** from the list below.\nIf the input does not match any intents, respond with "UNABLE TO CLASSIFY".\nThis is the list of available intents and their descriptions to match against:\n\n${intents
|
||||||
|
.map((intent) => `- ${intent.name}: ${intent.description}`)
|
||||||
|
.join(
|
||||||
|
"\n"
|
||||||
|
)}\n\nReturn the matched intents and the part of the input that matched each intent on their own line. For example:\n\nIntent A: partial utterance\nIntent B: partial utterance`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
role: "user",
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: recognizedObject.input,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
temperature: 1.0,
|
||||||
|
},
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: "AKIAXSFOCMMUBXR67SUK",
|
||||||
|
secretAccessKey: "bhV0HY3w0B+6eWQpwozhdayiXs+oVdvdJWq23S1n",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
r.router.logs.push({ agentClassification: data });
|
||||||
|
recognizedObject.classifier = data;
|
||||||
|
const tool = data?.content?.[0]?.text;
|
||||||
|
if (tool.includes("UNABLE TO CLASSIFY")) {
|
||||||
|
r.router.logs.push("No intent matched");
|
||||||
|
} else {
|
||||||
|
const list = tool.split("\n").map((line) => line.trim());
|
||||||
|
const results = list.map((line) => {
|
||||||
|
const [intent, utterance] = line.split(":").map((part) => part.trim());
|
||||||
|
return { intent, utterance };
|
||||||
|
});
|
||||||
|
results.sort((a, b) => {
|
||||||
|
const priorityA =
|
||||||
|
intents.find((intent) => intent.name === a.intent)?.priority || 0;
|
||||||
|
const priorityB =
|
||||||
|
intents.find((intent) => intent.name === b.intent)?.priority || 0;
|
||||||
|
return priorityA - priorityB;
|
||||||
|
});
|
||||||
|
c.router.agents = results.map((agent) => ({
|
||||||
|
id: agent.intent,
|
||||||
|
input: agent.utterance,
|
||||||
|
state: "submitted",
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(id, state) {
|
setState(id, state) {
|
||||||
const agent = r.router.agents.find((agent) => agent.id === id);
|
const agent = c.router.agents.find((agent) => agent.id === id);
|
||||||
if (agent) agent.state = state;
|
if (agent) {
|
||||||
|
agent.state = state;
|
||||||
|
r.router.logs.push(`router.setState: agent=${JSON.stringify(agent)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
68
AI-agents/snippets/routerLogic.js
Normal file
68
AI-agents/snippets/routerLogic.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
(async () => {
|
||||||
|
router.setNextAction("Next");
|
||||||
|
|
||||||
|
// Did the Model Respond?
|
||||||
|
if (recognizedObject.answers.length) {
|
||||||
|
// Yes
|
||||||
|
router.log("Model Responded");
|
||||||
|
router.log({ answers: recognizedObject.answers });
|
||||||
|
const activeAgent = router.getActiveAgent();
|
||||||
|
if (activeAgent) {
|
||||||
|
router.log("Model Responded -> Agent Active");
|
||||||
|
router.log(activeAgent);
|
||||||
|
router.setNextAction("ReturnAnswers");
|
||||||
|
} else {
|
||||||
|
router.log("Model Responded -> No Agent Active");
|
||||||
|
if (router.hasNext()) {
|
||||||
|
router.log("Model Responded -> No Agent Active -> Router Has next");
|
||||||
|
// Run Next Agent
|
||||||
|
router.setNextAction("RunNextAgent");
|
||||||
|
} else {
|
||||||
|
router.log("Model Responded -> No Agent Active -> Router Empty");
|
||||||
|
// Return Answers
|
||||||
|
// Run Next Agent
|
||||||
|
router.setNextAction("ReturnAnswers");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
router.log("Model Did Not Respond");
|
||||||
|
// No
|
||||||
|
const activeAgent = router.getActiveAgent();
|
||||||
|
if (activeAgent) {
|
||||||
|
router.log("Model Did Not Respond -> Agent Active");
|
||||||
|
router.log("Deactivate Agent because it didn't respond");
|
||||||
|
// Deactivate Agent because it didn't respond
|
||||||
|
activeAgent.state = "Deactivated Agent because it didn't respond";
|
||||||
|
}
|
||||||
|
if (router.hasNext()) {
|
||||||
|
router.log("Model Did Not Respond -> Router Has next");
|
||||||
|
// Assign Agents
|
||||||
|
// Run Next Agent
|
||||||
|
router.setNextAction("RunNextAgent");
|
||||||
|
} else {
|
||||||
|
router.log("Model Did Not Respond -> Router Empty");
|
||||||
|
router.log("Assign Agents");
|
||||||
|
await router.assignAgents();
|
||||||
|
|
||||||
|
if (router.hasNext()) {
|
||||||
|
router.log(
|
||||||
|
"Model Did Not Respond -> Router was Empty -> Router has next"
|
||||||
|
);
|
||||||
|
router.setNextAction("RunNextAgent");
|
||||||
|
} else {
|
||||||
|
router.log(
|
||||||
|
"Model Did Not Respond -> Router was Empty -> Router still Empty"
|
||||||
|
);
|
||||||
|
// Return Answers
|
||||||
|
router.setNextAction("Next");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
.catch((e) => {
|
||||||
|
router.log(e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
router.log("Router Next Action: " + router.getNextAction());
|
||||||
|
next();
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user