mono/packages/media/dist-in/ref/query.js
2025-08-12 09:11:29 +02:00

272 lines
21 KiB
JavaScript

import * as path from 'path';
import * as fs from 'fs';
import { OpenAI, toFile } from "openai";
import { isString } from '@plastichub/core/primitives';
import { sync as write } from '@plastichub/fs/write';
import { sync as read } from '@plastichub/fs/read';
import { sync as exists } from '@plastichub/fs/exists';
import { resolve } from '@plastichub/osr-commons';
import { dumpAsScript, logger, toImages } from '../..';
import { Typescript, Commons, Markdown, Documents, Rust } from './system';
import { Filters } from '../filters';
import { parse } from './options';
import { web_prompt as eprompt } from '../ui/electron';
import { deepmerge as merge } from 'deepmerge-ts';
export const deepMerge = async (target, source) => {
if (!isString(target) || !source) {
logger.error(`Invalid deepmerge parameters:`, target, source);
return source;
}
target = read(target, 'json') || [];
try {
source = isString(source) ? JSON.parse(source) : source;
}
catch (e) {
logger.error('Error parsing completion:', e);
return source;
}
try {
const ret = merge(target, source);
return JSON.stringify(ret, null, 2);
}
catch (error) {
logger.error('Error merging completion:', error);
}
return target;
};
export const mergers = { deepMerge };
export const onCompletion = async (query, ret, opts) => {
if (!isString(ret)) {
logger.warn(`Invalid response :${query}`);
return;
}
const filters = opts.filters.split(',');
opts.filters = [];
filters.forEach((f) => {
if (Filters[f]) {
(opts.filters).push(Filters[f]);
}
});
if (opts.filters) {
opts.filters.forEach((f) => { ret = f(ret); });
}
if (opts.append && mergers[opts.append] && opts.dst) {
ret = await mergers[opts.append](opts.dst, ret);
}
if (opts.dst) {
let header = `${opts.showPrompt ? `// ${opts.query}` : ''}\n`;
let content = `${header}${ret}`;
write(opts.dst, content);
}
else {
process.stdout.write(ret);
}
return ret;
};
export const createOpenAIFile = async (client, filePath, purpose = 'assistants') => {
return client.files.create({
file: fs.createReadStream(filePath),
purpose: purpose
});
};
export const queryEx = async (api_key, options) => {
let ui_opts = null;
let ui_opts_variables = {};
if (options.gui === 'electron') {
const promptsFile = path.resolve(resolve(options.prompts));
const prompts = JSON.stringify(read(promptsFile, 'json') || []);
ui_opts = await eprompt(options.query, options.dst, { ...ui_opts_variables, PROMPTS: prompts, MODELS: [] });
}
options = parse(options);
if (ui_opts) {
if (ui_opts.files && ui_opts.files.length > 0) {
options.files = ui_opts.files;
}
if (ui_opts.textAreaValue !== options.query) {
options.query = ui_opts.textAreaValue;
}
if (ui_opts.target.length && ui_opts.target !== options.dst) {
options.dst = ui_opts.target;
}
}
const client = new OpenAI({ apiKey: api_key });
let messages = [];
let defaults = [...Typescript(), ...Documents()];
if (options.system && exists(options.system)) {
options.debug && logger.debug('Reading system instructions from', options.system);
try {
const system = read(options.system, 'json');
if (system) {
messages = [...system];
}
}
catch (error) {
logger.error('Error reading system instructions', error);
messages = defaults;
}
}
else {
messages = defaults;
}
const attachments = await Promise.all(options.files.map(async (file) => {
const file_id = await createOpenAIFile(client, file);
return {
file_id: file_id.id,
tools: [{ type: "file_search" }]
};
}));
const assistant = await client.beta.assistants.create({
name: "Documents Assistant",
instructions: "You are an expert data analyst.",
model: "gpt-4o",
tools: [{ type: "file_search" }],
});
const thread = await client.beta.threads.create({
messages: [
{
role: "user",
content: options.query,
attachments
}
]
});
return new Promise((resolve, reject) => {
try {
const stream = client.beta.threads.runs
.stream(thread.id, {
assistant_id: assistant.id,
})
.on("textCreated", () => console.log("assistant >"))
.on("toolCallCreated", (event) => console.log("assistant " + event.type))
.on("messageDone", async (event) => {
if (event.content[0].type === "text") {
const { text } = event.content[0];
const { annotations } = text;
const citations = [];
let index = 0;
/*
for (let annotation of annotations) {
text.value = text.value.replace(annotation.text, "[" + index + "]");
const { file_citation } = annotation;
if (file_citation) {
const citedFile = await openai.files.retrieve(file_citation.file_id);
citations.push("[" + index + "]" + citedFile.filename);
}
index++;
}*/
logger.debug('OpenAI response:', text.value);
resolve(text.value);
}
});
return stream;
}
catch (error) {
reject(error);
}
});
};
export const query = async (query, api_key, dst, options) => {
const client = new OpenAI({ apiKey: api_key });
let messages = [];
let defaults = [...Typescript(), ...Markdown(), ...Commons(), ...Rust()];
if (options.system && exists(options.system)) {
logger.debug('Reading system instructions from', options.system);
try {
const system = read(options.system, 'json');
if (system) {
messages = [...system];
}
}
catch (error) {
logger.error('Error reading system instructions', error);
messages = defaults;
}
}
else {
messages = defaults;
}
const requestMessage = {
role: "user",
content: query
};
messages.push(requestMessage);
if (options.files && options.filesInfo.FILES) {
const images = toImages(options.filesInfo.FILES).map((image) => {
return {
role: "user",
content: [{ ...image }]
};
});
messages = [...messages, ...images];
}
const tools = [
{
type: "function",
function: {
name: "list_files",
description: "List files in a given directory.",
parameters: {
type: "object",
properties: {
order_id: {
type: "string",
description: "The directory to list files in.",
},
},
required: ["dir"],
additionalProperties: false
}
}
}
];
const completion = await client.chat.completions.create({
model: options.model || "gpt-4o",
messages: messages,
//tools: tools as any
});
if (completion.choices.length === 0) {
logger.error('OpenAI response is empty');
return;
}
let ret = completion.choices[0].message.content;
ret = await onCompletion(query, ret, options);
dumpAsScript(options);
return ret;
};
const createBuffer = (path) => {
try {
const buffer = fs.readFileSync(path);
return buffer;
}
catch (error) {
console.error('Error creating buffer:', error);
return null;
}
};
export const transcribe = async (query, api_key, dst, options) => {
const client = new OpenAI({
apiKey: api_key
});
if (!exists(options.source)) {
logger.error('Source file does not exist', options.source);
return;
}
const file = await toFile(createBuffer(options.source), 'audio.mp3', { type: 'audio/mpeg' });
if (!file) {
logger.error('Error converting source to file');
return;
}
const completion = await client.audio.transcriptions.create({
model: 'whisper-1',
file: file,
response_format: options.response_format || "verbose_json",
});
if (!completion) {
logger.error('OpenAI response is empty');
return;
}
const ret = completion;
logger.debug('OpenAI Transcribe response:', ret);
return ret;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVmL3F1ZXJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQzVCLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFBO0FBQ3hCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQ3ZDLE9BQU8sRUFBRSxRQUFRLEVBQVksTUFBTSw2QkFBNkIsQ0FBQTtBQUNoRSxPQUFPLEVBQUUsSUFBSSxJQUFJLEtBQUssRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDbEQsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUV0RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFDakQsT0FBTyxFQUFFLFlBQVksRUFBWSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sT0FBTyxDQUFBO0FBQ2hFLE9BQU8sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBQ3pFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDcEMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUNqQyxPQUFPLEVBQUUsVUFBVSxJQUFJLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBRXRELE9BQU8sRUFBRSxTQUFTLElBQUksS0FBSyxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBR2pELE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBRyxLQUFLLEVBQUUsTUFBYyxFQUFFLE1BQVcsRUFBRSxFQUFFO0lBQzNELElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxD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