mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-19 20:50:09 +01:00
99f2c25b1c
* Enable agent context windows to be accurate per provider:model * Refactor model mapping to external file Add token count to document length instead of char-count refernce promptWindowLimit from AIProvider in central location * remove unused imports
181 lines
6.5 KiB
JavaScript
181 lines
6.5 KiB
JavaScript
const { Document } = require("../../../../models/documents");
|
|
const { safeJsonParse } = require("../../../http");
|
|
const { summarizeContent } = require("../utils/summarize");
|
|
const Provider = require("../providers/ai-provider");
|
|
|
|
const docSummarizer = {
|
|
name: "document-summarizer",
|
|
startupConfig: {
|
|
params: {},
|
|
},
|
|
plugin: function () {
|
|
return {
|
|
name: this.name,
|
|
setup(aibitat) {
|
|
aibitat.function({
|
|
super: aibitat,
|
|
name: this.name,
|
|
controller: new AbortController(),
|
|
description:
|
|
"Can get the list of files available to search with descriptions and can select a single file to open and summarize.",
|
|
examples: [
|
|
{
|
|
prompt: "Summarize example.txt",
|
|
call: JSON.stringify({
|
|
action: "summarize",
|
|
document_filename: "example.txt",
|
|
}),
|
|
},
|
|
{
|
|
prompt: "What files can you see?",
|
|
call: JSON.stringify({ action: "list", document_filename: null }),
|
|
},
|
|
{
|
|
prompt: "Tell me about readme.md",
|
|
call: JSON.stringify({
|
|
action: "summarize",
|
|
document_filename: "readme.md",
|
|
}),
|
|
},
|
|
],
|
|
parameters: {
|
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
type: "object",
|
|
properties: {
|
|
action: {
|
|
type: "string",
|
|
enum: ["list", "summarize"],
|
|
description:
|
|
"The action to take. 'list' will return all files available with their filename and descriptions. 'summarize' will open and summarize the file by the a document name.",
|
|
},
|
|
document_filename: {
|
|
type: "string",
|
|
"x-nullable": true,
|
|
description:
|
|
"The file name of the document you want to get the full content of.",
|
|
},
|
|
},
|
|
additionalProperties: false,
|
|
},
|
|
handler: async function ({ action, document_filename }) {
|
|
if (action === "list") return await this.listDocuments();
|
|
if (action === "summarize")
|
|
return await this.summarizeDoc(document_filename);
|
|
return "There is nothing we can do. This function call returns no information.";
|
|
},
|
|
|
|
/**
|
|
* List all documents available in a workspace
|
|
* @returns List of files and their descriptions if available.
|
|
*/
|
|
listDocuments: async function () {
|
|
try {
|
|
this.super.introspect(
|
|
`${this.caller}: Looking at the available documents.`
|
|
);
|
|
const documents = await Document.where({
|
|
workspaceId: this.super.handlerProps.invocation.workspace_id,
|
|
});
|
|
if (documents.length === 0)
|
|
return "No documents found - nothing can be done. Stop.";
|
|
|
|
this.super.introspect(
|
|
`${this.caller}: Found ${documents.length} documents`
|
|
);
|
|
const foundDocuments = documents.map((doc) => {
|
|
const metadata = safeJsonParse(doc.metadata, {});
|
|
return {
|
|
document_id: doc.docId,
|
|
filename: metadata?.title ?? "unknown.txt",
|
|
description: metadata?.description ?? "no description",
|
|
};
|
|
});
|
|
|
|
return JSON.stringify(foundDocuments);
|
|
} catch (error) {
|
|
this.super.handlerProps.log(
|
|
`document-summarizer.list raised an error. ${error.message}`
|
|
);
|
|
return `Let the user know this action was not successful. An error was raised while listing available files. ${error.message}`;
|
|
}
|
|
},
|
|
|
|
summarizeDoc: async function (filename) {
|
|
try {
|
|
const availableDocs = safeJsonParse(
|
|
await this.listDocuments(),
|
|
[]
|
|
);
|
|
if (!availableDocs.length) {
|
|
this.super.handlerProps.log(
|
|
`${this.caller}: No available documents to summarize.`
|
|
);
|
|
return "No documents were found.";
|
|
}
|
|
|
|
const docInfo = availableDocs.find(
|
|
(info) => info.filename === filename
|
|
);
|
|
if (!docInfo) {
|
|
this.super.handlerProps.log(
|
|
`${this.caller}: No available document by the name "${filename}".`
|
|
);
|
|
return `No available document by the name "${filename}".`;
|
|
}
|
|
|
|
const document = await Document.content(docInfo.document_id);
|
|
this.super.introspect(
|
|
`${this.caller}: Grabbing all content for ${
|
|
filename ?? "a discovered file."
|
|
}`
|
|
);
|
|
|
|
if (!document.content || document.content.length === 0) {
|
|
throw new Error(
|
|
"This document has no readable content that could be found."
|
|
);
|
|
}
|
|
|
|
const { TokenManager } = require("../../../helpers/tiktoken");
|
|
if (
|
|
new TokenManager(this.super.model).countFromString(
|
|
document.content
|
|
) < Provider.contextLimit(this.super.provider, this.super.model)
|
|
) {
|
|
return document.content;
|
|
}
|
|
|
|
this.super.introspect(
|
|
`${this.caller}: Summarizing ${filename ?? ""}...`
|
|
);
|
|
|
|
this.super.onAbort(() => {
|
|
this.super.handlerProps.log(
|
|
"Abort was triggered, exiting summarization early."
|
|
);
|
|
this.controller.abort();
|
|
});
|
|
|
|
return await summarizeContent({
|
|
provider: this.super.provider,
|
|
model: this.super.model,
|
|
controllerSignal: this.controller.signal,
|
|
content: document.content,
|
|
});
|
|
} catch (error) {
|
|
this.super.handlerProps.log(
|
|
`document-summarizer.summarizeDoc raised an error. ${error.message}`
|
|
);
|
|
return `Let the user know this action was not successful. An error was raised while summarizing the file. ${error.message}`;
|
|
}
|
|
},
|
|
});
|
|
},
|
|
};
|
|
},
|
|
};
|
|
|
|
module.exports = {
|
|
docSummarizer,
|
|
};
|