pomljs
Version:
Prompt Orchestration Markup Language
241 lines (235 loc) • 8.18 kB
JavaScript
var React = require('react');
var fs = require('./util/fs.cjs');
var path = require('path');
var writer = require('./writer.cjs');
var base = require('./base.cjs');
var file = require('./file.cjs');
require('./presentation.cjs');
require('./essentials.cjs');
require('./components/table.cjs');
require('./components/instructions.cjs');
require('./components/utils.cjs');
require('./components/document.cjs');
require('./components/message.cjs');
require('./components/tree.cjs');
require('./components/webpage.cjs');
var reactRender = require('./util/reactRender.cjs');
var trace = require('./util/trace.cjs');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const read = async (element, options, context, stylesheet, sourcePath) => {
let readElement;
if (typeof element === 'string') {
readElement = new file.PomlFile(element, options, sourcePath).react(context);
}
else {
if (options || context) {
console.warn('Options and context are ignored when element is React.ReactElement');
}
readElement = element;
}
if (stylesheet) {
readElement = React__namespace.createElement(base.StyleSheetProvider, { stylesheet }, readElement);
}
return await reactRender.reactRender(readElement);
};
// Read and also returning the POML file
// A hacky way to get the POML file from the React element
// Do not use it in production code
const _readWithFile = async (element, options, context, stylesheet, sourcePath) => {
let readElement;
let pomlFile;
if (typeof element === 'string') {
pomlFile = new file.PomlFile(element, options, sourcePath);
readElement = pomlFile.react(context);
}
else {
if (options || context) {
console.warn('Options and context are ignored when element is React.ReactElement');
}
readElement = element;
}
if (stylesheet) {
readElement = React__namespace.createElement(base.StyleSheetProvider, { stylesheet }, readElement);
}
return [
await reactRender.reactRender(readElement),
pomlFile
];
};
/**
* Entry point for turning a parsed IR string into rich content or a list of
* speaker messages. The heavy lifting is done by `EnvironmentDispatcher`.
*/
function write(ir, options) {
const writer$1 = new writer.EnvironmentDispatcher();
if (options?.speaker) {
return writer$1.writeMessages(ir);
}
else {
return writer$1.write(ir);
}
}
/**
* Variant of {@link write} that also exposes a source map describing the
* mapping between input indices and output content.
*/
function writeWithSourceMap(ir, options) {
const writer$1 = new writer.EnvironmentDispatcher();
if (options?.speaker) {
return writer$1.writeMessagesWithSourceMap(ir);
}
else {
return writer$1.writeWithSourceMap(ir);
}
}
const poml = async (element) => {
base.ErrorCollection.clear();
const readResult = await read(element);
const result = write(readResult);
if (!base.ErrorCollection.empty()) {
throw base.ErrorCollection.first();
}
return result;
};
async function commandLine(args) {
const readOptions = {
trim: args.trim,
};
if (args.traceDir) {
trace.setTrace(true, args.traceDir);
}
// Determine the working directory
let workingDirectory;
if (args.cwd) {
workingDirectory = path.resolve(args.cwd);
}
else {
workingDirectory = process.cwd();
}
let input;
let sourcePath;
if (args.input && args.file) {
throw new Error('Cannot specify both input and file');
}
else if (args.input) {
input = args.input;
}
else if (args.file) {
const filePath = path.resolve(workingDirectory, args.file);
input = fs.readFileSync(filePath, { encoding: 'utf8' });
sourcePath = filePath;
}
else {
throw new Error('Must specify either input or file');
}
let context = {};
if (args.context) {
for (const pair of args.context) {
if (!pair.includes('=')) {
throw new Error(`Invalid context variable, must include one '=': ${pair}`);
}
const [key, value] = pair.split('=', 2);
context[key] = value;
}
}
else if (args.contextFile) {
const contextFilePath = path.resolve(workingDirectory, args.contextFile);
const contextFromFile = trace.parseJsonWithBuffers(fs.readFileSync(contextFilePath, { encoding: 'utf8' }));
context = { ...context, ...contextFromFile };
}
let stylesheet = {};
if (args.stylesheetFile) {
const stylesheetFilePath = path.resolve(workingDirectory, args.stylesheetFile);
stylesheet = { ...stylesheet, ...trace.parseJsonWithBuffers(fs.readFileSync(stylesheetFilePath, { encoding: 'utf8' })) };
}
if (args.stylesheet) {
stylesheet = { ...stylesheet, ...JSON.parse(args.stylesheet) };
}
base.ErrorCollection.clear();
const pomlFile = new file.PomlFile(input, readOptions, sourcePath);
let reactElement = pomlFile.react(context);
reactElement = React__namespace.createElement(base.StyleSheetProvider, { stylesheet }, reactElement);
const ir = await read(input, readOptions, context, stylesheet, sourcePath);
const speakerMode = args.speakerMode === true || args.speakerMode === undefined;
const prettyPrint = args.prettyPrint === true;
let resultMessages = write(ir, { speaker: speakerMode });
const prettyOutput = speakerMode
? resultMessages.map((message) => `===== ${message.speaker} =====\n\n${renderContent(message.content)}`).join('\n\n')
: renderContent(resultMessages);
const result = {
messages: resultMessages,
schema: pomlFile.getResponseSchema()?.toOpenAPI(),
tools: pomlFile.getToolsSchema()?.toOpenAI(),
runtime: pomlFile.getRuntimeParameters(),
};
const output = prettyPrint ? prettyOutput : JSON.stringify(result);
if (trace.isTracing()) {
try {
trace.dumpTrace(input, context, stylesheet, result, sourcePath, prettyOutput);
}
catch (err) {
base.ErrorCollection.add(new base.SystemError('Failed to dump trace', { cause: err }));
}
}
if (args.strict === true || args.strict === undefined) {
if (!base.ErrorCollection.empty()) {
throw base.ErrorCollection.first();
}
}
if (args.output) {
const outputPath = path.resolve(workingDirectory, args.output);
fs.writeFileSync(outputPath, output);
}
else {
process.stdout.write(output);
}
}
const renderContent = (content) => {
if (typeof content === 'string') {
return content;
}
const outputs = content.map((part) => {
if (typeof part === 'string') {
return part;
}
else {
const media = JSON.stringify(part);
if (media.length > 100) {
return media.slice(0, 100) + '...';
}
else {
return media;
}
}
});
return outputs.join('\n\n');
};
exports.richContentFromSourceMap = base.richContentFromSourceMap;
exports.clearTrace = trace.clearTrace;
exports.dumpTrace = trace.dumpTrace;
exports.parseJsonWithBuffers = trace.parseJsonWithBuffers;
exports.setTrace = trace.setTrace;
exports._readWithFile = _readWithFile;
exports.commandLine = commandLine;
exports.poml = poml;
exports.read = read;
exports.write = write;
exports.writeWithSourceMap = writeWithSourceMap;
//# sourceMappingURL=index.cjs.map
;