auto-gpt-ts
Version:
my take of Auto-GPT in typescript
217 lines (216 loc) • 10.3 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createEmbedding = exports.getAdaEmbedding = exports.createChatCompletion = exports.callAiFunction = exports.RetryOpenaiApi = void 0;
const logging_1 = require("../logging");
const openai_1 = require("openai");
const api_manages_1 = require("./api-manages");
const config_1 = require("../config/config");
const configuration = new openai_1.Configuration({
apiKey: new config_1.Config().openaiApiKey,
});
const openai = new openai_1.OpenAIApi(configuration);
const logger = (0, logging_1.getLogger)("llm-utils");
function RetryOpenaiApi(numRetries = 10, backoffBase = 2.0, warnUser = true) {
const retryLimitMsg = `Error: Reached rate limit, passing...`;
const apiKeyErrorMsg = `Please double check that you have setup a PAID OpenAI API Account. You can read more here: https://significant-gravitas.github.io/Auto-GPT/setup/#getting-an-api-key`;
const backoffMsg = `Error: API Bad gateway. Waiting {backoff} seconds...`;
return (target, propertyKey) => {
const originalMethod = target[propertyKey].bind(target);
const replacedFunction = function (...args) {
return __awaiter(this, void 0, void 0, function* () {
let userWarned = !warnUser;
for (let attempt = 1; attempt <= numRetries + 1; attempt++) {
try {
return yield originalMethod.apply(target, args);
}
catch (error) {
if (error.httpStatus) {
if (attempt === numRetries + 1) {
throw error;
}
logger.debug(retryLimitMsg);
if (!userWarned) {
logger.error(apiKeyErrorMsg);
userWarned = true;
}
}
else if (error.httpStatus === 502) {
if (attempt === numRetries + 1) {
throw error;
}
const backoff = Math.pow(backoffBase, (attempt + 2));
logger.debug(backoffMsg.replace("{backoff}", `${backoff}`));
yield new Promise((resolve) => setTimeout(resolve, backoff * 1000));
throw error;
}
else {
throw error;
}
}
}
Object.defineProperty(target, propertyKey, {
value: replacedFunction,
});
});
};
};
}
exports.RetryOpenaiApi = RetryOpenaiApi;
function callAiFunction(fnName, args, description, model = "") {
return __awaiter(this, void 0, void 0, function* () {
const cfg = new config_1.Config();
if (!model) {
model = cfg.smartLlmModel;
}
// For each arg, if any are null, convert to "null":
const parsedArgs = args.map((arg) => (arg !== null ? String(arg) : "null"));
// Parse args to comma-separated string
const argsStr = parsedArgs.join(", ");
const messages = [
{
role: "system",
content: `You are now the following Python function: \`\`\`# ${description}\n${fnName}\`\`\`\n\nOnly respond with your \`return\` value.`,
},
{
role: "user",
content: argsStr,
},
];
return (yield openai.createChatCompletion({
model,
messages,
temperature: 0,
})).data.choices[0].message.content;
});
}
exports.callAiFunction = callAiFunction;
/**
Create a chat completion using the OpenAI API
@param {Message[]} messages - The messages to send to the chat completion.
@param {string} [model] - The model to use. Defaults to null.
@param {number} [temperature] - The temperature to use. Defaults to 0.9.
@param {number} [maxTokens] - The max tokens to use. Defaults to null.
@returns {string} - The response from the chat completion.
*/
function createChatCompletion(messages, model = "", temperature, maxTokens) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
const cfg = new config_1.Config();
if (!temperature) {
temperature = cfg.temperature;
}
const num_retries = 10;
let warned_user = false;
logger.debug(`Creating chat completion with model ${model}, temperature ${temperature}, max_tokens ${maxTokens}`);
const api_manager = new api_manages_1.ApiManager();
let response = undefined;
for (let attempt = 0; attempt < num_retries; attempt++) {
const backoff = Math.pow(2, (attempt + 2));
try {
response = yield api_manager.createChatCompletion({
model,
messages,
temperature,
max_tokens: maxTokens,
});
break;
}
catch (error) {
logger.debug(`Error: createChatCompletion returned: `, { error, messages });
if (/400/.test(error.message)) {
// TODO: find rate limit error status code
if (!warned_user) {
logger.warn(`Please double check that you have setup a PAID OpenAI API Account. You can read more here: https://significant-gravitas.github.io/Auto-GPT/setup/#getting-an-api-key`);
warned_user = true;
}
}
else {
if (/429/.test(error.message) || /ENOTFOUND/.test(error.message)) {
logger.debug(`Retrying after ${backoff} seconds...`);
yield new Promise((res) => setTimeout(res, backoff));
}
else if (attempt === num_retries - 1) {
return `Error: couldn't not get response from API.`;
}
else {
throw `Error: couldn't not get response from API.`;
}
}
logger.debug(`Error: API Bad gateway. Waiting ${backoff} seconds...`);
yield new Promise((res) => setTimeout(res, backoff));
}
}
if (!response) {
logger.info("FAILED TO GET RESPONSE FROM OPENAI Auto-GPT has failed to get a response from OpenAI's services. Try running Auto-GPT again, and if the problem the persists try running it with --debug.");
if (cfg.debugMode) {
throw new Error(`Failed to get response after ${num_retries} retries`);
}
else {
process.exit(1);
}
}
let resp = (_b = (_a = response === null || response === void 0 ? void 0 : response.choices[0]) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b["content"];
return resp;
});
}
exports.createChatCompletion = createChatCompletion;
/**
* Get an embedding from the ada model.
*
* @param {string} text - The text to embed.
* @returns {number[]} - The embedding.
*/
function getAdaEmbedding(text) {
return __awaiter(this, void 0, void 0, function* () {
const model = "text-embedding-ada-002";
const sanitizedText = text.replace("\n", " ");
const kwargs = { model };
const embedding = yield LlmUtils.createEmbedding(sanitizedText, kwargs);
const apiManager = new api_manages_1.ApiManager();
apiManager.updateCost(embedding.usage.prompt_tokens, 0, model);
return embedding.data[0].embedding;
});
}
exports.getAdaEmbedding = getAdaEmbedding;
class LlmUtils {
/** warped in class for decorating
*/
static createEmbedding(text, ..._) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield openai.createEmbedding(Object.assign({ input: [text], model: "text-embedding-ada-002" }, _));
return res.data;
});
}
}
__decorate([
RetryOpenaiApi(),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, Object]),
__metadata("design:returntype", Promise)
], LlmUtils, "createEmbedding", null);
/**
* Creates an embedding using the OpenAI API
* @param {string} text - The text to embed.
* @param {...any} _ - Additional arguments to pass to the OpenAI API embedding creation call.
* @returns {openai.Embedding} - The embedding object.
*/
exports.createEmbedding = LlmUtils.createEmbedding;
//# sourceMappingURL=llm-utils.js.map