UNPKG

aiwrapper

Version:

A Universal AI Wrapper for JavaScript & TypeScript

111 lines 3.88 kB
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