directus-extension-ai-sdk-bundle
Version:
A small bundle of Flow Operations which enable interaction with the [OpenAI](https://beta.openai.com/overview) and [Stability](https://stability.ai/) API's.
152 lines (145 loc) • 4.17 kB
JavaScript
import { defineOperationApi } from "@directus/extensions-sdk";
import OpenAI from "openai";
import { openAIField } from "../configuration/fields";
import { getSetting } from "../lib/util";
export default defineOperationApi({
id: "chatgpt-operation",
handler: async (
{
system,
text,
engine = "gpt-3.5-turbo",
api_key,
base_url,
amodel,
temperature = 0.5,
max_tokens = 2048,
top_p = 1,
frequency_penalty = 0,
presence_penalty = 0,
json_mode = false,
stream = false,
thread = false,
},
{ services, database, getSchema },
) => {
const { SettingsService } = services;
const schema = await getSchema();
const settings = new SettingsService({ schema, knex: database });
const apiKey = await getSetting(settings, openAIField.field, api_key);
const openai = new OpenAI({
apiKey,
baseURL: base_url ?? "https://api.openai.com/v1",
});
const messages = [];
let systemp = system ?? "";
if (json_mode) {
systemp += "You are a helpful assistant designed to output JSON.";
}
messages.push({ role: "system", content: systemp });
if (thread) {
messages.push(...thread);
}
if (text) {
messages.push({ role: "user", content: text });
}
let obj = {
model: amodel ?? engine,
messages: [...messages],
stream: stream ?? false,
temperature: temperature ?? 0.6,
max_tokens: max_tokens ?? 2048,
top_p: top_p ?? 1,
frequency_penalty: frequency_penalty ?? 0,
presence_penalty: presence_penalty ?? 0,
n: 1,
};
if (json_mode) {
obj.response_format = {
type: "json_object",
};
delete obj.max_tokens;
//obj.messages[0].content += "You are a helpful assistant designed to output JSON.";
}
const response = await openai.chat.completions.create(obj);
if (stream) {
let message = "";
if (stream) {
let lastMessage = "";
for await (const part of response) {
const ret = part.choices[0]?.delta?.content || "";
if (ret) {
lastMessage = lastMessage + ret;
}
}
//console.log('lastMessage', lastMessage)
if (json_mode) {
message =
typeof lastMessage === "string"
? JSON.parse(lastMessage)
: lastMessage;
} else {
message = lastMessage;
}
}
return { response: message };
}
return { response: response.choices[0].message.content };
},
});
export async function getCompletion(inputText, json = false, stream = false) {
let payload = {
model: openAIModel,
messages: [
{ role: "system", content: "" },
{ role: "user", content: inputText },
],
temperature: 0.6,
//max_tokens: 1024,
top_p: 1,
frequency_penalty: 0,
presence_penalty: 0,
stream: stream ?? false,
n: 1,
};
if (json) {
payload.response_format = { type: "json_object" };
delete payload.max_tokens;
// update the system role with a message:
payload.messages[0].content +=
"You are a helpful assistant designed to output JSON.";
}
try {
const response = await client.chat.completions.create(payload);
let message = "";
if (stream) {
let lastMessage = "";
for await (const part of response) {
const ret = part.choices[0]?.delta?.content || "";
if (ret) {
lastMessage = lastMessage + ret;
}
}
//console.log('lastMessage', lastMessage)
if (json) {
message =
typeof lastMessage === "string"
? JSON.parse(lastMessage)
: lastMessage;
} else {
message = lastMessage;
}
} else {
if (json) {
const ret = response.choices[0].message?.content;
message = typeof ret === "string" ? JSON.parse(ret) : ret;
} else {
message = response.choices[0].message?.content ?? "";
}
}
return message;
} catch (err) {
console.error("failed to generate completions from OpenAI", err);
throw err;
}
}