UNPKG

node-agency

Version:
379 lines 19.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Model = void 0; const openai_1 = __importDefault(require("openai")); const utils_1 = require("../utils"); const logger_1 = require("../logger"); function isParseableJson(str) { try { return JSON.parse(str); } catch (e) { return null; } } class Model { constructor(options) { this.history = []; this.selfReflected = 0; this.parallelToolCalls = false; this.isManager = false; this.model = "gpt-3.5-turbo"; this.selfReflect = true; const { parallelToolCalls, OPENAI_API_KEY, model, selfReflect } = options || {}; const openai = new openai_1.default({ apiKey: OPENAI_API_KEY || process.env.OPENAI_API_KEY, }); this.openai = openai; this.parallelToolCalls = parallelToolCalls || false; this.model = model || this.model; this.selfReflect = selfReflect !== null && selfReflect !== void 0 ? selfReflect : true; } call(systemMessage, prompt, tools, context) { return __awaiter(this, void 0, void 0, function* () { prompt.content = prompt.content + (context ? "\n\n## This is results from your coworkers to help you with your task:\n" + context : ""); // console.log("-----------------"); // console.log("Prompt: ", prompt.content); // console.log("-----------------"); // debugger; this.history.push(prompt); const messages = [ { role: "system", content: systemMessage, }, ...this.history, ]; try { const message = yield this.callGPT(messages, tools); this.history.push({ role: "assistant", content: message.content, tool_calls: message.tool_calls, }); if (message.tool_calls) { if (message.content) { (0, logger_1.Logger)({ type: "info", payload: "\n\n" + message.content + "\n\n", }); } const { tool_calls } = message; const toolMessagesResolved = []; const coWorkerCalls = tool_calls.filter((tool_call) => { return (tool_call.function.name === "delegate_task" || tool_call.function.name === "ask_question"); }); if (this.parallelToolCalls && !this.isManager) { const filteredCalls = tool_calls.filter((tool_call) => { return (tool_call.function.name !== "delegate_task" && tool_call.function.name !== "ask_question"); }); const toolMessagePromises = filteredCalls.map((tool_call) => __awaiter(this, void 0, void 0, function* () { return this.processingToolCall(tool_call); })); const toolMessagesSettled = yield Promise.allSettled(toolMessagePromises); for (const toolMessage of toolMessagesSettled) { if (toolMessage.status === "fulfilled") { toolMessagesResolved.push(toolMessage.value); } } for (const tool_call of coWorkerCalls) { const toolMessage = yield this.processingToolCall(tool_call); toolMessagesResolved.push(toolMessage); } } else { for (const tool_call of tool_calls) { const toolMessage = yield this.processingToolCall(tool_call); toolMessagesResolved.push(toolMessage); } } const allMessagesHasResvoled = tool_calls.every((message) => { return toolMessagesResolved.find((toolMessage) => toolMessage.tool_call_id === message.id); }); if (!allMessagesHasResvoled) { const missingToolCalls = tool_calls.filter((message) => { return !toolMessagesResolved.find((toolMessage) => { toolMessage.tool_call_id === message.id; }); }); throw new Error("Failed to resolve all tool calls Missing: " + missingToolCalls .map((message) => `Name: '${message.function.name}', ID:${message.id}`) .join(", ")); } const lastMessage = toolMessagesResolved[toolMessagesResolved.length - 1]; const allButLastMessage = toolMessagesResolved.slice(0, toolMessagesResolved.length - 1); this.history.push(...allButLastMessage); return this.call(systemMessage, lastMessage, tools); } // if (message.content && !message.content.includes("<CONTINUE>")) { // const maxRuntime = new Date().getTime() + 1000 * 60 * 5; // let currentTime = new Date().getTime(); // let currentStep = "plan"; // while (currentStep === "plan" && currentTime < maxRuntime) { // const plan = await this.call( // systemMessage, // { // role: "user", // content: // "Plan your next steps, when you are ready, if there are no more steps to take then indicate you are done with <CONTINUE> at the very end of your response.", // }, // tools // ); // if (!plan.includes("<CONTINUE>")) { // message.content = plan; // currentTime = new Date().getTime(); // } else { // message.content = plan.replace("<CONTINUE>", ""); // currentStep = "execute"; // } // } // } return message.content || "Unknown Error Occurred, Please try again."; } catch (error) { console.error(error); throw new Error("Failed to call GPT-3"); } }); } callStream(systemMessage, prompt, callback, tools, context) { return __awaiter(this, void 0, void 0, function* () { prompt.content = prompt.content + (context ? "\n\nHere is further context to help you with your task:\n" + context : ""); this.history.push(prompt); const messages = [ { role: "system", content: systemMessage, }, ...this.history, ]; try { const message = yield this.callGPTStream(messages, callback, tools); return message; } catch (error) { console.error(error); throw new Error("Failed to call GPT-3"); } }); } processingToolCall(tool_call) { return __awaiter(this, void 0, void 0, function* () { const { name, arguments: args } = tool_call.function; (0, logger_1.Logger)({ type: "function", payload: JSON.stringify({ name, params: args, }), }); const result = yield (0, utils_1.callFunction)(name, args); const toolMessage = { role: "tool", tool_call_id: tool_call.id, content: JSON.stringify({ result }), }; return toolMessage; }); } callGPT(messages_1, tools_1) { return __awaiter(this, arguments, void 0, function* (messages, tools, reflected = false) { try { const gptResponse = yield this.openai.chat.completions.create({ model: this.model, messages, tools: tools, stream: false, }); const { choices: [reply], usage, } = gptResponse; const { message } = reply; if (this.selfReflect && reflected && this.selfReflected >= 3) { (0, logger_1.Logger)({ type: "warn", payload: "Self-Reflection Limit Reached\n\n" }); } if (this.selfReflect && !reflected && message.content && this.selfReflected < 3 && !message.tool_calls) { (0, logger_1.Logger)({ type: "info", payload: `Self-Reflecting On Output (${this.selfReflected})...\n\n`, }); this.selfReflected++; return this.callGPT([ ...messages, message, { role: "user", content: "Reflect on your response, find ways to improve it, respond with only the improved version, with no mention of the reflection process, or changes made.", }, ], tools, true); } return message; } catch (error) { console.error(error); console.debug("History: ", this.history); throw new Error("Failed to call GPT-3"); } }); } callGPTStream(messages, callback, tools) { return __awaiter(this, void 0, void 0, function* () { const gptResponse = yield this.openai.chat.completions.create({ model: this.model, messages, tools: tools, stream: true, }); const _this = this; const toolCalls = []; const toolMessages = []; const stream = new ReadableStream({ start(controller) { return __awaiter(this, void 0, void 0, function* () { var _a, e_1, _b, _c, _d, e_2, _e, _f; var _g, _h, _j, _k, _l, _m, _o; let currentMessage = ""; try { for (var _p = true, gptResponse_1 = __asyncValues(gptResponse), gptResponse_1_1; gptResponse_1_1 = yield gptResponse_1.next(), _a = gptResponse_1_1.done, !_a; _p = true) { _c = gptResponse_1_1.value; _p = false; const value = _c; const choice = value.choices[0]; const delta = choice.delta; if (delta.tool_calls != null) { for (const toolCallDelta of delta.tool_calls) { const index = toolCallDelta.index; if (toolCalls[index] == null) { if (toolCallDelta.type !== "function") { continue; } if (toolCallDelta.id == null) { continue; } if (((_g = toolCallDelta.function) === null || _g === void 0 ? void 0 : _g.name) == null) { continue; } if (toolCallDelta.function && toolCallDelta.id && toolCallDelta.function.name) { toolCalls[index] = { id: toolCallDelta.id, type: "function", function: { name: toolCallDelta.function.name, arguments: (_h = toolCallDelta.function.arguments) !== null && _h !== void 0 ? _h : "", }, }; } continue; } const toolCall = toolCalls[index]; if (((_j = toolCallDelta.function) === null || _j === void 0 ? void 0 : _j.arguments) != null) { toolCall.function.arguments += (_l = (_k = toolCallDelta.function) === null || _k === void 0 ? void 0 : _k.arguments) !== null && _l !== void 0 ? _l : ""; } // check if tool call is complete if (((_m = toolCall.function) === null || _m === void 0 ? void 0 : _m.name) == null || ((_o = toolCall.function) === null || _o === void 0 ? void 0 : _o.arguments) == null || !isParseableJson(toolCall.function.arguments)) { continue; } (0, logger_1.Logger)({ type: "function", payload: JSON.stringify({ name: toolCall.function.name, params: toolCall.function.arguments, }), }); const toolMessage = yield _this.processingToolCall(toolCall); const toolRequestMessage = { role: "assistant", content: null, tool_calls: [toolCall], }; toolMessages.push(toolRequestMessage, toolMessage); continue; } } else if (delta.content != null) { controller.enqueue(value.choices[0].delta.content); currentMessage += value.choices[0].delta.content; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (!_p && !_a && (_b = gptResponse_1.return)) yield _b.call(gptResponse_1); } finally { if (e_1) throw e_1.error; } } if (currentMessage && !toolMessages.length) { _this.history.push({ role: "assistant", content: currentMessage, }); callback(currentMessage); } if (toolMessages.length) { _this.history.push(...toolMessages); const newStream = yield _this.callGPTStream(_this.history, callback, tools); try { for (var _q = true, newStream_1 = __asyncValues(newStream), newStream_1_1; newStream_1_1 = yield newStream_1.next(), _d = newStream_1_1.done, !_d; _q = true) { _f = newStream_1_1.value; _q = false; const newPart = _f; controller.enqueue(newPart); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (!_q && !_d && (_e = newStream_1.return)) yield _e.call(newStream_1); } finally { if (e_2) throw e_2.error; } } } controller.close(); }); }, }); return (0, utils_1.readableStreamAsyncIterable)(stream); }); } } exports.Model = Model; //# sourceMappingURL=openai.js.map