aiwrapper
Version:
A Universal AI Wrapper for JavaScript & TypeScript
111 lines • 3.88 kB
JavaScript
import { buildPromptForGettingJSON } from "./prompt-for-json.js";
import extractJSON from "./json/extract-json.js";
/**
* LanguageProvider is an abstract class that represents a language model and
* its basic functionality.
*/
export class LanguageProvider {
constructor(name) {
this.name = name;
}
async askForObject(promptObj, onResult) {
let trialsLeft = 3;
const trials = trialsLeft;
const prompt = buildPromptForGettingJSON(promptObj);
const result = new LangResultWithObject(prompt);
while (trialsLeft > 0) {
trialsLeft--;
const res = await this.ask(prompt, (r) => {
result.answer = r.answer;
result.finished = r.finished;
onResult === null || onResult === void 0 ? void 0 : onResult(result);
});
const jsonObj = extractJSON(res.answer);
if (jsonObj !== null) {
result.answerObj = jsonObj;
}
if (result.answerObj === null && trialsLeft <= 0) {
throw new Error(`Failed to parse JSON after ${trials} trials`);
}
else if (result.answerObj === null) {
console.log(`Failed to parse JSON, trying again...`);
continue;
}
// @TODO: make sure examples themselves have consistent schemas
const firstExample = promptObj.objectExamples[0];
const shemasAreMatching = schemasAreMatching(firstExample, result.answerObj);
if (!shemasAreMatching && trialsLeft <= 0) {
throw new Error(`The parsed JSON doesn't match the schema after ${trials} trials`);
}
else if (!shemasAreMatching) {
console.log(`The parsed JSON doesn't match the schema, trying again...`);
continue;
}
break;
}
result.finished = true;
// Calling it one more time after parsing JSON to return a valid JSON string
onResult === null || onResult === void 0 ? void 0 : onResult(result);
return result;
}
}
function schemasAreMatching(example, target) {
// If both are arrays
if (Array.isArray(example) && Array.isArray(target)) {
return true;
}
// If both are objects
if (typeof example === 'object' && typeof target === 'object') {
const exampleKeys = Object.keys(example);
const targetKeys = Object.keys(target);
return exampleKeys.length === targetKeys.length && exampleKeys.every(key => targetKeys.includes(key));
}
// If example and target are neither arrays nor objects, they don't match the schema
return false;
}
export class LangResultWithString {
constructor(prompt) {
this.finished = false;
this.prompt = prompt;
this.answer = "";
this.finished;
}
toString() {
return this.answer;
}
abort() {
throw new Error("Not implemented yet");
}
}
export class LangResultWithObject {
constructor(prompt) {
this.answerObj = {};
this.answer = "";
this.finished = false;
this.prompt = prompt;
this.finished;
}
toString() {
if (Object.keys(this.answerObj).length === 0) {
return this.answer;
}
return JSON.stringify(this.answerObj);
}
}
export class LangResultWithMessages {
constructor(messages) {
this.messages = [];
this.finished = false;
// The prompt is the latest message
this.prompt = messages.length > 0 ? messages[messages.length - 1].content : "";
this.answer = "";
this.finished;
}
toString() {
return this.answer;
}
abort() {
throw new Error("Not implemented yet");
}
}
//# sourceMappingURL=language-provider.js.map