/** * @description 表示普通文本块。 */ export interface PromptBlockText { type: "text" content: string } /** * @description 创建一个普通文本块。 */ export const text = (content: string): PromptBlockText => ({ type: "text", content, }) /** * @description 表示空行块。 */ export interface PromptBlockEmptyLine { type: "empty-line" } /** * @description 创建一个空行块。 */ export const emptyLine = (): PromptBlockEmptyLine => ({ type: "empty-line", }) /** * @description 表示作用域内容块。 */ export interface PromptBlockScopeContent { type: "scope-content" content: string } /** * @description 创建一个作用域内容块,并自动包裹三引号边界。 */ export const scopeContent = (content: string): PromptBlockScopeContent => ({ type: "scope-content", content: `""" ${content} """`, }) /** * @description 表示有序列表项块。 */ export interface PromptBlockOrderedListItem { type: "ordered-list-item" content: string } /** * @description 创建一个有序列表项块。 */ export const orderedListItem = (content: string): PromptBlockOrderedListItem => ({ type: "ordered-list-item", content, }) /** * @description 表示无序列表项块。 */ export interface PromptBlockUnorderedListItem { type: "unordered-list-item" content: string } /** * @description 创建一个无序列表项块。 */ export const unorderedListItem = (content: string): PromptBlockUnorderedListItem => ({ type: "unordered-list-item", content, }) /** * @description 表示 Prompt 可接受的基础块类型。 */ export type PromptBlock = | PromptBlockText | PromptBlockEmptyLine | PromptBlockScopeContent | PromptBlockOrderedListItem | PromptBlockUnorderedListItem /** * @description 定义用于创建 Prompt 块的辅助函数集合。 */ export type CreateBlockHelpers = { text: typeof text emptyLine: typeof emptyLine scopeContent: typeof scopeContent orderedListItem: typeof orderedListItem unorderedListItem: typeof unorderedListItem } /** * @description 提供一组可直接复用的 Prompt 块创建辅助函数。 */ export const CREATE_BLOCK_HELPERS: CreateBlockHelpers = { text, emptyLine, scopeContent, orderedListItem, unorderedListItem, } /** * @description 定义 Prompt 的构造选项。 */ export interface PromptOptions { debug?: boolean } /** * @description 以块组合的方式构建 Prompt 文本。 */ export class Prompt { private promptBlocks: PromptBlock[] constructor(options: PromptOptions) { void options this.promptBlocks = [] } /** * @description 使用辅助函数创建并追加一个 Prompt 块。 */ addBlock(creator: (helpers: CreateBlockHelpers) => PromptBlock): this { this.promptBlocks.push(creator(CREATE_BLOCK_HELPERS)) return this } /** * @description 直接追加一个文本块。 */ addText(content: string): this { this.promptBlocks.push(CREATE_BLOCK_HELPERS.text(content)) return this } /** * @description 追加一个空行块。 */ addEmptyLine(): this { this.promptBlocks.push(CREATE_BLOCK_HELPERS.emptyLine()) return this } /** * @description 追加一个作用域内容块。 */ addScopeContent(content: string): this { this.promptBlocks.push(CREATE_BLOCK_HELPERS.scopeContent(content)) return this } /** * @description 追加一个有序列表项块。 */ addOrderedListItem(content: string): this { this.promptBlocks.push(CREATE_BLOCK_HELPERS.orderedListItem(content)) return this } /** * @description 追加一个无序列表项块。 */ addUnorderedListItem(content: string): this { this.promptBlocks.push(CREATE_BLOCK_HELPERS.unorderedListItem(content)) return this } /** * @description 将当前 Prompt 块序列渲染为字符串。 * * 当前实现支持基础文本、空行、作用域内容以及简单的有序/无序列表,且列表不支持嵌套。 */ async getPromptInString(): Promise { const orderedListContext = { enabled: false, index: 1, } const resetOrderedListContext = (): void => { orderedListContext.enabled = false orderedListContext.index = 1 } const unorderedListContext = { enabled: false, } const resetUnorderedListContext = (): void => { unorderedListContext.enabled = false } // TODO: 目前有序列表和无序列表不支持嵌套。 const promptInString = this.promptBlocks .map((block) => { switch (block.type) { case "text": { resetOrderedListContext() resetUnorderedListContext() return block.content } case "empty-line": { resetOrderedListContext() resetUnorderedListContext() return "\r\n" } case "scope-content": { resetOrderedListContext() resetUnorderedListContext() return block.content } case "ordered-list-item": { resetUnorderedListContext() if (orderedListContext.enabled === false) { orderedListContext.enabled = true const currentIndex = orderedListContext.index orderedListContext.index = currentIndex + 1 return `${currentIndex}. ${block.content}` } const currentIndex = orderedListContext.index orderedListContext.index = currentIndex + 1 return `${currentIndex}. ${block.content}` } case "unordered-list-item": { resetOrderedListContext() if (unorderedListContext.enabled === false) { unorderedListContext.enabled = true return `- ${block.content}` } return `- ${block.content}` } default: { throw new Error(`Unknown block type: ${String(block)}`) } } }) .join("\r\n") return await Promise.resolve(promptInString) } }