181 lines
16 KiB
JavaScript
181 lines
16 KiB
JavaScript
import * as path from 'path';
|
|
import { sync as read } from '@plastichub/fs/read';
|
|
import { sync as write } from '@plastichub/fs/write';
|
|
import { sync as exists } from '@plastichub/fs/exists';
|
|
import { CONFIG_DEFAULT } from '@plastichub/osr-commons';
|
|
import { resolve as resolvePath } from '@plastichub/osr-commons';
|
|
import { logger } from '../';
|
|
import { defaults } from '../_cli';
|
|
import { Filters } from '../lib/filters';
|
|
import { readPipedInput } from '../lib/args';
|
|
import { queryEx, transcribe } from '../lib/openai';
|
|
import { isString } from '@plastichub/core/primitives';
|
|
const defaultOptions = (yargs) => {
|
|
yargs.parserConfiguration({
|
|
"camel-case-expansion": false
|
|
});
|
|
return yargs.option('debug', {
|
|
default: false,
|
|
describe: 'debug messages',
|
|
type: 'boolean'
|
|
}).option('append', {
|
|
default: false,
|
|
describe: 'append to file instead of overwriting',
|
|
type: 'boolean'
|
|
}).option('showPrompt', {
|
|
default: false,
|
|
describe: 'insert prompt in output',
|
|
type: 'boolean'
|
|
}).option('cache', {
|
|
default: true,
|
|
describe: 'Enable cache',
|
|
type: 'boolean'
|
|
}).option('alt', {
|
|
default: false,
|
|
describe: 'Use alternative path variable token separator',
|
|
type: 'boolean'
|
|
}).option('query', {
|
|
description: 'query',
|
|
default: "list all towns of barcelona, as typescript enum, with gps coords, as strings"
|
|
}).option('dst', {
|
|
description: 'Destination output path',
|
|
_default: './tests/chatgpt/last.ts'
|
|
}).option('env_key', {
|
|
default: 'OSR-CONFIG',
|
|
describe: 'Environment key to the config path'
|
|
}).option('api_key', {
|
|
describe: 'OpenAI key'
|
|
}).option('model', {
|
|
describe: 'OpenAI Model',
|
|
default: "gpt-4o"
|
|
}).option('system', {
|
|
describe: 'Path to system instructions'
|
|
}).option('source', {
|
|
describe: 'Path to a source file'
|
|
}).option('response_format', {
|
|
describe: 'Format of the response (for transcribe)',
|
|
default: "text"
|
|
}).option('filters', {
|
|
describe: `An array of filters to apply to the response: JSON : ${Object.keys(Filters)} `,
|
|
default: ""
|
|
}).option('files', {
|
|
describe: `List of files to attach to the query: String|Glob`
|
|
}).option('logLevel', {
|
|
describe: `Log level: warn|info|trace|debug|error|fatal`,
|
|
default: 'info'
|
|
}).option('gui', {
|
|
describe: `GUI: electron|puppeteer`,
|
|
default: false
|
|
}).option('prompts', {
|
|
describe: `Path to prompts file, JSON - Array`,
|
|
default: '${OSR_ROOT}/osr-ai-templates/prompts/documents.json',
|
|
type: 'string'
|
|
});
|
|
};
|
|
let options = (yargs) => defaultOptions(yargs);
|
|
export const register = (cli) => {
|
|
return cli.command('chatgpt-ex <verb>', 'Prompt ChatGPT - Ex', options, async (argv) => {
|
|
defaults();
|
|
if (argv.help) {
|
|
return;
|
|
}
|
|
const args = argv;
|
|
const verb = args.verb || 'prompt';
|
|
const config = CONFIG_DEFAULT(args.env_key);
|
|
if (!config) {
|
|
logger.warn('No config found!');
|
|
return;
|
|
}
|
|
if (config && !config.openai.key) {
|
|
logger.warn('No OpenAI key found in config!');
|
|
return;
|
|
}
|
|
const variables = Object.assign({}, ...Object.keys(argv).filter((k) => k.startsWith('var-')).map((k) => {
|
|
return {
|
|
[k.replace('var-', '')]: argv[k]
|
|
};
|
|
}));
|
|
const opts = {
|
|
query: argv.query,
|
|
...argv,
|
|
dst: args.dst,
|
|
source: argv.source ? path.resolve(resolvePath(args.source)) : undefined,
|
|
system: argv.system ? path.resolve(resolvePath(args.system)) : undefined,
|
|
api_key: argv.openai_key || process.env.OPENAI_API_KEY || config.openai.key,
|
|
variables
|
|
};
|
|
logger.debug('Options', opts);
|
|
const filters = (opts.filters || "").split(',');
|
|
opts.filters = [];
|
|
filters.forEach((f) => {
|
|
if (Filters[f]) {
|
|
(opts.filters).push(Filters[f]);
|
|
}
|
|
});
|
|
if (opts.cache === true && exists(opts.dst)) {
|
|
logger.debug('Output file already exists, skipping');
|
|
return;
|
|
}
|
|
if (!opts.api_key) {
|
|
logger.error('No OpenAI key found in config or options!');
|
|
return;
|
|
}
|
|
if (!opts.query) {
|
|
logger.error('No query specified');
|
|
return;
|
|
}
|
|
logger.debug('Options', opts);
|
|
return new Promise(async (resolve, reject) => {
|
|
switch (verb) {
|
|
case 'prompt': {
|
|
if (opts.source && !exists(opts.source)) {
|
|
logger.error('Source specified but file not found', opts.source);
|
|
return;
|
|
}
|
|
const src = opts.source && exists(opts.source) ? read(opts.source, 'string') : '';
|
|
const stdin = await readPipedInput() || src || '';
|
|
let q = stdin ? `${opts.query} : "${stdin}"` : opts.query;
|
|
const queryPath = path.resolve(resolvePath(opts.query));
|
|
if (exists(queryPath)) {
|
|
q = read(queryPath);
|
|
}
|
|
opts.query = `${opts.query} : ${src}`;
|
|
let ret = await queryEx(opts.api_key, opts);
|
|
if (opts.filters) {
|
|
opts.filters.forEach((f) => {
|
|
let _ret = f(ret);
|
|
if (isString(_ret) && _ret.length > 0) {
|
|
ret = _ret;
|
|
}
|
|
});
|
|
}
|
|
if (opts.dst) {
|
|
let header = `${argv.showPrompt ? `// ${q}` : ''}\n`;
|
|
let content = `${argv.append ? read(opts.dst) || '' : ''}\n${header}${ret}`;
|
|
write(opts.dst, content);
|
|
}
|
|
if (isString(ret) || Buffer.isBuffer(ret)) {
|
|
process.stdout.write(ret);
|
|
}
|
|
else {
|
|
logger.warn('Invalid response: not a string or buffer');
|
|
}
|
|
break;
|
|
}
|
|
case 'transcribe': {
|
|
const ret = await transcribe(opts.query, opts.api_key, opts.dst, {
|
|
...opts
|
|
});
|
|
if (ret && opts.dst) {
|
|
write(opts.dst, ret);
|
|
}
|
|
process.stdout.write(ret);
|
|
break;
|
|
}
|
|
}
|
|
resolve();
|
|
process.exit(0);
|
|
});
|
|
});
|
|
};
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdGdwdC1leC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWYvY2hhdGdwdC1leC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUU1QixPQUFPLEVBQUUsSUFBSSxJQUFJLElBQUksRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQ2xELE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFDcEQsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUN0RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFDeEQsT0FBTyxFQUFFLE9BQU8sSUFBSSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQTtBQUVoRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBQzVCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxTQUFTLENBQUE7QUFDbEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQ3hDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFFNUMsT0FBTyxFQUFvQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ3JFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQTtBQUV0RCxNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQWUsRUFBRSxFQUFFO0lBQ3ZDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQztRQUN0QixzQkFBc0IsRUFBRSxLQUFLO0tBQ2hDLENBQUMsQ0FBQTtJQUNGLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDekIsT0FBTyxFQUFFLEtBQUs7UUFDZCxRQUFRLEVBQUUsZ0JBQWdCO1FBQzFCLElBQUksRUFBRSxTQUFTO0tBQ2xCLENBQUMsQ0FBQyxNQUFN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
|