UNPKG

pomljs

Version:

Prompt Orchestration Markup Language

241 lines (235 loc) 8.18 kB
'use strict'; 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