File size: 6,700 Bytes
f8b5d42 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
const { v4 } = require("uuid");
const { getVectorDbClass, getLLMProvider } = require("../../../helpers");
const { Deduplicator } = require("../utils/dedupe");
const memory = {
name: "rag-memory",
startupConfig: {
params: {},
},
plugin: function () {
return {
name: this.name,
setup(aibitat) {
aibitat.function({
super: aibitat,
tracker: new Deduplicator(),
name: this.name,
description:
"Search against local documents for context that is relevant to the query or store a snippet of text into memory for retrieval later. Storing information should only be done when the user specifically requests for information to be remembered or saved to long-term memory. You should use this tool before search the internet for information. Do not use this tool unless you are explicitly told to 'remember' or 'store' information.",
examples: [
{
prompt: "What is AnythingLLM?",
call: JSON.stringify({
action: "search",
content: "What is AnythingLLM?",
}),
},
{
prompt: "What do you know about Plato's motives?",
call: JSON.stringify({
action: "search",
content: "What are the facts about Plato's motives?",
}),
},
{
prompt: "Remember that you are a robot",
call: JSON.stringify({
action: "store",
content: "I am a robot, the user told me that i am.",
}),
},
{
prompt: "Save that to memory please.",
call: JSON.stringify({
action: "store",
content: "<insert summary of conversation until now>",
}),
},
],
parameters: {
$schema: "http://json-schema.org/draft-07/schema#",
type: "object",
properties: {
action: {
type: "string",
enum: ["search", "store"],
description:
"The action we want to take to search for existing similar context or storage of new context.",
},
content: {
type: "string",
description:
"The plain text to search our local documents with or to store in our vector database.",
},
},
additionalProperties: false,
},
handler: async function ({ action = "", content = "" }) {
try {
if (this.tracker.isDuplicate(this.name, { action, content }))
return `This was a duplicated call and it's output will be ignored.`;
let response = "There was nothing to do.";
if (action === "search") response = await this.search(content);
if (action === "store") response = await this.store(content);
this.tracker.trackRun(this.name, { action, content });
return response;
} catch (error) {
console.log(error);
return `There was an error while calling the function. ${error.message}`;
}
},
search: async function (query = "") {
try {
const workspace = this.super.handlerProps.invocation.workspace;
const LLMConnector = getLLMProvider({
provider: workspace?.chatProvider,
model: workspace?.chatModel,
});
const vectorDB = getVectorDbClass();
const { contextTexts = [] } =
await vectorDB.performSimilaritySearch({
namespace: workspace.slug,
input: query,
LLMConnector,
topN: workspace?.topN ?? 4,
rerank: workspace?.vectorSearchMode === "rerank",
});
if (contextTexts.length === 0) {
this.super.introspect(
`${this.caller}: I didn't find anything locally that would help answer this question.`
);
return "There was no additional context found for that query. We should search the web for this information.";
}
this.super.introspect(
`${this.caller}: Found ${contextTexts.length} additional piece of context to help answer this question.`
);
let combinedText = "Additional context for query:\n";
for (const text of contextTexts) combinedText += text + "\n\n";
return combinedText;
} catch (error) {
this.super.handlerProps.log(
`memory.search raised an error. ${error.message}`
);
return `An error was raised while searching the vector database. ${error.message}`;
}
},
store: async function (content = "") {
try {
const workspace = this.super.handlerProps.invocation.workspace;
const vectorDB = getVectorDbClass();
const { error } = await vectorDB.addDocumentToNamespace(
workspace.slug,
{
docId: v4(),
id: v4(),
url: "file://embed-via-agent.txt",
title: "agent-memory.txt",
docAuthor: "@agent",
description: "Unknown",
docSource: "a text file stored by the workspace agent.",
chunkSource: "",
published: new Date().toLocaleString(),
wordCount: content.split(" ").length,
pageContent: content,
token_count_estimate: 0,
},
null
);
if (!!error)
return "The content was failed to be embedded properly.";
this.super.introspect(
`${this.caller}: I saved the content to long-term memory in this workspaces vector database.`
);
return "The content given was successfully embedded. There is nothing else to do.";
} catch (error) {
this.super.handlerProps.log(
`memory.store raised an error. ${error.message}`
);
return `Let the user know this action was not successful. An error was raised while storing data in the vector database. ${error.message}`;
}
},
});
},
};
},
};
module.exports = {
memory,
};
|