Spaces:
Running
Running
File size: 5,685 Bytes
b39afbe |
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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
/**
* Copyright (c) 2023 MERCENARIES.AI PTE. LTD.
* All rights reserved.
*/
//@ts-check
import { runBlock } from './blocks.js';
import { Llm, fixJsonString, generateModelId, deduceLlmTitle, deduceLlmDescription } from './llm.js';
import { is_valid, clean_string } from './utils.js';
import { Tokenizer_Openai } from './tokenizer_Openai.js';
const LLM_PROVIDER_OPENAI_SERVER = 'openai'; // we may need to support Azure and other providers (e.g. Poe)
const LLM_MODEL_TYPE_OPENAI = 'openai';
const BLOCK_OPENAI_ADVANCED_CHATGPT = 'openai.advancedChatGPT';
const LLM_CONTEXT_SIZE_MARGIN = 500;
const GPT3_MODEL_SMALL = 'gpt-3.5-turbo';
const GPT3_MODEL_LARGE = 'gpt-3.5-turbo-16k';
const GPT4_MODEL_SMALL = 'gpt-4';
const GPT4_MODEL_LARGE = 'gpt-4-32k';
const GPT3_MODEL_PREVIEW = 'gpt-3.5-turbo-1106';
const GPT4_MODEL_PREVIEW= 'gpt-4-1106-preview';
const GPT4_SIZE_CUTOFF = 8192 - LLM_CONTEXT_SIZE_MARGIN;
const ICON_OPENAI = '💰';
const llm_openai_models = [
{
model_name: GPT3_MODEL_SMALL,
model_type: LLM_MODEL_TYPE_OPENAI,
context_size: 4096,
provider: LLM_PROVIDER_OPENAI_SERVER
},
{
model_name: GPT3_MODEL_LARGE,
model_type: LLM_MODEL_TYPE_OPENAI,
context_size: 16385,
provider: LLM_PROVIDER_OPENAI_SERVER
},
{
model_name: GPT4_MODEL_SMALL,
model_type: LLM_MODEL_TYPE_OPENAI,
context_size: 8192,
provider: LLM_PROVIDER_OPENAI_SERVER
},
{
model_name: GPT4_MODEL_LARGE,
model_type: LLM_MODEL_TYPE_OPENAI,
context_size: 32768,
provider: LLM_PROVIDER_OPENAI_SERVER
},
{
model_name: GPT3_MODEL_PREVIEW,
model_type: LLM_MODEL_TYPE_OPENAI,
context_size: 16385,
provider: LLM_PROVIDER_OPENAI_SERVER
},
{
model_name: GPT4_MODEL_PREVIEW,
model_type: LLM_MODEL_TYPE_OPENAI,
context_size: 128000,
provider: LLM_PROVIDER_OPENAI_SERVER
}
];
class Llm_Openai extends Llm {
constructor() {
const tokenizer_Openai = new Tokenizer_Openai();
super(tokenizer_Openai);
// @ts-ignore
this.context_sizes[GPT3_MODEL_SMALL] = 4096;
// @ts-ignore
this.context_sizes[GPT3_MODEL_LARGE] = 16385;
// @ts-ignore
this.context_sizes[GPT4_MODEL_SMALL] = 8192;
// @ts-ignore
this.context_sizes[GPT4_MODEL_LARGE] = 32768;
// @ts-ignore
this.context_sizes[GPT3_MODEL_PREVIEW] = 16385;
// @ts-ignore
this.context_sizes[GPT4_MODEL_PREVIEW] = 128000;
}
// -----------------------------------------------------------------------
/**
* @param {any} ctx
* @param {string} prompt
* @param {string} instruction
* @param {string} model_name
* @param {number} [temperature=0]
* @param {any} [args=null]
* @returns {Promise<{ answer_text: string; answer_json: any; }>}
*/
async query(ctx, prompt, instruction, model_name, temperature = 0, args = null) {
const block_args = { ...args };
block_args.user = ctx.userId;
if (prompt !== '') block_args.prompt = prompt;
if (instruction !== '') block_args.instruction = instruction;
block_args.temperature = temperature;
block_args.model = model_name;
const response = await this.runLlmBlock(ctx, block_args);
if (response.error) throw new Error(response.error);
const total_tokens = response?.usage?.total_tokens || 0;
let answer_text = response?.answer_text || '';
const function_arguments_string = response?.function_arguments_string || '';
let function_arguments = null;
if (is_valid(function_arguments_string)) function_arguments = await fixJsonString(ctx, function_arguments_string);
if (is_valid(answer_text)) answer_text = clean_string(answer_text);
const answer_json = {};
answer_json.function_arguments_string = function_arguments_string;
answer_json.function_arguments = function_arguments;
answer_json.total_tokens = total_tokens;
answer_json.answer_text = answer_text;
const return_value = {
answer_text,
answer_json
};
return return_value;
}
getProvider() {
return LLM_PROVIDER_OPENAI_SERVER;
}
getModelType() {
return LLM_MODEL_TYPE_OPENAI;
}
// @ts-ignore
async getModelChoices(choices, llm_model_types, llm_context_sizes) {
const models = Object.values(llm_openai_models);
for (const model of models) {
const model_name = model.model_name;
const provider = model.provider;
const model_id = generateModelId(model_name, provider);
// @ts-ignore
const title = model.title || deduceLlmTitle(model_name, provider, ICON_OPENAI);
// @ts-ignore
const description = model.description || deduceLlmDescription(model_name, model.context_size);
// @ts-ignore
llm_model_types[model_name] = model.type;
llm_context_sizes[model_name] = model.context_size;
const choice = { value: model_id, title, description };
choices.push(choice);
}
}
// @ts-ignore
async runLlmBlock(ctx, args) {
// TBD ensure all the runLLM blocks have the same exact response format
// or clean it up here for openai
const prompt = args.prompt;
const instruction = args.instruction;
const model = args.model;
const prompt_cost = this.tokenizer.countTextTokens(prompt);
const instruction_cost = this.tokenizer.countTextTokens(instruction);
const cost = prompt_cost + instruction_cost;
let response = null;
try {
response = await runBlock(ctx, BLOCK_OPENAI_ADVANCED_CHATGPT, args);
} catch (err) {
// @ts-ignore
const error_message = `Error running openai.advancedChatGPT: ${err.message}`;
console.error(error_message);
throw err;
}
return response;
}
}
export { Llm_Openai };
|