chat 4.16.0 → 4.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7S5DLTN2.js → chunk-A2J5CUHD.js} +29 -1
- package/dist/chunk-A2J5CUHD.js.map +1 -0
- package/dist/index.d.ts +84 -9
- package/dist/index.js +85 -18
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime.js +1 -1
- package/docs/actions.mdx +1 -1
- package/docs/adapters/slack.mdx +2 -0
- package/docs/api/postable-message.mdx +12 -4
- package/docs/api/thread.mdx +2 -2
- package/docs/handling-events.mdx +28 -1
- package/docs/posting-messages.mdx +7 -4
- package/docs/streaming.mdx +76 -4
- package/package.json +1 -1
- package/dist/chunk-7S5DLTN2.js.map +0 -1
|
@@ -159,6 +159,34 @@ function root(children) {
|
|
|
159
159
|
return { type: "root", children };
|
|
160
160
|
}
|
|
161
161
|
var BaseFormatConverter = class {
|
|
162
|
+
renderList(node, depth, nodeConverter, unorderedBullet = "-") {
|
|
163
|
+
const indent = " ".repeat(depth);
|
|
164
|
+
const start = node.start ?? 1;
|
|
165
|
+
const lines = [];
|
|
166
|
+
for (const [i, item] of getNodeChildren(node).entries()) {
|
|
167
|
+
const prefix = node.ordered ? `${start + i}.` : unorderedBullet;
|
|
168
|
+
let isFirstContent = true;
|
|
169
|
+
for (const child of getNodeChildren(item)) {
|
|
170
|
+
if (isListNode(child)) {
|
|
171
|
+
lines.push(
|
|
172
|
+
this.renderList(child, depth + 1, nodeConverter, unorderedBullet)
|
|
173
|
+
);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const text2 = nodeConverter(child);
|
|
177
|
+
if (!text2.trim()) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (isFirstContent) {
|
|
181
|
+
lines.push(`${indent}${prefix} ${text2}`);
|
|
182
|
+
isFirstContent = false;
|
|
183
|
+
} else {
|
|
184
|
+
lines.push(`${indent} ${text2}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return lines.join("\n");
|
|
189
|
+
}
|
|
162
190
|
/**
|
|
163
191
|
* Default fallback for converting an unknown mdast node to text.
|
|
164
192
|
* Recursively converts children if present, otherwise extracts the node value.
|
|
@@ -1068,4 +1096,4 @@ export {
|
|
|
1068
1096
|
toModalElement,
|
|
1069
1097
|
isJSX
|
|
1070
1098
|
};
|
|
1071
|
-
//# sourceMappingURL=chunk-
|
|
1099
|
+
//# sourceMappingURL=chunk-A2J5CUHD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/markdown.ts","../src/cards.ts","../src/modals.ts","../src/jsx-runtime.ts"],"sourcesContent":["/**\n * Markdown parsing and conversion utilities using unified/remark.\n */\n\nimport type {\n Blockquote,\n Code,\n Content,\n Delete,\n Emphasis,\n InlineCode,\n Link,\n List,\n ListItem,\n Paragraph,\n Root,\n Strong,\n Table,\n TableCell,\n TableRow,\n Text,\n} from \"mdast\";\n\nimport { toString as mdastToString } from \"mdast-util-to-string\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkParse from \"remark-parse\";\nimport remarkStringify from \"remark-stringify\";\nimport { unified } from \"unified\";\nimport type { CardChild, CardElement } from \"./cards\";\nimport type { AdapterPostableMessage } from \"./types\";\n\n// Alias for use within this file\ntype PostableMessageInput = AdapterPostableMessage;\n\n// Re-export types for adapters\nexport type {\n Blockquote,\n Code,\n Content,\n Delete,\n Emphasis,\n InlineCode,\n Link,\n List,\n ListItem,\n Paragraph,\n Root,\n Strong,\n Table,\n TableCell,\n TableRow,\n Text,\n} from \"mdast\";\n\n// ============================================================================\n// Type Guards for mdast nodes\n// ============================================================================\n\n/**\n * Type guard for text nodes.\n */\nexport function isTextNode(node: Content): node is Text {\n return node.type === \"text\";\n}\n\n/**\n * Type guard for paragraph nodes.\n */\nexport function isParagraphNode(node: Content): node is Paragraph {\n return node.type === \"paragraph\";\n}\n\n/**\n * Type guard for strong (bold) nodes.\n */\nexport function isStrongNode(node: Content): node is Strong {\n return node.type === \"strong\";\n}\n\n/**\n * Type guard for emphasis (italic) nodes.\n */\nexport function isEmphasisNode(node: Content): node is Emphasis {\n return node.type === \"emphasis\";\n}\n\n/**\n * Type guard for delete (strikethrough) nodes.\n */\nexport function isDeleteNode(node: Content): node is Delete {\n return node.type === \"delete\";\n}\n\n/**\n * Type guard for inline code nodes.\n */\nexport function isInlineCodeNode(node: Content): node is InlineCode {\n return node.type === \"inlineCode\";\n}\n\n/**\n * Type guard for code block nodes.\n */\nexport function isCodeNode(node: Content): node is Code {\n return node.type === \"code\";\n}\n\n/**\n * Type guard for link nodes.\n */\nexport function isLinkNode(node: Content): node is Link {\n return node.type === \"link\";\n}\n\n/**\n * Type guard for blockquote nodes.\n */\nexport function isBlockquoteNode(node: Content): node is Blockquote {\n return node.type === \"blockquote\";\n}\n\n/**\n * Type guard for list nodes.\n */\nexport function isListNode(node: Content): node is List {\n return node.type === \"list\";\n}\n\n/**\n * Type guard for list item nodes.\n */\nexport function isListItemNode(node: Content): node is ListItem {\n return node.type === \"listItem\";\n}\n\n/**\n * Type guard for table nodes.\n */\nexport function isTableNode(node: Content): node is Table {\n return node.type === \"table\";\n}\n\n/**\n * Type guard for table row nodes.\n */\nexport function isTableRowNode(node: Content): node is TableRow {\n return node.type === \"tableRow\";\n}\n\n/**\n * Type guard for table cell nodes.\n */\nexport function isTableCellNode(node: Content): node is TableCell {\n return node.type === \"tableCell\";\n}\n\n/**\n * Render an mdast table node as a padded ASCII table string.\n *\n * Produces output like:\n * ```\n * Name | Age | Role\n * ------|-----|--------\n * Alice | 30 | Engineer\n * Bob | 25 | Designer\n * ```\n *\n * Shared by adapters that lack native table support (Slack, GChat, Discord, Telegram).\n */\nexport function tableToAscii(node: Table): string {\n const rows: string[][] = [];\n\n for (const row of node.children) {\n const cells: string[] = [];\n for (const cell of row.children) {\n cells.push(mdastToString(cell));\n }\n rows.push(cells);\n }\n\n if (rows.length === 0) {\n return \"\";\n }\n\n const headers = rows[0];\n const dataRows = rows.slice(1);\n return tableElementToAscii(headers, dataRows);\n}\n\n/**\n * Render a table from headers and string rows as a padded ASCII table.\n * Used for card TableElement fallback rendering.\n */\nexport function tableElementToAscii(\n headers: string[],\n rows: string[][]\n): string {\n const allRows = [headers, ...rows];\n const colCount = Math.max(...allRows.map((r) => r.length));\n if (colCount === 0) {\n return \"\";\n }\n const colWidths: number[] = Array.from({ length: colCount }, () => 0);\n\n for (const row of allRows) {\n for (let i = 0; i < colCount; i++) {\n const cellLen = (row[i] || \"\").length;\n if (cellLen > colWidths[i]) {\n colWidths[i] = cellLen;\n }\n }\n }\n\n const formatRow = (cells: string[]): string =>\n Array.from({ length: colCount }, (_, i) =>\n (cells[i] || \"\").padEnd(colWidths[i])\n )\n .join(\" | \")\n .trimEnd();\n\n const lines: string[] = [];\n lines.push(formatRow(headers));\n lines.push(colWidths.map((w) => \"-\".repeat(w)).join(\"-|-\"));\n for (const row of rows) {\n lines.push(formatRow(row));\n }\n return lines.join(\"\\n\");\n}\n\n// ============================================================================\n// Helper functions for accessing node properties type-safely\n// ============================================================================\n\n/**\n * Get children from a content node that has children.\n * Returns empty array for nodes without children.\n * This eliminates the need for `as Content` casts in adapter converters.\n */\nexport function getNodeChildren(node: Content): Content[] {\n if (\"children\" in node && Array.isArray(node.children)) {\n return node.children as Content[];\n }\n return [];\n}\n\n/**\n * Get value from a content node that has a value property.\n * Returns empty string for nodes without value.\n */\nexport function getNodeValue(node: Content): string {\n if (\"value\" in node && typeof node.value === \"string\") {\n return node.value;\n }\n return \"\";\n}\n\n/**\n * Parse markdown string into an AST.\n * Supports GFM (GitHub Flavored Markdown) for strikethrough, tables, etc.\n */\nexport function parseMarkdown(markdown: string): Root {\n const processor = unified().use(remarkParse).use(remarkGfm);\n return processor.parse(markdown);\n}\n\n/**\n * Stringify an AST back to markdown.\n */\nexport function stringifyMarkdown(ast: Root): string {\n const processor = unified().use(remarkStringify).use(remarkGfm);\n return processor.stringify(ast);\n}\n\n/**\n * Extract plain text from an AST (strips all formatting).\n */\nexport function toPlainText(ast: Root): string {\n return mdastToString(ast);\n}\n\n/**\n * Extract plain text from a markdown string.\n */\nexport function markdownToPlainText(markdown: string): string {\n const ast = parseMarkdown(markdown);\n return mdastToString(ast);\n}\n\n/**\n * Walk the AST and transform nodes.\n */\nexport function walkAst<T extends Content | Root>(\n node: T,\n visitor: (node: Content) => Content | null\n): T {\n if (\"children\" in node && Array.isArray(node.children)) {\n node.children = node.children\n .map((child) => {\n const result = visitor(child as Content);\n if (result === null) {\n return null;\n }\n return walkAst(result, visitor);\n })\n .filter((n): n is Content => n !== null);\n }\n return node;\n}\n\n/**\n * Create a text node.\n */\nexport function text(value: string): Text {\n return { type: \"text\", value };\n}\n\n/**\n * Create a strong (bold) node.\n */\nexport function strong(children: Content[]): Strong {\n return { type: \"strong\", children: children as Strong[\"children\"] };\n}\n\n/**\n * Create an emphasis (italic) node.\n */\nexport function emphasis(children: Content[]): Emphasis {\n return { type: \"emphasis\", children: children as Emphasis[\"children\"] };\n}\n\n/**\n * Create a delete (strikethrough) node.\n */\nexport function strikethrough(children: Content[]): Delete {\n return { type: \"delete\", children: children as Delete[\"children\"] };\n}\n\n/**\n * Create an inline code node.\n */\nexport function inlineCode(value: string): InlineCode {\n return { type: \"inlineCode\", value };\n}\n\n/**\n * Create a code block node.\n */\nexport function codeBlock(value: string, lang?: string): Code {\n return { type: \"code\", value, lang };\n}\n\n/**\n * Create a link node.\n */\nexport function link(url: string, children: Content[], title?: string): Link {\n return { type: \"link\", url, children: children as Link[\"children\"], title };\n}\n\n/**\n * Create a blockquote node.\n */\nexport function blockquote(children: Content[]): Blockquote {\n return { type: \"blockquote\", children: children as Blockquote[\"children\"] };\n}\n\n/**\n * Create a paragraph node.\n */\nexport function paragraph(children: Content[]): Paragraph {\n return { type: \"paragraph\", children: children as Paragraph[\"children\"] };\n}\n\n/**\n * Create a root node (top-level AST container).\n */\nexport function root(children: Content[]): Root {\n return { type: \"root\", children: children as Root[\"children\"] };\n}\n\n/**\n * Interface for platform-specific format converters.\n *\n * The AST (mdast Root) is the canonical representation.\n * All conversions go through the AST:\n *\n * Platform Format <-> AST <-> Markdown String\n *\n * Adapters implement this interface to convert between\n * their platform-specific format and the standard AST.\n */\nexport interface FormatConverter {\n /**\n * Extract plain text from platform format.\n * Convenience method - default implementation uses toAst + toPlainText.\n */\n extractPlainText(platformText: string): string;\n /**\n * Render an AST to the platform's native format.\n * This is the primary method used when sending messages.\n */\n fromAst(ast: Root): string;\n\n /**\n * Parse platform's native format into an AST.\n * This is the primary method used when receiving messages.\n */\n toAst(platformText: string): Root;\n}\n\n/**\n * @deprecated Use FormatConverter instead\n */\nexport interface MarkdownConverter extends FormatConverter {\n // Convenience methods for markdown string I/O\n fromMarkdown(markdown: string): string;\n toMarkdown(platformText: string): string;\n toPlainText(platformText: string): string;\n}\n\n/**\n * Base class for format converters with default implementations.\n */\nexport abstract class BaseFormatConverter implements FormatConverter {\n abstract fromAst(ast: Root): string;\n abstract toAst(platformText: string): Root;\n\n protected renderList(\n node: List,\n depth: number,\n nodeConverter: (node: Content) => string,\n unorderedBullet = \"-\"\n ): string {\n const indent = \" \".repeat(depth);\n const start = node.start ?? 1;\n const lines: string[] = [];\n for (const [i, item] of getNodeChildren(node).entries()) {\n const prefix = node.ordered ? `${start + i}.` : unorderedBullet;\n let isFirstContent = true;\n for (const child of getNodeChildren(item)) {\n if (isListNode(child)) {\n lines.push(\n this.renderList(child, depth + 1, nodeConverter, unorderedBullet)\n );\n continue;\n }\n const text = nodeConverter(child);\n if (!text.trim()) {\n continue;\n }\n if (isFirstContent) {\n lines.push(`${indent}${prefix} ${text}`);\n isFirstContent = false;\n } else {\n lines.push(`${indent} ${text}`);\n }\n }\n }\n return lines.join(\"\\n\");\n }\n\n /**\n * Default fallback for converting an unknown mdast node to text.\n * Recursively converts children if present, otherwise extracts the node value.\n * Adapters should call this in their nodeToX() default case.\n */\n protected defaultNodeToText(\n node: Content,\n nodeConverter: (node: Content) => string\n ): string {\n const children = getNodeChildren(node);\n if (children.length > 0) {\n return children.map(nodeConverter).join(\"\");\n }\n return getNodeValue(node);\n }\n\n /**\n * Template method for implementing fromAst with a node converter.\n * Iterates through AST children and converts each using the provided function.\n * Joins results with double newlines (standard paragraph separation).\n *\n * @param ast - The AST to convert\n * @param nodeConverter - Function to convert each Content node to string\n * @returns Platform-formatted string\n */\n protected fromAstWithNodeConverter(\n ast: Root,\n nodeConverter: (node: Content) => string\n ): string {\n const parts: string[] = [];\n for (const node of ast.children) {\n parts.push(nodeConverter(node as Content));\n }\n return parts.join(\"\\n\\n\");\n }\n\n extractPlainText(platformText: string): string {\n return toPlainText(this.toAst(platformText));\n }\n\n // Convenience methods for markdown string I/O\n fromMarkdown(markdown: string): string {\n return this.fromAst(parseMarkdown(markdown));\n }\n\n toMarkdown(platformText: string): string {\n return stringifyMarkdown(this.toAst(platformText));\n }\n\n /** @deprecated Use extractPlainText instead */\n toPlainText(platformText: string): string {\n return this.extractPlainText(platformText);\n }\n\n /**\n * Convert a PostableMessage to platform format (text only).\n * - string: passed through as raw text (no conversion)\n * - { raw: string }: passed through as raw text (no conversion)\n * - { markdown: string }: converted from markdown to platform format\n * - { ast: Root }: converted from AST to platform format\n * - { card: CardElement }: returns fallback text (cards should be handled by adapter)\n * - CardElement: returns fallback text (cards should be handled by adapter)\n *\n * Note: For cards, adapters should check for card content first and render\n * them using platform-specific card APIs, using this method only for fallback.\n */\n renderPostable(message: PostableMessageInput): string {\n if (typeof message === \"string\") {\n return message;\n }\n if (\"raw\" in message) {\n return message.raw;\n }\n if (\"markdown\" in message) {\n return this.fromMarkdown(message.markdown);\n }\n if (\"ast\" in message) {\n return this.fromAst(message.ast);\n }\n if (\"card\" in message) {\n // Card with fallback text or generate from card content\n return message.fallbackText || this.cardToFallbackText(message.card);\n }\n if (\"type\" in message && message.type === \"card\") {\n // Direct CardElement\n return this.cardToFallbackText(message);\n }\n // Should never reach here with proper typing\n throw new Error(\"Invalid PostableMessage format\");\n }\n\n /**\n * Generate fallback text from a card element.\n * Override in subclasses for platform-specific formatting.\n */\n protected cardToFallbackText(card: CardElement): string {\n const parts: string[] = [];\n\n if (card.title) {\n parts.push(`**${card.title}**`);\n }\n\n if (card.subtitle) {\n parts.push(card.subtitle);\n }\n\n for (const child of card.children) {\n const text = this.cardChildToFallbackText(child);\n if (text) {\n parts.push(text);\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n /**\n * Convert card child element to fallback text.\n */\n protected cardChildToFallbackText(child: CardChild): string | null {\n switch (child.type) {\n case \"text\":\n return child.content;\n case \"fields\":\n return child.children\n .map((f) => `**${f.label}**: ${f.value}`)\n .join(\"\\n\");\n case \"actions\":\n // Actions are interactive-only — exclude from fallback text.\n // See: https://docs.slack.dev/reference/methods/chat.postMessage\n return null;\n case \"table\":\n return tableElementToAscii(child.headers, child.rows);\n case \"section\":\n return child.children\n .map((c) => this.cardChildToFallbackText(c))\n .filter(Boolean)\n .join(\"\\n\");\n default:\n return null;\n }\n }\n}\n","/**\n * Card elements for cross-platform rich messaging.\n *\n * Provides a builder API for creating rich cards that automatically\n * convert to platform-specific formats:\n * - Slack: Block Kit\n * - Teams: Adaptive Cards\n * - Google Chat: Card v2\n *\n * Supports both function-call and JSX syntax:\n *\n * @example Function API\n * ```ts\n * import { Card, Text, Actions, Button } from \"chat\";\n *\n * await thread.post(\n * Card({\n * title: \"Order #1234\",\n * children: [\n * Text(\"Total: $50.00\"),\n * Actions([\n * Button({ id: \"approve\", label: \"Approve\", style: \"primary\" }),\n * Button({ id: \"reject\", label: \"Reject\", style: \"danger\" }),\n * ]),\n * ],\n * })\n * );\n * ```\n *\n * @example JSX API (requires jsxImportSource: \"chat\" in tsconfig)\n * ```tsx\n * /** @jsxImportSource chat *\\/\n * import { Card, Text, Actions, Button } from \"chat\";\n *\n * await thread.post(\n * <Card title=\"Order #1234\">\n * <Text>Total: $50.00</Text>\n * <Actions>\n * <Button id=\"approve\" style=\"primary\">Approve</Button>\n * <Button id=\"reject\" style=\"danger\">Reject</Button>\n * </Actions>\n * </Card>\n * );\n * ```\n */\n\nimport { tableElementToAscii } from \"./markdown\";\nimport type { RadioSelectElement, SelectElement } from \"./modals\";\n\n// ============================================================================\n// Card Element Types\n// ============================================================================\n\n/** Button style options */\nexport type ButtonStyle = \"primary\" | \"danger\" | \"default\";\n\n/** Text style options */\nexport type TextStyle = \"plain\" | \"bold\" | \"muted\";\n\n/** Button element for interactive actions */\nexport interface ButtonElement {\n /** If true, the button is displayed in an inactive state and doesn't respond to user actions */\n disabled?: boolean;\n /** Unique action ID for callback routing */\n id: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n type: \"button\";\n /** Optional payload value sent with action callback */\n value?: string;\n}\n\n/** Link button element that opens a URL */\nexport interface LinkButtonElement {\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n type: \"link-button\";\n /** URL to open when clicked */\n url: string;\n}\n\n/** Text content element */\nexport interface TextElement {\n /** Text content (supports markdown in some platforms) */\n content: string;\n /** Text style */\n style?: TextStyle;\n type: \"text\";\n}\n\n/** Image element */\nexport interface ImageElement {\n /** Alt text for accessibility */\n alt?: string;\n type: \"image\";\n /** Image URL */\n url: string;\n}\n\n/** Visual divider/separator */\nexport interface DividerElement {\n type: \"divider\";\n}\n\n/** Container for action buttons and selects */\nexport interface ActionsElement {\n /** Button, link button, select, and radio select elements */\n children: (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[];\n type: \"actions\";\n}\n\n/** Section container for grouping elements */\nexport interface SectionElement {\n /** Section children */\n children: CardChild[];\n type: \"section\";\n}\n\n/** Inline hyperlink element */\nexport interface LinkElement {\n /** Link label text */\n label: string;\n type: \"link\";\n /** URL to link to */\n url: string;\n}\n\n/** Field for key-value display */\nexport interface FieldElement {\n /** Field label */\n label: string;\n type: \"field\";\n /** Field value */\n value: string;\n}\n\n/** Fields container for multi-column layout */\nexport interface FieldsElement {\n /** Field elements */\n children: FieldElement[];\n type: \"fields\";\n}\n\n/** Column alignment for table elements */\nexport type TableAlignment = \"left\" | \"center\" | \"right\";\n\n/** Table element for structured data display */\nexport interface TableElement {\n /** Column alignment */\n align?: TableAlignment[];\n /** Column header labels */\n headers: string[];\n /** Data rows (each row is an array of cell strings) */\n rows: string[][];\n type: \"table\";\n}\n\n/** Union of all card child element types */\nexport type CardChild =\n | TextElement\n | ImageElement\n | DividerElement\n | ActionsElement\n | SectionElement\n | FieldsElement\n | LinkElement\n | TableElement;\n\n/** Union of all element types (including nested children) */\ntype AnyCardElement =\n | CardChild\n | CardElement\n | ButtonElement\n | LinkButtonElement\n | LinkElement\n | FieldElement\n | SelectElement\n | RadioSelectElement;\n\n/** Root card element */\nexport interface CardElement {\n /** Card content */\n children: CardChild[];\n /** Header image URL */\n imageUrl?: string;\n /** Card subtitle */\n subtitle?: string;\n /** Card title */\n title?: string;\n type: \"card\";\n}\n\n/** Type guard for CardElement */\nexport function isCardElement(value: unknown): value is CardElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n (value as CardElement).type === \"card\"\n );\n}\n\n// ============================================================================\n// Builder Functions\n// ============================================================================\n\n/** Options for Card */\nexport interface CardOptions {\n children?: CardChild[];\n imageUrl?: string;\n subtitle?: string;\n title?: string;\n}\n\n/**\n * Create a Card element.\n *\n * @example\n * ```ts\n * Card({\n * title: \"Welcome\",\n * children: [Text(\"Hello!\")],\n * })\n * ```\n */\nexport function Card(options: CardOptions = {}): CardElement {\n return {\n type: \"card\",\n title: options.title,\n subtitle: options.subtitle,\n imageUrl: options.imageUrl,\n children: options.children ?? [],\n };\n}\n\n/**\n * Create a Text element.\n *\n * @example\n * ```ts\n * Text(\"Hello, world!\")\n * Text(\"Important\", { style: \"bold\" })\n * ```\n */\nexport function Text(\n content: string,\n options: { style?: TextStyle } = {}\n): TextElement {\n return {\n type: \"text\",\n content,\n style: options.style,\n };\n}\n\n/**\n * Alias for Text that avoids conflicts with DOM's global Text constructor.\n * Use this when importing in environments where `Text` would conflict.\n *\n * @example\n * ```ts\n * import { CardText } from \"chat\";\n * CardText(\"Hello, world!\")\n * ```\n */\nexport const CardText = Text;\n\n/**\n * Create an Image element.\n *\n * @example\n * ```ts\n * Image({ url: \"https://example.com/image.png\", alt: \"Description\" })\n * ```\n */\nexport function Image(options: { url: string; alt?: string }): ImageElement {\n return {\n type: \"image\",\n url: options.url,\n alt: options.alt,\n };\n}\n\n/**\n * Create a Divider element.\n *\n * @example\n * ```ts\n * Divider()\n * ```\n */\nexport function Divider(): DividerElement {\n return { type: \"divider\" };\n}\n\n/**\n * Create a Section container.\n *\n * @example\n * ```ts\n * Section([\n * Text(\"Grouped content\"),\n * Image({ url: \"...\" }),\n * ])\n * ```\n */\nexport function Section(children: CardChild[]): SectionElement {\n return {\n type: \"section\",\n children,\n };\n}\n\n/**\n * Create an Actions container for buttons and selects.\n *\n * @example\n * ```ts\n * Actions([\n * Button({ id: \"ok\", label: \"OK\" }),\n * Button({ id: \"cancel\", label: \"Cancel\" }),\n * LinkButton({ url: \"https://example.com\", label: \"Learn More\" }),\n * Select({ id: \"priority\", label: \"Priority\", options: [...] }),\n * RadioSelect({ id: \"status\", label: \"Status\", options: [...] }),\n * ])\n * ```\n */\nexport function Actions(\n children: (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[]\n): ActionsElement {\n return {\n type: \"actions\",\n children,\n };\n}\n\n/** Options for Button */\nexport interface ButtonOptions {\n /** If true, the button is displayed in an inactive state and doesn't respond to user actions */\n disabled?: boolean;\n /** Unique action ID for callback routing */\n id: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n /** Optional payload value sent with action callback */\n value?: string;\n}\n\n/**\n * Create a Button element.\n *\n * @example\n * ```ts\n * Button({ id: \"submit\", label: \"Submit\", style: \"primary\" })\n * Button({ id: \"delete\", label: \"Delete\", style: \"danger\", value: \"item-123\" })\n * ```\n */\nexport function Button(options: ButtonOptions): ButtonElement {\n return {\n type: \"button\",\n id: options.id,\n label: options.label,\n style: options.style,\n value: options.value,\n disabled: options.disabled,\n };\n}\n\n/** Options for LinkButton */\nexport interface LinkButtonOptions {\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n /** URL to open when clicked */\n url: string;\n}\n\n/**\n * Create a LinkButton element that opens a URL when clicked.\n *\n * @example\n * ```ts\n * LinkButton({ url: \"https://example.com\", label: \"View Docs\" })\n * LinkButton({ url: \"https://example.com\", label: \"Learn More\", style: \"primary\" })\n * ```\n */\nexport function LinkButton(options: LinkButtonOptions): LinkButtonElement {\n return {\n type: \"link-button\",\n url: options.url,\n label: options.label,\n style: options.style,\n };\n}\n\n/**\n * Create a Field element for key-value display.\n *\n * @example\n * ```ts\n * Field({ label: \"Status\", value: \"Active\" })\n * ```\n */\nexport function Field(options: { label: string; value: string }): FieldElement {\n return {\n type: \"field\",\n label: options.label,\n value: options.value,\n };\n}\n\n/**\n * Create a Fields container for multi-column layout.\n *\n * @example\n * ```ts\n * Fields([\n * Field({ label: \"Name\", value: \"John\" }),\n * Field({ label: \"Email\", value: \"john@example.com\" }),\n * ])\n * ```\n */\nexport function Fields(children: FieldElement[]): FieldsElement {\n return {\n type: \"fields\",\n children,\n };\n}\n\n/** Options for Table */\nexport interface TableOptions {\n /** Column alignment */\n align?: TableAlignment[];\n /** Column header labels */\n headers: string[];\n /** Data rows */\n rows: string[][];\n}\n\n/**\n * Create a Table element for structured data display.\n *\n * @example\n * ```ts\n * Table({\n * headers: [\"Name\", \"Age\", \"Role\"],\n * rows: [\n * [\"Alice\", \"30\", \"Engineer\"],\n * [\"Bob\", \"25\", \"Designer\"],\n * ],\n * })\n * ```\n */\nexport function Table(options: TableOptions): TableElement {\n return {\n type: \"table\",\n headers: options.headers,\n rows: options.rows,\n align: options.align,\n };\n}\n\n/**\n * Create a CardLink element for inline hyperlinks.\n *\n * @example\n * ```ts\n * CardLink({ url: \"https://example.com\", label: \"Visit Site\" })\n * ```\n */\nexport function CardLink(options: { url: string; label: string }): LinkElement {\n return {\n type: \"link\",\n url: options.url,\n label: options.label,\n };\n}\n\n// ============================================================================\n// React Element Support\n// ============================================================================\n\n/** React element shape (minimal typing to avoid React dependency) */\ninterface ReactElement {\n $$typeof: symbol;\n props: Record<string, unknown>;\n type: unknown;\n}\n\n/**\n * Check if a value is a React element.\n */\nfunction isReactElement(value: unknown): value is ReactElement {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const maybeElement = value as { $$typeof?: unknown };\n if (typeof maybeElement.$$typeof !== \"symbol\") {\n return false;\n }\n const symbolStr = maybeElement.$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n}\n\n/**\n * Map of component functions to their names for React element conversion.\n */\nconst componentMap = new Map<unknown, string>([\n [Card, \"Card\"],\n [Text, \"Text\"],\n [Image, \"Image\"],\n [Divider, \"Divider\"],\n [Section, \"Section\"],\n [Actions, \"Actions\"],\n [Button, \"Button\"],\n [LinkButton, \"LinkButton\"],\n [CardLink, \"CardLink\"],\n [Field, \"Field\"],\n [Fields, \"Fields\"],\n [Table, \"Table\"],\n]);\n\n/**\n * Convert a React element tree to a CardElement tree.\n * This allows using React's JSX with our card components.\n *\n * @example\n * ```tsx\n * import React from \"react\";\n * import { Card, Text, fromReactElement } from \"chat\";\n *\n * const element = (\n * <Card title=\"Hello\">\n * <Text>World</Text>\n * </Card>\n * );\n *\n * const card = fromReactElement(element);\n * await thread.post(card);\n * ```\n */\nexport function fromReactElement(element: unknown): AnyCardElement | null {\n if (!isReactElement(element)) {\n // Already a card element or primitive\n if (isCardElement(element)) {\n return element;\n }\n if (typeof element === \"object\" && element !== null && \"type\" in element) {\n return element as CardChild;\n }\n return null;\n }\n\n const { type, props } = element;\n const componentName = componentMap.get(type);\n\n if (!componentName) {\n // Check if it's an HTML element (string type like \"div\", \"a\", \"span\")\n if (typeof type === \"string\") {\n throw new Error(\n `HTML element <${type}> is not supported in card elements. ` +\n \"Use Card, Text, Section, Actions, Button, Fields, Field, Image, or Divider components instead.\"\n );\n }\n\n // Unknown custom component - try to extract children\n if (props.children) {\n return convertChildren(props.children)[0] ?? null;\n }\n return null;\n }\n\n // Convert children recursively\n const convertedChildren = props.children\n ? convertChildren(props.children)\n : [];\n\n // Helper to filter for CardChild elements\n const isCardChild = (el: AnyCardElement): el is CardChild =>\n el.type !== \"card\" &&\n el.type !== \"button\" &&\n el.type !== \"link-button\" &&\n el.type !== \"field\" &&\n el.type !== \"select\" &&\n el.type !== \"radio_select\";\n\n // Call the appropriate builder function based on component type\n switch (componentName) {\n case \"Card\":\n return Card({\n title: props.title as string | undefined,\n subtitle: props.subtitle as string | undefined,\n imageUrl: props.imageUrl as string | undefined,\n children: convertedChildren.filter(isCardChild),\n });\n\n case \"Text\": {\n // JSX: <Text style=\"bold\">content</Text>\n const content = extractTextContent(props.children);\n return Text(content, { style: props.style as TextStyle | undefined });\n }\n\n case \"Image\":\n return Image({\n url: props.url as string,\n alt: props.alt as string | undefined,\n });\n\n case \"Divider\":\n return Divider();\n\n case \"Section\":\n return Section(convertedChildren.filter(isCardChild));\n\n case \"Actions\":\n return Actions(\n convertedChildren.filter(\n (\n c\n ): c is\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement =>\n c.type === \"button\" ||\n c.type === \"link-button\" ||\n c.type === \"select\" ||\n c.type === \"radio_select\"\n )\n );\n\n case \"Button\": {\n // JSX: <Button id=\"x\" style=\"primary\">Label</Button>\n const label = extractTextContent(props.children);\n return Button({\n id: props.id as string,\n label: (props.label as string | undefined) ?? label,\n style: props.style as ButtonStyle | undefined,\n value: props.value as string | undefined,\n });\n }\n\n case \"LinkButton\": {\n // JSX: <LinkButton url=\"https://...\" style=\"primary\">Label</LinkButton>\n const label = extractTextContent(props.children);\n return LinkButton({\n url: props.url as string,\n label: (props.label as string | undefined) ?? label,\n style: props.style as ButtonStyle | undefined,\n });\n }\n\n case \"CardLink\": {\n const label = extractTextContent(props.children);\n return CardLink({\n url: props.url as string,\n label: (props.label as string | undefined) ?? label,\n });\n }\n\n case \"Field\":\n return Field({\n label: props.label as string,\n value: props.value as string,\n });\n\n case \"Fields\":\n return Fields(\n convertedChildren.filter((c): c is FieldElement => c.type === \"field\")\n );\n\n case \"Table\":\n return Table({\n headers: props.headers as string[],\n rows: props.rows as string[][],\n align: props.align as TableAlignment[] | undefined,\n });\n\n default:\n return null;\n }\n}\n\n/**\n * Convert React children to card elements.\n */\nfunction convertChildren(children: unknown): AnyCardElement[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(convertChildren);\n }\n\n const converted = fromReactElement(children);\n if (converted && typeof converted === \"object\" && \"type\" in converted) {\n // If it's a card, extract its children\n if (converted.type === \"card\") {\n return (converted as CardElement).children;\n }\n return [converted];\n }\n\n return [];\n}\n\n/**\n * Extract text content from React children.\n */\nfunction extractTextContent(children: unknown): string {\n if (typeof children === \"string\") {\n return children;\n }\n if (typeof children === \"number\") {\n return String(children);\n }\n if (Array.isArray(children)) {\n return children.map(extractTextContent).join(\"\");\n }\n return \"\";\n}\n\n// ============================================================================\n// Fallback Text Generation\n// ============================================================================\n\n/**\n * Generate plain text fallback from a CardElement.\n * Used for platforms/clients that can't render rich cards,\n * and for the SentMessage.text property.\n */\nexport function cardToFallbackText(card: CardElement): string {\n const parts: string[] = [];\n\n if (card.title) {\n parts.push(`**${card.title}**`);\n }\n\n if (card.subtitle) {\n parts.push(card.subtitle);\n }\n\n for (const child of card.children) {\n const text = cardChildToFallbackText(child);\n if (text) {\n parts.push(text);\n }\n }\n\n return parts.join(\"\\n\");\n}\n\n/**\n * Generate fallback text from a card child element.\n * Exported so adapter card converters can call it for unknown types.\n */\nexport function cardChildToFallbackText(child: CardChild): string | null {\n switch (child.type) {\n case \"text\":\n return child.content;\n case \"link\":\n return `${child.label} (${child.url})`;\n case \"fields\":\n return child.children.map((f) => `${f.label}: ${f.value}`).join(\"\\n\");\n case \"actions\":\n // Actions are interactive-only — exclude from fallback text.\n // See: https://docs.slack.dev/reference/methods/chat.postMessage\n return null;\n case \"table\":\n return tableElementToAscii(child.headers, child.rows);\n case \"section\":\n return child.children\n .map((c) => cardChildToFallbackText(c))\n .filter(Boolean)\n .join(\"\\n\");\n default:\n return null;\n }\n}\n","/**\n * Modal elements for form dialogs.\n */\n\nimport type { FieldsElement, TextElement } from \"./cards\";\n\n// ============================================================================\n// Modal Element Types\n// ============================================================================\n\nexport const VALID_MODAL_CHILD_TYPES = [\n \"text_input\",\n \"select\",\n \"radio_select\",\n \"text\",\n \"fields\",\n] as const;\n\nexport type ModalChild =\n | TextInputElement\n | SelectElement\n | RadioSelectElement\n | TextElement\n | FieldsElement;\n\nexport interface ModalElement {\n callbackId: string;\n children: ModalChild[];\n closeLabel?: string;\n notifyOnClose?: boolean;\n /** Arbitrary string passed through the modal lifecycle (e.g., JSON context). */\n privateMetadata?: string;\n submitLabel?: string;\n title: string;\n type: \"modal\";\n}\n\nexport interface TextInputElement {\n id: string;\n initialValue?: string;\n label: string;\n maxLength?: number;\n multiline?: boolean;\n optional?: boolean;\n placeholder?: string;\n type: \"text_input\";\n}\n\nexport interface SelectElement {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n placeholder?: string;\n type: \"select\";\n}\n\nexport interface SelectOptionElement {\n description?: string;\n label: string;\n value: string;\n}\n\nexport interface RadioSelectElement {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n type: \"radio_select\";\n}\n\nexport function isModalElement(value: unknown): value is ModalElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n (value as ModalElement).type === \"modal\"\n );\n}\n\nexport function filterModalChildren(children: unknown[]): ModalChild[] {\n const validChildren = children.filter(\n (c): c is ModalChild =>\n typeof c === \"object\" &&\n c !== null &&\n \"type\" in c &&\n VALID_MODAL_CHILD_TYPES.includes(\n (c as { type: string }).type as (typeof VALID_MODAL_CHILD_TYPES)[number]\n )\n );\n if (validChildren.length < children.length) {\n console.warn(\n \"[chat] Modal contains unsupported child elements that were ignored\"\n );\n }\n return validChildren;\n}\n\n// ============================================================================\n// Builder Functions\n// ============================================================================\n\nexport interface ModalOptions {\n callbackId: string;\n children?: ModalChild[];\n closeLabel?: string;\n notifyOnClose?: boolean;\n /** Arbitrary string passed through the modal lifecycle (e.g., JSON context). */\n privateMetadata?: string;\n submitLabel?: string;\n title: string;\n}\n\nexport function Modal(options: ModalOptions): ModalElement {\n return {\n type: \"modal\",\n callbackId: options.callbackId,\n title: options.title,\n submitLabel: options.submitLabel,\n closeLabel: options.closeLabel,\n notifyOnClose: options.notifyOnClose,\n privateMetadata: options.privateMetadata,\n children: options.children ?? [],\n };\n}\n\nexport interface TextInputOptions {\n id: string;\n initialValue?: string;\n label: string;\n maxLength?: number;\n multiline?: boolean;\n optional?: boolean;\n placeholder?: string;\n}\n\nexport function TextInput(options: TextInputOptions): TextInputElement {\n return {\n type: \"text_input\",\n id: options.id,\n label: options.label,\n placeholder: options.placeholder,\n initialValue: options.initialValue,\n multiline: options.multiline,\n optional: options.optional,\n maxLength: options.maxLength,\n };\n}\n\nexport interface SelectOptions {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n placeholder?: string;\n}\n\nexport function Select(options: SelectOptions): SelectElement {\n if (!options.options || options.options.length === 0) {\n throw new Error(\"Select requires at least one option\");\n }\n return {\n type: \"select\",\n id: options.id,\n label: options.label,\n placeholder: options.placeholder,\n options: options.options,\n initialOption: options.initialOption,\n optional: options.optional,\n };\n}\n\nexport function SelectOption(options: {\n label: string;\n value: string;\n description?: string;\n}): SelectOptionElement {\n return {\n label: options.label,\n value: options.value,\n description: options.description,\n };\n}\n\nexport interface RadioSelectOptions {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n}\n\nexport function RadioSelect(options: RadioSelectOptions): RadioSelectElement {\n if (!options.options || options.options.length === 0) {\n throw new Error(\"RadioSelect requires at least one option\");\n }\n return {\n type: \"radio_select\",\n id: options.id,\n label: options.label,\n options: options.options,\n initialOption: options.initialOption,\n optional: options.optional,\n };\n}\n\n// ============================================================================\n// JSX Support\n// ============================================================================\n\ninterface ReactElement {\n $$typeof: symbol;\n props: Record<string, unknown>;\n type: unknown;\n}\n\nfunction isReactElement(value: unknown): value is ReactElement {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const maybeElement = value as { $$typeof?: unknown };\n if (typeof maybeElement.$$typeof !== \"symbol\") {\n return false;\n }\n const symbolStr = maybeElement.$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n}\n\ntype AnyModalElement = ModalElement | ModalChild | SelectOptionElement;\n\nconst modalComponentMap = new Map<unknown, string>([\n [Modal, \"Modal\"],\n [TextInput, \"TextInput\"],\n [Select, \"Select\"],\n [RadioSelect, \"RadioSelect\"],\n [SelectOption, \"SelectOption\"],\n]);\n\nexport function fromReactModalElement(\n element: unknown\n): AnyModalElement | null {\n if (!isReactElement(element)) {\n if (isModalElement(element)) {\n return element;\n }\n if (typeof element === \"object\" && element !== null && \"type\" in element) {\n return element as ModalChild;\n }\n return null;\n }\n\n const { type, props } = element;\n const componentName = modalComponentMap.get(type);\n\n if (!componentName) {\n if (props.children) {\n return convertModalChildren(props.children)[0] ?? null;\n }\n return null;\n }\n\n const convertedChildren = props.children\n ? convertModalChildren(props.children)\n : [];\n\n switch (componentName) {\n case \"Modal\":\n return Modal({\n callbackId: props.callbackId as string,\n title: props.title as string,\n submitLabel: props.submitLabel as string | undefined,\n closeLabel: props.closeLabel as string | undefined,\n notifyOnClose: props.notifyOnClose as boolean | undefined,\n privateMetadata: props.privateMetadata as string | undefined,\n children: filterModalChildren(convertedChildren),\n });\n\n case \"TextInput\":\n return TextInput({\n id: props.id as string,\n label: props.label as string,\n placeholder: props.placeholder as string | undefined,\n initialValue: props.initialValue as string | undefined,\n multiline: props.multiline as boolean | undefined,\n optional: props.optional as boolean | undefined,\n maxLength: props.maxLength as number | undefined,\n });\n\n case \"Select\":\n return Select({\n id: props.id as string,\n label: props.label as string,\n placeholder: props.placeholder as string | undefined,\n options: convertedChildren.filter(\n (c): c is SelectOptionElement =>\n c !== null && \"label\" in c && \"value\" in c && !(\"type\" in c)\n ),\n initialOption: props.initialOption as string | undefined,\n optional: props.optional as boolean | undefined,\n });\n\n case \"RadioSelect\":\n return RadioSelect({\n id: props.id as string,\n label: props.label as string,\n options: convertedChildren.filter(\n (c): c is SelectOptionElement =>\n c !== null && \"label\" in c && \"value\" in c && !(\"type\" in c)\n ),\n initialOption: props.initialOption as string | undefined,\n optional: props.optional as boolean | undefined,\n });\n\n case \"SelectOption\":\n return SelectOption({\n label: props.label as string,\n value: props.value as string,\n description: props.description as string | undefined,\n });\n\n default:\n return null;\n }\n}\n\nfunction convertModalChildren(children: unknown): AnyModalElement[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(convertModalChildren);\n }\n\n const converted = fromReactModalElement(children);\n if (converted) {\n if (isModalElement(converted)) {\n return converted.children;\n }\n return [converted];\n }\n\n return [];\n}\n","/**\n * Custom JSX runtime for chat cards.\n *\n * This allows using JSX syntax without React. Configure your bundler:\n *\n * tsconfig.json:\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"chat\"\n * }\n * }\n *\n * Or per-file:\n * /** @jsxImportSource chat *\\/\n *\n * Usage:\n * ```tsx\n * import { Card, Text, Button, Actions } from \"chat\";\n *\n * const card = (\n * <Card title=\"Order #1234\">\n * <Text>Your order is ready!</Text>\n * <Actions>\n * <Button id=\"pickup\" style=\"primary\">Schedule Pickup</Button>\n * </Actions>\n * </Card>\n * );\n * ```\n */\n\nimport {\n Actions,\n Button,\n type ButtonElement,\n type ButtonStyle,\n Card,\n type CardChild,\n type CardElement,\n CardLink,\n Divider,\n Field,\n type FieldElement,\n Fields,\n Image,\n LinkButton,\n type LinkButtonElement,\n type LinkElement,\n Section,\n Text,\n type TextStyle,\n} from \"./cards\";\n\nimport {\n filterModalChildren,\n isModalElement,\n Modal,\n type ModalChild,\n type ModalElement,\n RadioSelect,\n type RadioSelectElement,\n Select,\n type SelectElement,\n SelectOption,\n type SelectOptionElement,\n TextInput,\n} from \"./modals\";\n\n// Symbol to identify our JSX elements before they're processed\nconst JSX_ELEMENT = Symbol.for(\"chat.jsx.element\");\n\n// ============================================================================\n// JSX Props Types - Strongly typed props for each component\n// ============================================================================\n\n/** Props for Card component in JSX */\nexport interface CardProps {\n children?: unknown;\n imageUrl?: string;\n subtitle?: string;\n title?: string;\n}\n\n/** Props for Text component in JSX */\nexport interface TextProps {\n children?: string | number;\n style?: TextStyle;\n}\n\n/** Props for Button component in JSX */\nexport interface ButtonProps {\n children?: string | number;\n id: string;\n label?: string;\n style?: ButtonStyle;\n value?: string;\n}\n\n/** Props for LinkButton component in JSX */\nexport interface LinkButtonProps {\n children?: string | number;\n label?: string;\n style?: ButtonStyle;\n url: string;\n}\n\n/** Props for CardLink component in JSX */\nexport interface CardLinkProps {\n children?: string | number;\n label?: string;\n url: string;\n}\n\n/** Props for Image component in JSX */\nexport interface ImageProps {\n alt?: string;\n url: string;\n}\n\n/** Props for Field component in JSX */\nexport interface FieldProps {\n label: string;\n value: string;\n}\n\n/** Props for container components (Section, Actions, Fields) */\nexport interface ContainerProps {\n children?: unknown;\n}\n\n/** Props for Divider component (no props) */\nexport type DividerProps = Record<string, never>;\n\n/** Props for Modal component in JSX */\nexport interface ModalProps {\n callbackId: string;\n children?: unknown;\n closeLabel?: string;\n notifyOnClose?: boolean;\n privateMetadata?: string;\n submitLabel?: string;\n title: string;\n}\n\n/** Props for TextInput component in JSX */\nexport interface TextInputProps {\n id: string;\n initialValue?: string;\n label: string;\n maxLength?: number;\n multiline?: boolean;\n optional?: boolean;\n placeholder?: string;\n}\n\n/** Props for Select component in JSX */\nexport interface SelectProps {\n children?: unknown;\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n placeholder?: string;\n}\n\n/** Props for SelectOption component in JSX */\nexport interface SelectOptionProps {\n description?: string;\n label: string;\n value: string;\n}\n\n/** Union of all valid JSX props */\nexport type CardJSXProps =\n | CardProps\n | TextProps\n | ButtonProps\n | LinkButtonProps\n | CardLinkProps\n | ImageProps\n | FieldProps\n | ContainerProps\n | DividerProps\n | ModalProps\n | TextInputProps\n | SelectProps\n | SelectOptionProps;\n\n/** Component function type with proper overloads */\ntype CardComponentFunction =\n | typeof Card\n | typeof Text\n | typeof Button\n | typeof LinkButton\n | typeof CardLink\n | typeof Image\n | typeof Field\n | typeof Divider\n | typeof Section\n | typeof Actions\n | typeof Fields\n | typeof Modal\n | typeof TextInput\n | typeof Select\n | typeof RadioSelect\n | typeof SelectOption;\n\n/**\n * Represents a JSX element from the chat JSX runtime.\n * This is the type returned when using JSX syntax with chat components.\n */\nexport interface CardJSXElement<P extends CardJSXProps = CardJSXProps> {\n $$typeof: typeof JSX_ELEMENT;\n children: unknown[];\n props: P;\n type: CardComponentFunction;\n}\n\n// Internal alias for backwards compatibility\ntype JSXElement = CardJSXElement;\n\n/**\n * Check if a value is a JSX element from our runtime.\n */\nfunction isJSXElement(value: unknown): value is JSXElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as JSXElement).$$typeof === JSX_ELEMENT\n );\n}\n\n/** Non-null card element for children arrays */\ntype CardChildOrNested =\n | CardChild\n | ButtonElement\n | LinkButtonElement\n | LinkElement\n | FieldElement\n | SelectElement\n | SelectOptionElement\n | RadioSelectElement;\n\n/**\n * Process children, converting JSX elements to card elements.\n */\nfunction processChildren(children: unknown): CardChildOrNested[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(processChildren);\n }\n\n // If it's a JSX element, resolve it\n if (isJSXElement(children)) {\n const resolved = resolveJSXElement(children);\n if (resolved) {\n return [resolved as CardChildOrNested];\n }\n return [];\n }\n\n // If it's already a card element, return it\n if (typeof children === \"object\" && \"type\" in children) {\n return [children as CardChildOrNested];\n }\n\n // If it's a string or number, it might be text content for a Button or Text\n if (typeof children === \"string\" || typeof children === \"number\") {\n // Return as string, the component will handle it\n return [String(children) as unknown as CardChildOrNested];\n }\n\n return [];\n}\n\n/** Any card element type that can be created */\ntype AnyCardElement =\n | CardElement\n | CardChild\n | ButtonElement\n | LinkButtonElement\n | FieldElement\n | ModalElement\n | ModalChild\n | SelectOptionElement\n | null;\n\n/**\n * Type guard to check if props match TextProps\n */\nfunction isTextProps(props: CardJSXProps): props is TextProps {\n return !(\"id\" in props || \"url\" in props || \"label\" in props);\n}\n\n/**\n * Type guard to check if props match ButtonProps\n */\nfunction isButtonProps(props: CardJSXProps): props is ButtonProps {\n return \"id\" in props && typeof props.id === \"string\" && !(\"url\" in props);\n}\n\n/**\n * Type guard to check if props match LinkButtonProps\n */\nfunction isLinkButtonProps(props: CardJSXProps): props is LinkButtonProps {\n return \"url\" in props && typeof props.url === \"string\" && !(\"id\" in props);\n}\n\n/**\n * Type guard to check if props match CardLinkProps\n */\nexport function isCardLinkProps(props: CardJSXProps): props is CardLinkProps {\n return (\n \"url\" in props &&\n typeof props.url === \"string\" &&\n !(\"id\" in props) &&\n !(\"alt\" in props) &&\n !(\"style\" in props)\n );\n}\n\n/**\n * Type guard to check if props match ImageProps\n */\nfunction isImageProps(props: CardJSXProps): props is ImageProps {\n return \"url\" in props && typeof props.url === \"string\";\n}\n\n/**\n * Type guard to check if props match FieldProps\n */\nfunction isFieldProps(props: CardJSXProps): props is FieldProps {\n return (\n \"label\" in props &&\n \"value\" in props &&\n typeof props.label === \"string\" &&\n typeof props.value === \"string\"\n );\n}\n\n/**\n * Type guard to check if props match CardProps\n */\nfunction isCardProps(props: CardJSXProps): props is CardProps {\n return (\n !(\"id\" in props || \"url\" in props || \"callbackId\" in props) &&\n (\"title\" in props || \"subtitle\" in props || \"imageUrl\" in props)\n );\n}\n\n/**\n * Type guard to check if props match ModalProps\n */\nfunction isModalProps(props: CardJSXProps): props is ModalProps {\n return \"callbackId\" in props && \"title\" in props;\n}\n\n/**\n * Type guard to check if props match TextInputProps\n */\nfunction isTextInputProps(props: CardJSXProps): props is TextInputProps {\n return (\n \"id\" in props &&\n \"label\" in props &&\n !(\"options\" in props) &&\n !(\"value\" in props)\n );\n}\n\n/**\n * Type guard to check if props match SelectProps\n */\nfunction isSelectProps(props: CardJSXProps): props is SelectProps {\n return \"id\" in props && \"label\" in props && !(\"value\" in props);\n}\n\n/**\n * Type guard to check if props match SelectOptionProps\n */\nfunction isSelectOptionProps(props: CardJSXProps): props is SelectOptionProps {\n return \"label\" in props && \"value\" in props && !(\"id\" in props);\n}\n\n/**\n * Resolve a JSX element by calling its component function.\n * Transforms JSX props into the format each builder function expects.\n */\nfunction resolveJSXElement(element: JSXElement): AnyCardElement {\n const { type, props, children } = element;\n\n // Process children first\n const processedChildren = processChildren(children);\n\n // Use identity comparison to determine which builder function this is\n // This is necessary because function names get minified in production builds\n if (type === Text) {\n // Text(content: string, options?: { style })\n // JSX children become the content string\n const textProps = isTextProps(props) ? props : { style: undefined };\n const content =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : String(textProps.children ?? \"\");\n return Text(content, { style: textProps.style });\n }\n\n if (type === Section) {\n // Section takes array as first argument\n return Section(processedChildren as CardChild[]);\n }\n\n if (type === Actions) {\n // Actions takes array of ButtonElements, LinkButtonElements, SelectElements, and RadioSelectElements\n return Actions(\n processedChildren as (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[]\n );\n }\n\n if (type === Fields) {\n // Fields takes array of FieldElements\n return Fields(processedChildren as FieldElement[]);\n }\n\n if (type === Button) {\n // Button({ id, label, style, value })\n // JSX children become the label\n if (!isButtonProps(props)) {\n throw new Error(\"Button requires an 'id' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return Button({\n id: props.id,\n label,\n style: props.style,\n value: props.value,\n });\n }\n\n if (type === LinkButton) {\n // LinkButton({ url, label, style })\n // JSX children become the label\n if (!isLinkButtonProps(props)) {\n throw new Error(\"LinkButton requires a 'url' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return LinkButton({\n url: props.url,\n label,\n style: props.style,\n });\n }\n\n if (type === CardLink) {\n // CardLink({ url, label })\n // JSX children become the label\n if (!isCardLinkProps(props)) {\n throw new Error(\"CardLink requires a 'url' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return CardLink({\n url: props.url,\n label,\n });\n }\n\n if (type === Image) {\n // Image({ url, alt })\n if (!isImageProps(props)) {\n throw new Error(\"Image requires a 'url' prop\");\n }\n return Image({ url: props.url, alt: props.alt });\n }\n\n if (type === Field) {\n // Field({ label, value })\n if (!isFieldProps(props)) {\n throw new Error(\"Field requires 'label' and 'value' props\");\n }\n return Field({\n label: props.label,\n value: props.value,\n });\n }\n\n if (type === Divider) {\n // Divider() - no args\n return Divider();\n }\n\n // Modal components\n if (type === Modal) {\n if (!isModalProps(props)) {\n throw new Error(\"Modal requires 'callbackId' and 'title' props\");\n }\n return Modal({\n callbackId: props.callbackId,\n title: props.title,\n submitLabel: props.submitLabel,\n closeLabel: props.closeLabel,\n notifyOnClose: props.notifyOnClose,\n privateMetadata: props.privateMetadata,\n children: filterModalChildren(processedChildren),\n });\n }\n\n if (type === TextInput) {\n if (!isTextInputProps(props)) {\n throw new Error(\"TextInput requires 'id' and 'label' props\");\n }\n return TextInput({\n id: props.id,\n label: props.label,\n placeholder: props.placeholder,\n initialValue: props.initialValue,\n multiline: props.multiline,\n optional: props.optional,\n maxLength: props.maxLength,\n });\n }\n\n if (type === Select) {\n if (!isSelectProps(props)) {\n throw new Error(\"Select requires 'id' and 'label' props\");\n }\n return Select({\n id: props.id,\n label: props.label,\n placeholder: props.placeholder,\n initialOption: props.initialOption,\n optional: props.optional,\n options: processedChildren as SelectOptionElement[],\n });\n }\n\n if (type === RadioSelect) {\n if (!isSelectProps(props)) {\n throw new Error(\"RadioSelect requires 'id' and 'label' props\");\n }\n return RadioSelect({\n id: props.id,\n label: props.label,\n initialOption: props.initialOption,\n optional: props.optional,\n options: processedChildren as SelectOptionElement[],\n });\n }\n\n if (type === SelectOption) {\n if (!isSelectOptionProps(props)) {\n throw new Error(\"SelectOption requires 'label' and 'value' props\");\n }\n return SelectOption({\n label: props.label,\n value: props.value,\n description: props.description,\n });\n }\n\n // Default: Card({ title, subtitle, imageUrl, children })\n const cardProps = isCardProps(props) ? props : {};\n return Card({\n title: cardProps.title,\n subtitle: cardProps.subtitle,\n imageUrl: cardProps.imageUrl,\n children: processedChildren as CardChild[],\n });\n}\n\n/**\n * JSX factory function (used by the JSX transform).\n * Creates a lazy JSX element that will be resolved when needed.\n */\nexport function jsx<P extends CardJSXProps>(\n type: CardComponentFunction,\n props: P & { children?: unknown },\n _key?: string\n): CardJSXElement<P> {\n const { children, ...restProps } = props;\n return {\n $$typeof: JSX_ELEMENT,\n type,\n props: restProps as P,\n children: children != null ? [children] : [],\n };\n}\n\n/**\n * JSX factory for elements with multiple children.\n */\nexport function jsxs<P extends CardJSXProps>(\n type: CardComponentFunction,\n props: P & { children?: unknown },\n _key?: string\n): CardJSXElement<P> {\n const { children, ...restProps } = props;\n let resolvedChildren: unknown[];\n if (Array.isArray(children)) {\n resolvedChildren = children;\n } else if (children != null) {\n resolvedChildren = [children];\n } else {\n resolvedChildren = [];\n }\n return {\n $$typeof: JSX_ELEMENT,\n type,\n props: restProps as P,\n children: resolvedChildren,\n };\n}\n\n/**\n * Development JSX factory (same as jsx, but called in dev mode).\n */\nexport const jsxDEV = jsx;\n\n/**\n * Fragment support (flattens children).\n */\nexport function Fragment(props: { children?: unknown }): CardChild[] {\n return processChildren(props.children) as CardChild[];\n}\n\n/**\n * Convert a JSX element tree to a CardElement.\n * Call this on the root JSX element to get a usable CardElement.\n */\nexport function toCardElement(jsxElement: unknown): CardElement | null {\n if (isJSXElement(jsxElement)) {\n const resolved = resolveJSXElement(jsxElement);\n if (\n resolved &&\n typeof resolved === \"object\" &&\n \"type\" in resolved &&\n resolved.type === \"card\"\n ) {\n return resolved as CardElement;\n }\n }\n\n // Already a CardElement\n if (\n typeof jsxElement === \"object\" &&\n jsxElement !== null &&\n \"type\" in jsxElement &&\n (jsxElement as CardElement).type === \"card\"\n ) {\n return jsxElement as CardElement;\n }\n\n return null;\n}\n\nexport function toModalElement(jsxElement: unknown): ModalElement | null {\n if (isJSXElement(jsxElement)) {\n const resolved = resolveJSXElement(jsxElement);\n if (\n resolved &&\n typeof resolved === \"object\" &&\n \"type\" in resolved &&\n resolved.type === \"modal\"\n ) {\n return resolved as ModalElement;\n }\n }\n if (isModalElement(jsxElement)) {\n return jsxElement;\n }\n return null;\n}\n\n/**\n * Check if a value is a JSX element (from our runtime or React).\n */\nexport function isJSX(value: unknown): boolean {\n if (isJSXElement(value)) {\n return true;\n }\n // Check for React elements\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"$$typeof\" in value &&\n typeof (value as { $$typeof: unknown }).$$typeof === \"symbol\"\n ) {\n const symbolStr = (value as { $$typeof: symbol }).$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n }\n return false;\n}\n\n// biome-ignore lint/style/noNamespace: JSX namespace required by TypeScript JSX transform\nexport namespace JSX {\n export interface Element extends JSXElement {}\n // biome-ignore lint/complexity/noBannedTypes: Required for JSX namespace\n export type IntrinsicElements = {};\n export interface ElementChildrenAttribute {\n // biome-ignore lint/complexity/noBannedTypes: Required for JSX children attribute\n children: {};\n }\n}\n"],"mappings":"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","names":["text","text","isReactElement"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { C as CardElement, M as ModalElement, a as CardJSXElement, b as CardChild, A as Actions$1, B as Button$1, c as Card$1, d as cardChildToFallbackText$1, e as CardLink$1, T as Text$1, D as Divider$1, F as Field$1, f as Fields$1, g as fromReactElement$1, I as Image$1, i as isCardElement$1, h as isJSX$1, L as LinkButton$1, S as Section$1, j as Table$2, t as toCardElement$1, k as toModalElement$1, l as fromReactModalElement$1, m as isModalElement$1, n as Modal$1, R as RadioSelect$1, o as Select$1, p as SelectOption$1, q as TextInput$1 } from './jsx-runtime-Bokk9xw5.js';
|
|
2
2
|
export { r as ActionsElement, s as ButtonElement, u as ButtonOptions, V as ButtonProps, v as ButtonStyle, W as CardJSXProps, X as CardLinkProps, w as CardOptions, Y as CardProps, Z as ContainerProps, x as DividerElement, _ as DividerProps, y as FieldElement, $ as FieldProps, z as FieldsElement, E as ImageElement, a0 as ImageProps, G as LinkButtonElement, H as LinkButtonOptions, a1 as LinkButtonProps, J as LinkElement, a3 as ModalChild, a4 as ModalOptions, a5 as RadioSelectElement, a6 as RadioSelectOptions, K as SectionElement, a7 as SelectElement, a8 as SelectOptionElement, a9 as SelectOptions, N as TableAlignment, O as TableElement, P as TableOptions, Q as TextElement, aa as TextInputElement, ab as TextInputOptions, a2 as TextProps, U as TextStyle } from './jsx-runtime-Bokk9xw5.js';
|
|
3
3
|
import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
|
|
4
|
-
import { Root, Content, Blockquote, Code, Emphasis, InlineCode, Delete, Link, ListItem,
|
|
4
|
+
import { Root, List, Content, Blockquote, Code, Emphasis, InlineCode, Delete, Link, ListItem, Paragraph, Strong, TableCell, Table as Table$1, TableRow, Text } from 'mdast';
|
|
5
5
|
export { Blockquote, Code, Content, Delete, Emphasis, InlineCode, Link, List, ListItem, Table as MdastTable, Paragraph, Root, Strong, TableCell, TableRow, Text } from 'mdast';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -263,15 +263,46 @@ interface Adapter<TThreadId = unknown, TRawMessage = unknown> {
|
|
|
263
263
|
* The adapter consumes the async iterable and handles the entire streaming lifecycle.
|
|
264
264
|
* Only available on platforms with native streaming support (e.g., Slack).
|
|
265
265
|
*
|
|
266
|
+
* The stream can yield plain strings (text chunks) or {@link StreamChunk} objects
|
|
267
|
+
* for rich content like task progress cards. Adapters that don't support structured
|
|
268
|
+
* chunks will extract text from `markdown_text` chunks and ignore other types.
|
|
269
|
+
*
|
|
266
270
|
* @param threadId - The thread to stream to
|
|
267
|
-
* @param textStream - Async iterable of text chunks
|
|
271
|
+
* @param textStream - Async iterable of text chunks or structured StreamChunk objects
|
|
268
272
|
* @param options - Platform-specific streaming options
|
|
269
273
|
* @returns The raw message after streaming completes
|
|
270
274
|
*/
|
|
271
|
-
stream?(threadId: string, textStream: AsyncIterable<string>, options?: StreamOptions): Promise<RawMessage<TRawMessage>>;
|
|
275
|
+
stream?(threadId: string, textStream: AsyncIterable<string | StreamChunk>, options?: StreamOptions): Promise<RawMessage<TRawMessage>>;
|
|
272
276
|
/** Bot username (can override global userName) */
|
|
273
277
|
readonly userName: string;
|
|
274
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* A structured streaming chunk for platform-native rich content.
|
|
281
|
+
*
|
|
282
|
+
* On Slack, these map directly to streaming chunk types:
|
|
283
|
+
* - `markdown_text`: Streamed text content
|
|
284
|
+
* - `task_update`: Tool/step progress cards (pending → in_progress → complete → error)
|
|
285
|
+
* - `plan_update`: Plan title updates
|
|
286
|
+
*
|
|
287
|
+
* Adapters that don't support structured chunks will extract `text` from
|
|
288
|
+
* `markdown_text` chunks and ignore other types gracefully.
|
|
289
|
+
*/
|
|
290
|
+
type StreamChunk = MarkdownTextChunk | TaskUpdateChunk | PlanUpdateChunk;
|
|
291
|
+
interface MarkdownTextChunk {
|
|
292
|
+
text: string;
|
|
293
|
+
type: "markdown_text";
|
|
294
|
+
}
|
|
295
|
+
interface TaskUpdateChunk {
|
|
296
|
+
id: string;
|
|
297
|
+
output?: string;
|
|
298
|
+
status: "pending" | "in_progress" | "complete" | "error";
|
|
299
|
+
title: string;
|
|
300
|
+
type: "task_update";
|
|
301
|
+
}
|
|
302
|
+
interface PlanUpdateChunk {
|
|
303
|
+
title: string;
|
|
304
|
+
type: "plan_update";
|
|
305
|
+
}
|
|
275
306
|
/**
|
|
276
307
|
* Options for streaming messages.
|
|
277
308
|
* Platform-specific options are passed through to the adapter.
|
|
@@ -283,6 +314,12 @@ interface StreamOptions {
|
|
|
283
314
|
recipientUserId?: string;
|
|
284
315
|
/** Block Kit elements to attach when stopping the stream (Slack only, via chat.stopStream) */
|
|
285
316
|
stopBlocks?: unknown[];
|
|
317
|
+
/**
|
|
318
|
+
* Slack: Controls how task_update chunks are displayed.
|
|
319
|
+
* - `"timeline"` — individual task cards shown inline with text (default)
|
|
320
|
+
* - `"plan"` — all tasks grouped into a single plan block
|
|
321
|
+
*/
|
|
322
|
+
taskDisplayMode?: "timeline" | "plan";
|
|
286
323
|
/** Minimum interval between updates in ms (default: 1000). Used for fallback mode (GChat/Teams). */
|
|
287
324
|
updateIntervalMs?: number;
|
|
288
325
|
}
|
|
@@ -794,8 +831,23 @@ type AdapterPostableMessage = string | PostableRaw | PostableMarkdown | Postable
|
|
|
794
831
|
* - `{ card: CardElement }` - Rich card with buttons (Block Kit / Adaptive Cards / GChat Cards)
|
|
795
832
|
* - `CardElement` - Direct card element
|
|
796
833
|
* - `AsyncIterable<string>` - Streaming text (e.g., from AI SDK's textStream)
|
|
797
|
-
|
|
798
|
-
|
|
834
|
+
* - `AsyncIterable<string | StreamEvent>` - AI SDK fullStream (auto-detected, extracts text with step separators)
|
|
835
|
+
*/
|
|
836
|
+
type PostableMessage = AdapterPostableMessage | AsyncIterable<string | StreamChunk | StreamEvent>;
|
|
837
|
+
/**
|
|
838
|
+
* Duck-typed stream event compatible with AI SDK's `fullStream`.
|
|
839
|
+
* - `text-delta` events are extracted as text output.
|
|
840
|
+
* - `step-finish` events trigger paragraph separators between steps.
|
|
841
|
+
* - All other event types (tool-call, tool-result, etc.) are silently skipped.
|
|
842
|
+
*/
|
|
843
|
+
type StreamEvent = {
|
|
844
|
+
textDelta: string;
|
|
845
|
+
type: "text-delta";
|
|
846
|
+
} | {
|
|
847
|
+
type: "step-finish";
|
|
848
|
+
} | {
|
|
849
|
+
type: string;
|
|
850
|
+
};
|
|
799
851
|
interface PostableRaw {
|
|
800
852
|
/** File/image attachments */
|
|
801
853
|
attachments?: Attachment[];
|
|
@@ -1067,8 +1119,8 @@ interface ActionEvent<TRawMessage = unknown> {
|
|
|
1067
1119
|
} | undefined>;
|
|
1068
1120
|
/** Platform-specific raw event data */
|
|
1069
1121
|
raw: unknown;
|
|
1070
|
-
/** The thread where the action occurred */
|
|
1071
|
-
thread: Thread<TRawMessage
|
|
1122
|
+
/** The thread where the action occurred (null for view-based actions like home tab buttons) */
|
|
1123
|
+
thread: Thread<TRawMessage> | null;
|
|
1072
1124
|
/** The thread ID */
|
|
1073
1125
|
threadId: string;
|
|
1074
1126
|
/** Trigger ID for opening modals (required by some platforms, may expire quickly) */
|
|
@@ -1979,6 +2031,27 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
|
|
|
1979
2031
|
private runHandlers;
|
|
1980
2032
|
}
|
|
1981
2033
|
|
|
2034
|
+
/**
|
|
2035
|
+
* Normalizes an async iterable stream for use with `thread.post()`.
|
|
2036
|
+
*
|
|
2037
|
+
* Handles three stream types automatically:
|
|
2038
|
+
* - **Text streams** (`AsyncIterable<string>`, e.g. AI SDK `textStream`) —
|
|
2039
|
+
* passed through as-is.
|
|
2040
|
+
* - **Full streams** (`AsyncIterable<object>`, e.g. AI SDK `fullStream`) —
|
|
2041
|
+
* extracts `text-delta` events and injects `"\n\n"` separators between
|
|
2042
|
+
* steps so that multi-step agent output reads naturally.
|
|
2043
|
+
* - **StreamChunk objects** (`task_update`, `plan_update`, `markdown_text`) —
|
|
2044
|
+
* passed through as-is for adapters with native structured chunk support.
|
|
2045
|
+
*
|
|
2046
|
+
* This is used internally by `thread.post()`, so you can pass either stream
|
|
2047
|
+
* directly:
|
|
2048
|
+
* ```ts
|
|
2049
|
+
* await thread.post(result.fullStream); // auto-detected
|
|
2050
|
+
* await thread.post(result.textStream); // still works
|
|
2051
|
+
* ```
|
|
2052
|
+
*/
|
|
2053
|
+
declare function fromFullStream(stream: AsyncIterable<unknown>): AsyncIterable<string | StreamChunk>;
|
|
2054
|
+
|
|
1982
2055
|
/**
|
|
1983
2056
|
* A streaming markdown renderer that buffers potential table headers
|
|
1984
2057
|
* until confirmed by a separator line, preventing tables from flashing
|
|
@@ -2130,7 +2203,8 @@ declare class ThreadImpl<TState = Record<string, unknown>> implements Thread<TSt
|
|
|
2130
2203
|
postEphemeral(user: string | Author, message: AdapterPostableMessage | CardJSXElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
|
|
2131
2204
|
/**
|
|
2132
2205
|
* Handle streaming from an AsyncIterable.
|
|
2133
|
-
*
|
|
2206
|
+
* Normalizes the stream (supports both textStream and fullStream from AI SDK),
|
|
2207
|
+
* then uses adapter's native streaming if available, otherwise falls back to post+edit.
|
|
2134
2208
|
*/
|
|
2135
2209
|
private handleStream;
|
|
2136
2210
|
startTyping(status?: string): Promise<void>;
|
|
@@ -2548,6 +2622,7 @@ interface MarkdownConverter extends FormatConverter {
|
|
|
2548
2622
|
declare abstract class BaseFormatConverter implements FormatConverter {
|
|
2549
2623
|
abstract fromAst(ast: Root): string;
|
|
2550
2624
|
abstract toAst(platformText: string): Root;
|
|
2625
|
+
protected renderList(node: List, depth: number, nodeConverter: (node: Content) => string, unorderedBullet?: string): string;
|
|
2551
2626
|
/**
|
|
2552
2627
|
* Default fallback for converting an unknown mdast node to text.
|
|
2553
2628
|
* Recursively converts children if present, otherwise extracts the node value.
|
|
@@ -2620,4 +2695,4 @@ declare const Select: typeof Select$1;
|
|
|
2620
2695
|
declare const SelectOption: typeof SelectOption$1;
|
|
2621
2696
|
declare const TextInput: typeof TextInput$1;
|
|
2622
2697
|
|
|
2623
|
-
export { type ActionEvent, type ActionHandler, Actions, type Adapter, type AdapterPostableMessage, type AppHomeOpenedEvent, type AppHomeOpenedHandler, type AssistantContextChangedEvent, type AssistantContextChangedHandler, type AssistantThreadStartedEvent, type AssistantThreadStartedHandler, type Attachment, type Author, BaseFormatConverter, Button, Card, CardChild, CardElement, CardJSXElement, CardLink, CardText, type Channel, ChannelImpl, type ChannelInfo, Chat, type ChatConfig, ChatError, type ChatInstance, ConsoleLogger, type CustomEmojiMap, DEFAULT_EMOJI_MAP, Divider, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, type FetchDirection, type FetchOptions, type FetchResult, Field, Fields, type FileUpload, type FormatConverter, type FormattedContent, Image, LinkButton, type ListThreadsOptions, type ListThreadsResult, type Lock, LockError, type LogLevel, type Logger, type MarkdownConverter, type MemberJoinedChannelEvent, type MemberJoinedChannelHandler, type MentionHandler, Message, type MessageData, type MessageHandler, type MessageMetadata, Modal, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type PostEphemeralOptions, type Postable, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableRaw, RadioSelect, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, Section, Select, SelectOption, type SentMessage, type SerializedChannel, type SerializedMessage, type SerializedThread, type SlashCommandEvent, type SlashCommandHandler, type StateAdapter, type StreamOptions, StreamingMarkdownRenderer, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, Table, TextInput, type Thread, ThreadImpl, type ThreadInfo, type ThreadSummary, type WebhookOptions, type WellKnownEmoji, blockquote, cardChildToFallbackText, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, deriveChannelId, emoji, emphasis, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isStrongNode, isTableCellNode, isTableNode, isTableRowNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, root, strikethrough, stringifyMarkdown, strong, tableElementToAscii, tableToAscii, text, toCardElement, toModalElement, toPlainText, walkAst };
|
|
2698
|
+
export { type ActionEvent, type ActionHandler, Actions, type Adapter, type AdapterPostableMessage, type AppHomeOpenedEvent, type AppHomeOpenedHandler, type AssistantContextChangedEvent, type AssistantContextChangedHandler, type AssistantThreadStartedEvent, type AssistantThreadStartedHandler, type Attachment, type Author, BaseFormatConverter, Button, Card, CardChild, CardElement, CardJSXElement, CardLink, CardText, type Channel, ChannelImpl, type ChannelInfo, Chat, type ChatConfig, ChatError, type ChatInstance, ConsoleLogger, type CustomEmojiMap, DEFAULT_EMOJI_MAP, Divider, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, type FetchDirection, type FetchOptions, type FetchResult, Field, Fields, type FileUpload, type FormatConverter, type FormattedContent, Image, LinkButton, type ListThreadsOptions, type ListThreadsResult, type Lock, LockError, type LogLevel, type Logger, type MarkdownConverter, type MarkdownTextChunk, type MemberJoinedChannelEvent, type MemberJoinedChannelHandler, type MentionHandler, Message, type MessageData, type MessageHandler, type MessageMetadata, Modal, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type PlanUpdateChunk, type PostEphemeralOptions, type Postable, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableRaw, RadioSelect, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, Section, Select, SelectOption, type SentMessage, type SerializedChannel, type SerializedMessage, type SerializedThread, type SlashCommandEvent, type SlashCommandHandler, type StateAdapter, type StreamChunk, type StreamEvent, type StreamOptions, StreamingMarkdownRenderer, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, Table, type TaskUpdateChunk, TextInput, type Thread, ThreadImpl, type ThreadInfo, type ThreadSummary, type WebhookOptions, type WellKnownEmoji, blockquote, cardChildToFallbackText, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, deriveChannelId, emoji, emphasis, fromFullStream, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isStrongNode, isTableCellNode, isTableNode, isTableRowNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, root, strikethrough, stringifyMarkdown, strong, tableElementToAscii, tableToAscii, text, toCardElement, toModalElement, toPlainText, walkAst };
|
package/dist/index.js
CHANGED
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
toModalElement,
|
|
60
60
|
toPlainText,
|
|
61
61
|
walkAst
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-A2J5CUHD.js";
|
|
63
63
|
|
|
64
64
|
// src/channel.ts
|
|
65
65
|
import { WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE2, WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE2 } from "@workflow/serde";
|
|
@@ -613,6 +613,41 @@ function extractMessageContent(message) {
|
|
|
613
613
|
// src/thread.ts
|
|
614
614
|
import { WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE3, WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE3 } from "@workflow/serde";
|
|
615
615
|
|
|
616
|
+
// src/from-full-stream.ts
|
|
617
|
+
var STREAM_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
618
|
+
"markdown_text",
|
|
619
|
+
"task_update",
|
|
620
|
+
"plan_update"
|
|
621
|
+
]);
|
|
622
|
+
async function* fromFullStream(stream) {
|
|
623
|
+
let needsSeparator = false;
|
|
624
|
+
let hasEmittedText = false;
|
|
625
|
+
for await (const event of stream) {
|
|
626
|
+
if (typeof event === "string") {
|
|
627
|
+
yield event;
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
if (event === null || typeof event !== "object" || !("type" in event)) {
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
633
|
+
const typed = event;
|
|
634
|
+
if (STREAM_CHUNK_TYPES.has(typed.type)) {
|
|
635
|
+
yield event;
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
if (typed.type === "text-delta" && typeof typed.textDelta === "string") {
|
|
639
|
+
if (needsSeparator && hasEmittedText) {
|
|
640
|
+
yield "\n\n";
|
|
641
|
+
}
|
|
642
|
+
needsSeparator = false;
|
|
643
|
+
hasEmittedText = true;
|
|
644
|
+
yield typed.textDelta;
|
|
645
|
+
} else if (typed.type === "step-finish") {
|
|
646
|
+
needsSeparator = true;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
616
651
|
// src/streaming-markdown.ts
|
|
617
652
|
import remend from "remend";
|
|
618
653
|
var StreamingMarkdownRenderer = class {
|
|
@@ -1080,9 +1115,11 @@ var ThreadImpl = class _ThreadImpl {
|
|
|
1080
1115
|
}
|
|
1081
1116
|
/**
|
|
1082
1117
|
* Handle streaming from an AsyncIterable.
|
|
1083
|
-
*
|
|
1118
|
+
* Normalizes the stream (supports both textStream and fullStream from AI SDK),
|
|
1119
|
+
* then uses adapter's native streaming if available, otherwise falls back to post+edit.
|
|
1084
1120
|
*/
|
|
1085
|
-
async handleStream(
|
|
1121
|
+
async handleStream(rawStream) {
|
|
1122
|
+
const textStream = fromFullStream(rawStream);
|
|
1086
1123
|
const options = {};
|
|
1087
1124
|
if (this._currentMessage) {
|
|
1088
1125
|
options.recipientUserId = this._currentMessage.author.userId;
|
|
@@ -1098,7 +1135,12 @@ var ThreadImpl = class _ThreadImpl {
|
|
|
1098
1135
|
async next() {
|
|
1099
1136
|
const result = await iterator.next();
|
|
1100
1137
|
if (!result.done) {
|
|
1101
|
-
|
|
1138
|
+
const value = result.value;
|
|
1139
|
+
if (typeof value === "string") {
|
|
1140
|
+
accumulated += value;
|
|
1141
|
+
} else if (value.type === "markdown_text") {
|
|
1142
|
+
accumulated += value.text;
|
|
1143
|
+
}
|
|
1102
1144
|
}
|
|
1103
1145
|
return result;
|
|
1104
1146
|
}
|
|
@@ -1112,7 +1154,29 @@ var ThreadImpl = class _ThreadImpl {
|
|
|
1112
1154
|
raw.threadId
|
|
1113
1155
|
);
|
|
1114
1156
|
}
|
|
1115
|
-
|
|
1157
|
+
const textOnlyStream = {
|
|
1158
|
+
[Symbol.asyncIterator]: () => {
|
|
1159
|
+
const iterator = textStream[Symbol.asyncIterator]();
|
|
1160
|
+
return {
|
|
1161
|
+
async next() {
|
|
1162
|
+
while (true) {
|
|
1163
|
+
const result = await iterator.next();
|
|
1164
|
+
if (result.done) {
|
|
1165
|
+
return { value: void 0, done: true };
|
|
1166
|
+
}
|
|
1167
|
+
const value = result.value;
|
|
1168
|
+
if (typeof value === "string") {
|
|
1169
|
+
return { value, done: false };
|
|
1170
|
+
}
|
|
1171
|
+
if (value.type === "markdown_text") {
|
|
1172
|
+
return { value: value.text, done: false };
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
return this.fallbackStream(textOnlyStream, options);
|
|
1116
1180
|
}
|
|
1117
1181
|
async startTyping(status) {
|
|
1118
1182
|
await this.adapter.startTyping(this.id, status);
|
|
@@ -2131,30 +2195,32 @@ var Chat = class {
|
|
|
2131
2195
|
}
|
|
2132
2196
|
modalElement = converted;
|
|
2133
2197
|
}
|
|
2134
|
-
const isEphemeralMessage = event.messageId?.startsWith("ephemeral:");
|
|
2135
2198
|
let message;
|
|
2136
|
-
if (
|
|
2137
|
-
const
|
|
2138
|
-
if (
|
|
2139
|
-
message = recentMessage;
|
|
2140
|
-
}
|
|
2141
|
-
} else if (event.messageId && event.adapter.fetchMessage) {
|
|
2142
|
-
const fetched = await event.adapter.fetchMessage(event.threadId, event.messageId).catch(() => null);
|
|
2143
|
-
if (fetched) {
|
|
2144
|
-
message = new Message(fetched);
|
|
2145
|
-
} else {
|
|
2199
|
+
if (thread) {
|
|
2200
|
+
const isEphemeralMessage = event.messageId?.startsWith("ephemeral:");
|
|
2201
|
+
if (isEphemeralMessage) {
|
|
2146
2202
|
const recentMessage = thread.recentMessages[0];
|
|
2147
2203
|
if (recentMessage && typeof recentMessage.toJSON === "function") {
|
|
2148
2204
|
message = recentMessage;
|
|
2149
2205
|
}
|
|
2206
|
+
} else if (event.messageId && event.adapter.fetchMessage) {
|
|
2207
|
+
const fetched = await event.adapter.fetchMessage(event.threadId, event.messageId).catch(() => null);
|
|
2208
|
+
if (fetched) {
|
|
2209
|
+
message = new Message(fetched);
|
|
2210
|
+
} else {
|
|
2211
|
+
const recentMessage = thread.recentMessages[0];
|
|
2212
|
+
if (recentMessage && typeof recentMessage.toJSON === "function") {
|
|
2213
|
+
message = recentMessage;
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2150
2216
|
}
|
|
2151
2217
|
}
|
|
2152
2218
|
const contextId = crypto.randomUUID();
|
|
2153
|
-
const channel = thread.channel;
|
|
2219
|
+
const channel = thread ? thread.channel : void 0;
|
|
2154
2220
|
this.storeModalContext(
|
|
2155
2221
|
event.adapter.name,
|
|
2156
2222
|
contextId,
|
|
2157
|
-
thread,
|
|
2223
|
+
thread ? thread : void 0,
|
|
2158
2224
|
message,
|
|
2159
2225
|
channel
|
|
2160
2226
|
);
|
|
@@ -3005,6 +3071,7 @@ export {
|
|
|
3005
3071
|
deriveChannelId,
|
|
3006
3072
|
emoji,
|
|
3007
3073
|
emphasis,
|
|
3074
|
+
fromFullStream,
|
|
3008
3075
|
fromReactElement2 as fromReactElement,
|
|
3009
3076
|
fromReactModalElement2 as fromReactModalElement,
|
|
3010
3077
|
getEmoji,
|