agsamantha/node_modules/langchain/dist/experimental/babyagi/agent.cjs
2024-10-02 15:15:21 -05:00

274 lines
10 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BabyAGI = void 0;
const documents_1 = require("@langchain/core/documents");
const base_js_1 = require("../../chains/base.cjs");
const task_creation_js_1 = require("./task_creation.cjs");
const task_execution_js_1 = require("./task_execution.cjs");
const task_prioritization_js_1 = require("./task_prioritization.cjs");
/**
* Class responsible for managing tasks, including their creation,
* prioritization, and execution. It uses three chains for these
* operations: `creationChain`, `prioritizationChain`, and
* `executionChain`.
* @example
* ```typescript
* const babyAGI = BabyAGI.fromLLM({
* llm: new OpenAI({ temperature: 0 }),
* vectorstore: new MemoryVectorStore(new OpenAIEmbeddings()),
* maxIterations: 3,
* });
*
* const result = await babyAGI.call({
* objective: "Write a weather report for SF today",
* });
* ```
*/
class BabyAGI extends base_js_1.BaseChain {
static lc_name() {
return "BabyAGI";
}
constructor({ creationChain, prioritizationChain, executionChain, vectorstore, maxIterations = 100, verbose, callbacks, }) {
super(undefined, verbose, callbacks);
Object.defineProperty(this, "taskList", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "creationChain", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "prioritizationChain", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "executionChain", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "taskIDCounter", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "vectorstore", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "maxIterations", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.taskList = [];
this.creationChain = creationChain;
this.prioritizationChain = prioritizationChain;
this.executionChain = executionChain;
this.taskIDCounter = 1;
this.vectorstore = vectorstore;
this.maxIterations = maxIterations;
}
_chainType() {
return "BabyAGI";
}
get inputKeys() {
return ["objective", "firstTask"];
}
get outputKeys() {
return [];
}
/**
* Adds a task to the task list.
* @param task The task to be added.
* @returns Promise resolving to void.
*/
async addTask(task) {
this.taskList.push(task);
}
/**
* Prints the current task list to the console.
* @returns void
*/
printTaskList() {
console.log("\x1b[95m\x1b[1m\n*****TASK LIST*****\n\x1b[0m\x1b[0m");
for (const t of this.taskList) {
console.log(`${t.taskID}: ${t.taskName}`);
}
}
/**
* Prints the next task to the console.
* @param task The next task to be printed.
* @returns void
*/
printNextTask(task) {
console.log("\x1b[92m\x1b[1m\n*****NEXT TASK*****\n\x1b[0m\x1b[0m");
console.log(`${task.taskID}: ${task.taskName}`);
}
/**
* Prints the result of a task to the console.
* @param result The result of the task.
* @returns void
*/
printTaskResult(result) {
console.log("\x1b[93m\x1b[1m\n*****TASK RESULT*****\n\x1b[0m\x1b[0m");
console.log(result.trim());
}
/**
* Generates the next tasks based on the result of the previous task, the
* task description, and the objective.
* @param result The result of the previous task.
* @param task_description The description of the task.
* @param objective The objective of the task.
* @param runManager Optional CallbackManagerForChainRun instance.
* @returns Promise resolving to an array of tasks without taskID.
*/
async getNextTasks(result, task_description, objective, runManager) {
const taskNames = this.taskList.map((t) => t.taskName);
const incomplete_tasks = taskNames.join(", ");
const { [this.creationChain.outputKeys[0]]: text } = await this.creationChain.call({
result,
task_description,
incomplete_tasks,
objective,
}, runManager?.getChild());
const newTasks = text.split("\n");
return newTasks
.filter((taskName) => taskName.trim())
.map((taskName) => ({ taskName }));
}
/**
* Prioritizes the tasks based on the current task ID and the objective.
* @param thisTaskID The ID of the current task.
* @param objective The objective of the task.
* @param runManager Optional CallbackManagerForChainRun instance.
* @returns Promise resolving to an array of prioritized tasks.
*/
async prioritizeTasks(thisTaskID, objective, runManager) {
const taskNames = this.taskList.map((t) => t.taskName);
const nextTaskID = thisTaskID + 1;
const { [this.prioritizationChain.outputKeys[0]]: text } = await this.prioritizationChain.call({
task_names: taskNames.join(", "),
next_task_id: String(nextTaskID),
objective,
}, runManager?.getChild());
const newTasks = text.trim().split("\n");
const prioritizedTaskList = [];
for (const taskString of newTasks) {
const taskParts = taskString.trim().split(".", 2);
if (taskParts.length === 2) {
const taskID = taskParts[0].trim();
const taskName = taskParts[1].trim();
prioritizedTaskList.push({ taskID, taskName });
}
}
return prioritizedTaskList;
}
/**
* Retrieves the top tasks that are most similar to the given query.
* @param query The query to search for.
* @param k The number of top tasks to retrieve.
* @returns Promise resolving to an array of top tasks.
*/
async getTopTasks(query, k = 5) {
const results = await this.vectorstore.similaritySearch(query, k);
if (!results) {
return [];
}
return results.map((item) => String(item.metadata.task));
}
/**
* Executes a task based on the objective and the task description.
* @param objective The objective of the task.
* @param task The task to be executed.
* @param runManager Optional CallbackManagerForChainRun instance.
* @returns Promise resolving to the result of the task execution as a string.
*/
async executeTask(objective, task, runManager) {
const context = await this.getTopTasks(objective);
const { [this.executionChain.outputKeys[0]]: text } = await this.executionChain.call({
objective,
context: context.join("\n"),
task,
}, runManager?.getChild());
return text;
}
async _call({ objective, firstTask = "Make a todo list" }, runManager) {
this.taskList = [];
this.taskIDCounter = 1;
await this.addTask({ taskID: "1", taskName: firstTask });
let numIters = 0;
while (numIters < this.maxIterations && this.taskList.length > 0) {
this.printTaskList();
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const task = this.taskList.shift();
this.printNextTask(task);
const result = await this.executeTask(objective, task.taskName, runManager);
const thisTaskID = parseInt(task.taskID, 10);
this.printTaskResult(result);
await this.vectorstore.addDocuments([
new documents_1.Document({
pageContent: result,
metadata: { task: task.taskName },
}),
]);
const newTasks = await this.getNextTasks(result, task.taskName, objective, runManager);
for (const newTask of newTasks) {
this.taskIDCounter += 1;
newTask.taskID = this.taskIDCounter.toFixed();
await this.addTask(newTask);
}
this.taskList = await this.prioritizeTasks(thisTaskID, objective, runManager);
numIters += 1;
}
return {};
}
serialize() {
throw new Error("Method not implemented.");
}
/**
* Static method to create a new BabyAGI instance from a
* BaseLanguageModel.
* @param llm BaseLanguageModel instance used to generate a new BabyAGI instance.
* @param vectorstore VectorStore instance used to store and retrieve vectors.
* @param executionChain Optional BaseChain instance used to execute tasks.
* @param verbose Optional boolean indicating whether to log verbose output.
* @param callbacks Optional callbacks to be used during the execution of tasks.
* @param rest Optional additional parameters.
* @returns A new instance of BabyAGI.
*/
static fromLLM({ llm, vectorstore, executionChain, verbose, callbacks, ...rest }) {
const creationChain = task_creation_js_1.TaskCreationChain.fromLLM({
llm,
verbose,
callbacks,
});
const prioritizationChain = task_prioritization_js_1.TaskPrioritizationChain.fromLLM({
llm,
verbose,
callbacks,
});
return new BabyAGI({
creationChain,
prioritizationChain,
executionChain: executionChain ||
task_execution_js_1.TaskExecutionChain.fromLLM({ llm, verbose, callbacks }),
vectorstore,
verbose,
callbacks,
...rest,
});
}
}
exports.BabyAGI = BabyAGI;