chatgpt-dto
Version:
A lightweight wrapper for OpenAI's GPT API with DTO support via class-validator and class-transformer. Designed for structured JSON output in TypeScript backends.
121 lines • 4.4 kB
JavaScript
import { validationMetadatasToSchemas } from "class-validator-jsonschema";
import OpenAI from "openai";
import { plainToInstance } from "class-transformer";
function expandSchema(schema, definitions) {
if (!schema)
return schema;
if (schema.$ref) {
const refName = schema.$ref.replace("#/components/schemas/", "");
return expandSchema(definitions[refName], definitions);
}
if (schema.type === "array" && schema.items) {
schema.items = expandSchema(schema.items, definitions);
}
if (schema.properties) {
Object.keys(schema.properties).forEach((key) => {
schema.properties[key] = expandSchema(schema.properties[key], definitions);
});
}
return schema;
}
export class GPTProvider {
openai;
config;
constructor(config) {
if (!config.apiKey) {
throw new Error("❌ OpenAI API key is required.");
}
this.config = config;
this.openai = new OpenAI({ apiKey: config.apiKey });
}
async jsonDTO(prompt, dtoClass, model) {
const schemas = validationMetadatasToSchemas();
const jsonSchema = schemas[dtoClass.name];
if (!jsonSchema) {
console.error(`❌ Failed to generate JSON Schema for ${dtoClass.name}`);
return null;
}
const expandedSchema = expandSchema(jsonSchema, schemas);
try {
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const response = await openai.chat.completions.create({
model: model || this.config.model,
messages: [{ role: "user", content: prompt }],
response_format: {
type: "json_schema", json_schema: {
name: dtoClass.name,
schema: expandedSchema,
}
},
});
try {
const usage = response.usage;
const message = response.choices[0]?.message;
const rawData = JSON.parse(message?.content || "{}");
return {
message: message,
usage,
result: plainToInstance(dtoClass, rawData),
};
}
catch (e) {
}
}
catch (error) {
console.error("❌ GPT JSON Parsing Error:", error);
return null;
}
}
async chat(prompt, model) {
if (!this.openai) {
console.error("❌ OpenAI is not initialized. Please call init() first.");
return null;
}
try {
const response = await this.openai.chat.completions.create({
model: model || this.config.model,
messages: [{ role: "user", content: prompt }],
});
const message = response.choices[0]?.message;
return {
message: message,
usage: response.usage,
result: message?.content,
};
}
catch (error) {
console.error("❌ GPT Chat Error:", error);
return null;
}
}
async chatString(prompt, model) {
if (!this.openai) {
console.error("❌ OpenAI is not initialized. Please call init() first.");
return;
}
const response = await this.openai.chat.completions.create({
model: model || this.config.model,
messages: [{ role: "user", content: prompt }],
});
return response.choices[0]?.message?.content || "";
}
async JsonString(prompt, jsonSchema, model) {
if (!this.openai) {
console.error("❌ OpenAI is not initialized. Please call init() first.");
return null;
}
try {
const response = await this.openai.chat.completions.create({
model: model || this.config.model,
messages: [{ role: "user", content: prompt }],
response_format: { type: "json_schema", json_schema: jsonSchema },
});
return JSON.parse(response.choices[0]?.message?.content || "{}");
}
catch (error) {
console.error("❌ GPT JSON Parsing Error:", error);
return null;
}
}
}
//# sourceMappingURL=provider.js.map