UNPKG

pomljs

Version:

Prompt Orchestration Markup Language

113 lines (110 loc) 4.35 kB
import { component } from '../base.js'; import { Text, Image, ToolRequest, ToolResponse } from '../essentials.js'; import * as React from 'react'; import { parsePythonStyleSlice } from './utils.js'; /** * Wrap the contents in a system message. * * @see {@link Text} for other props available. * * @example * ```xml * <system-msg>Answer concisely.</system-msg> * ``` */ component('SystemMessage', ['system-msg'])((props) => { const { children, ...others } = props; return (React.createElement(Text, { speaker: "system", ...others }, children)); }); /** * Wrap the contents in a user message. * * @see {@link Text} for other props available. * * @example * ```xml * <user-msg>What is the capital of France?</user-msg> * ``` */ component('HumanMessage', ['human-msg'])((props) => { const { children, ...others } = props; return (React.createElement(Text, { speaker: "human", ...others }, children)); }); /** * Wrap the contents in a AI message. * * @see {@link Text} for other props available. * * @example * ```xml * <ai-msg>Paris</ai-msg> * ``` */ component('AiMessage', ['ai-msg'])((props) => { const { children, ...others } = props; return (React.createElement(Text, { speaker: "ai", ...others }, children)); }); /** * Display a message content. * * @param {object|string} content - The content of the message. It can be a string, or an array of strings and multimedia content. * * @example * ```xml * <msg-content content="What is the capital of France?" /> * ``` */ const MessageContent = component('MessageContent', ['msg-content'])((props) => { const { children, content, ...others } = props; const displayStringOrMultimedia = (media, key) => { if (typeof media === 'string') { return (React.createElement(Text, { key: key, ...others }, media)); } else if (media.type.startsWith('image/')) { const image = media; return (React.createElement(Image, { key: key, base64: image.base64, alt: image.alt, type: image.type, ...others })); } else if (media.type === 'application/vnd.poml.toolrequest') { const toolRequest = media; return (React.createElement(ToolRequest, { key: key, id: toolRequest.id, name: toolRequest.name, parameters: toolRequest.content, ...others })); } else if (media.type === 'application/vnd.poml.toolresponse') { const toolResponse = media; return (React.createElement(ToolResponse, { key: key, id: toolResponse.id, name: toolResponse.name, ...others }, React.createElement(MessageContent, { content: toolResponse.content, ...others }))); } else { throw new Error(`Unsupported media type: ${media.type}`); } }; if (typeof content === 'string') { return displayStringOrMultimedia(content); } else if (Array.isArray(content)) { return React.createElement(Text, null, content.map((item, index) => displayStringOrMultimedia(item, `content-${index}`))); } }); /** * Display a conversation between system, human and AI. * * @param {object} messages - A list of message. Each message should have a `speaker` and a `content` field. * @param {string} selectedMessages - The messages to be selected. If not provided, all messages will be selected. * You can use a string like `2` to specify a single message, or slice like `2:4` to specify a range of messages (2 inclusive, 4 exclusive). * Or use `-6:` to select the last 6 messages. * * @example * ```xml * <conversation messages="{{[{ speaker: 'human', content: 'What is the capital of France?' }, { speaker: 'ai', content: 'Paris' }]}}" /> * ``` */ component('Conversation', ['conversation'])((props) => { let { children, messages, selectedMessages, ...others } = props; if (selectedMessages) { const [start, end] = parsePythonStyleSlice(selectedMessages, messages.length); messages = messages.slice(start, end); } return (React.createElement(Text, null, messages.map((message, index) => (React.createElement(Text, { key: `message-${index}`, speaker: message.speaker, ...others }, React.createElement(MessageContent, { content: message.content, ...others })))))); }); export { MessageContent }; //# sourceMappingURL=message.js.map