@ai-sdk/tui 1.0.27 → 1.0.29

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @ai-sdk/tui
2
2
 
3
+ ## 1.0.29
4
+
5
+ ### Patch Changes
6
+
7
+ - 6175a94: Allow `runAgentTUI` to communicate with remote agents through a `ChatTransport`.
8
+
9
+ ## 1.0.28
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [0bc8d4f]
14
+ - ai@7.0.28
15
+
3
16
  ## 1.0.27
4
17
 
5
18
  ### Patch Changes
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ai-sdk/tui
2
2
 
3
- Run AI SDK agents in a terminal UI.
3
+ Run local or remote AI SDK agents in a terminal UI.
4
4
 
5
5
  `@ai-sdk/tui` provides a full-screen interface with streaming output,
6
6
  tool cards, approvals, markdown rendering, scrollback, and a pinned prompt.
@@ -49,6 +49,18 @@ await runAgentTUI({
49
49
  });
50
50
  ```
51
51
 
52
+ To connect to a remote agent, pass a `ChatTransport` instead:
53
+
54
+ ```ts
55
+ import { runAgentTUI } from '@ai-sdk/tui';
56
+ import { DefaultChatTransport } from 'ai';
57
+
58
+ await runAgentTUI({
59
+ title: 'Remote Agent',
60
+ transport: new DefaultChatTransport({ api: 'https://example.com/api/chat' }),
61
+ });
62
+ ```
63
+
52
64
  ## Controls
53
65
 
54
66
  - `Enter`: submit prompt
@@ -73,9 +85,11 @@ await runAgentTUI({
73
85
 
74
86
  Settings:
75
87
 
76
- - `agent`: AI SDK agent to run.
88
+ - `agent`: AI SDK agent to run. Provide either `agent` or `transport`.
89
+ - `transport`: AI SDK chat transport used to communicate with a remote agent.
90
+ Provide either `agent` or `transport`.
77
91
  - `title`: optional title shown in the terminal UI.
78
92
  - `tools`: tool call rendering mode. Use `"full"` to show tool input and output, `"collapsed"` to show only tool cards, `"auto-collapsed"` to show the latest tool expanded until another visible section appears, or `"hidden"` to omit tool calls. Defaults to `"auto-collapsed"`.
79
93
  - `reasoning`: reasoning rendering mode. Use `"full"` to show reasoning, `"collapsed"` to show only reasoning cards, `"auto-collapsed"` to show the latest reasoning expanded until another visible section appears, or `"hidden"` to omit reasoning. Defaults to `"auto-collapsed"`.
80
94
  - `responseStatistics`: response header statistic. Use `"outputTokensPerSecond"` to show output token throughput or `"outputTokenCount"` to show output token count. Defaults to `"outputTokensPerSecond"`.
81
- - `sandbox`: optional sandbox session forwarded to every agent call as `experimental_sandbox` for tool descriptions and tool execution.
95
+ - `sandbox`: optional sandbox session forwarded to every agent call as `experimental_sandbox` for tool descriptions and tool execution. Only available with `agent`.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Agent, Experimental_SandboxSession } from 'ai';
1
+ import { Agent, Experimental_SandboxSession, ChatTransport, UIMessage } from 'ai';
2
2
 
3
3
  /**
4
4
  * Controls how terminal UI sections for stream parts are displayed.
@@ -25,10 +25,6 @@ type AgentTUIAgent = Agent<any, any, any, any>;
25
25
  * Options for starting an agent in the default terminal UI.
26
26
  */
27
27
  type RunAgentTUIOptions = {
28
- /**
29
- * The agent to run.
30
- */
31
- agent: AgentTUIAgent;
32
28
  /**
33
29
  * The title shown in the terminal UI.
34
30
  */
@@ -58,11 +54,24 @@ type RunAgentTUIOptions = {
58
54
  * percentage of this context window.
59
55
  */
60
56
  contextSize?: number;
57
+ } & ({
58
+ /**
59
+ * The agent to run.
60
+ */
61
+ agent: AgentTUIAgent;
62
+ transport?: never;
61
63
  /**
62
64
  * Sandbox session that is passed through to agent tool execution.
63
65
  */
64
66
  sandbox?: Experimental_SandboxSession;
65
- };
67
+ } | {
68
+ agent?: never;
69
+ /**
70
+ * The transport used to communicate with a remote agent.
71
+ */
72
+ transport: ChatTransport<UIMessage>;
73
+ sandbox?: never;
74
+ });
66
75
  /**
67
76
  * Runs an agent in the default terminal UI until the user exits.
68
77
  */
package/dist/index.js CHANGED
@@ -1438,14 +1438,17 @@ function parseKey(chunk) {
1438
1438
  // src/agent-tui-runner.ts
1439
1439
  import {
1440
1440
  convertToModelMessages,
1441
+ generateId,
1441
1442
  getToolName as getToolName2,
1442
1443
  isToolUIPart as isToolUIPart2
1443
1444
  } from "ai";
1444
1445
  var defaultResponseStatistics2 = "outputTokensPerSecond";
1445
1446
  var AgentTUIRunner = class {
1446
1447
  constructor(options) {
1448
+ this.chatId = generateId();
1447
1449
  var _a, _b, _c, _d;
1448
1450
  this.agent = options.agent;
1451
+ this.transport = options.transport;
1449
1452
  this.renderer = (_a = createRenderer(options)) != null ? _a : createDefaultRenderer(options);
1450
1453
  this.title = options.title;
1451
1454
  this.tools = (_b = options.tools) != null ? _b : "auto-collapsed";
@@ -1540,9 +1543,24 @@ var AgentTUIRunner = class {
1540
1543
  }
1541
1544
  async streamMessages(messages, generateMessageId) {
1542
1545
  const abortController = new AbortController();
1543
- const result = await this.agent.stream({
1546
+ const abort = () => abortController.abort();
1547
+ if (this.transport) {
1548
+ return {
1549
+ uiMessageStream: await this.transport.sendMessages({
1550
+ trigger: "submit-message",
1551
+ chatId: this.chatId,
1552
+ messageId: void 0,
1553
+ messages,
1554
+ abortSignal: abortController.signal
1555
+ }),
1556
+ message: lastAssistantMessage(messages),
1557
+ abort
1558
+ };
1559
+ }
1560
+ const agent = this.agent;
1561
+ const result = await agent.stream({
1544
1562
  prompt: await convertToModelMessages(messages, {
1545
- tools: this.agent.tools
1563
+ tools: agent.tools
1546
1564
  }),
1547
1565
  abortSignal: abortController.signal,
1548
1566
  options: void 0,
@@ -1555,7 +1573,7 @@ var AgentTUIRunner = class {
1555
1573
  messages
1556
1574
  ),
1557
1575
  message: lastAssistantMessage(messages),
1558
- abort: () => abortController.abort()
1576
+ abort
1559
1577
  };
1560
1578
  }
1561
1579
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tui/terminal-text.ts","../src/tui/markdown.ts","../src/tui/layout.ts","../src/tui/terminal-frame-buffer.ts","../src/tui/terminal-renderer.ts","../src/agent-tui-runner.ts","../src/run-agent-tui.ts"],"sourcesContent":["const ansiEscape = String.fromCharCode(27);\n\nexport const ansiPattern = new RegExp(`${ansiEscape}\\\\[[0-?]*[ -/]*[@-~]`, 'g');\nexport const ansiPrefixPattern = new RegExp(\n `^${ansiEscape}\\\\[[0-?]*[ -/]*[@-~]`,\n);\n\nexport function stripAnsi(input: string): string {\n return input.replace(ansiPattern, '');\n}\n\nexport function visibleLength(input: string): number {\n let width = 0;\n let index = 0;\n\n while (index < input.length) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (ansiMatch) {\n index += ansiMatch[0].length;\n continue;\n }\n\n const codePoint = input.codePointAt(index);\n\n if (codePoint == null) {\n break;\n }\n\n const character = String.fromCodePoint(codePoint);\n width += codePointWidth(codePoint);\n index += character.length;\n }\n\n return width;\n}\n\nexport function sliceVisible(input: string, width: number): string {\n if (width <= 0) {\n return '';\n }\n\n let output = '';\n let visible = 0;\n let index = 0;\n\n while (index < input.length && visible < width) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (ansiMatch) {\n output += ansiMatch[0];\n index += ansiMatch[0].length;\n continue;\n }\n\n const codePoint = input.codePointAt(index);\n\n if (codePoint == null) {\n break;\n }\n\n const character = String.fromCodePoint(codePoint);\n const characterWidth = codePointWidth(codePoint);\n\n if (characterWidth > 0 && visible + characterWidth > width) {\n break;\n }\n\n output += character;\n index += character.length;\n visible += characterWidth;\n }\n\n while (index < input.length) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (!ansiMatch) {\n break;\n }\n\n output += ansiMatch[0];\n index += ansiMatch[0].length;\n }\n\n return output;\n}\n\nexport function codePointWidth(codePoint: number): number {\n if (codePoint === 0x09) {\n return 4;\n }\n\n if (codePoint < 0x20 || (codePoint >= 0x7f && codePoint < 0xa0)) {\n return 0;\n }\n\n if (isZeroWidthCodePoint(codePoint)) {\n return 0;\n }\n\n return isWideCodePoint(codePoint) ? 2 : 1;\n}\n\nfunction isZeroWidthCodePoint(codePoint: number): boolean {\n return (\n (codePoint >= 0x0300 && codePoint <= 0x036f) ||\n (codePoint >= 0x0483 && codePoint <= 0x0489) ||\n (codePoint >= 0x0591 && codePoint <= 0x05bd) ||\n codePoint === 0x05bf ||\n (codePoint >= 0x05c1 && codePoint <= 0x05c2) ||\n (codePoint >= 0x05c4 && codePoint <= 0x05c5) ||\n codePoint === 0x05c7 ||\n (codePoint >= 0x0610 && codePoint <= 0x061a) ||\n (codePoint >= 0x064b && codePoint <= 0x065f) ||\n codePoint === 0x0670 ||\n (codePoint >= 0x06d6 && codePoint <= 0x06dc) ||\n (codePoint >= 0x06df && codePoint <= 0x06e4) ||\n (codePoint >= 0x06e7 && codePoint <= 0x06e8) ||\n (codePoint >= 0x06ea && codePoint <= 0x06ed) ||\n codePoint === 0x0711 ||\n (codePoint >= 0x0730 && codePoint <= 0x074a) ||\n (codePoint >= 0x07a6 && codePoint <= 0x07b0) ||\n (codePoint >= 0x07eb && codePoint <= 0x07f3) ||\n (codePoint >= 0x0816 && codePoint <= 0x0819) ||\n (codePoint >= 0x081b && codePoint <= 0x0823) ||\n (codePoint >= 0x0825 && codePoint <= 0x0827) ||\n (codePoint >= 0x0829 && codePoint <= 0x082d) ||\n (codePoint >= 0x0859 && codePoint <= 0x085b) ||\n (codePoint >= 0x08d3 && codePoint <= 0x0902) ||\n codePoint === 0x093a ||\n codePoint === 0x093c ||\n (codePoint >= 0x0941 && codePoint <= 0x0948) ||\n codePoint === 0x094d ||\n (codePoint >= 0x0951 && codePoint <= 0x0957) ||\n codePoint === 0x200d ||\n (codePoint >= 0xfe00 && codePoint <= 0xfe0f) ||\n (codePoint >= 0xe0100 && codePoint <= 0xe01ef)\n );\n}\n\nfunction isWideCodePoint(codePoint: number): boolean {\n return (\n codePoint >= 0x1100 &&\n (codePoint <= 0x115f ||\n codePoint === 0x2329 ||\n codePoint === 0x232a ||\n (codePoint >= 0x2e80 && codePoint <= 0xa4cf && codePoint !== 0x303f) ||\n (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||\n (codePoint >= 0xf900 && codePoint <= 0xfaff) ||\n (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||\n (codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||\n (codePoint >= 0xff00 && codePoint <= 0xff60) ||\n (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||\n (codePoint >= 0x1f300 && codePoint <= 0x1f64f) ||\n (codePoint >= 0x1f900 && codePoint <= 0x1f9ff) ||\n (codePoint >= 0x20000 && codePoint <= 0x3fffd))\n );\n}\n","import { visibleLength } from './terminal-text';\n\nexport type MarkdownToken =\n | { type: 'text'; text: string }\n | { type: 'bold'; text: string }\n | { type: 'italic'; text: string }\n | { type: 'code'; text: string };\n\ntype TableAlignment = 'left' | 'center' | 'right';\n\nconst ansi = {\n bold: '\\x1b[1m',\n boldOff: '\\x1b[22m',\n italic: '\\x1b[3m',\n italicOff: '\\x1b[23m',\n};\n\nconst tableSeparator = '─';\n\nexport function renderMarkdown(input: string): string {\n const lines = input.split('\\n');\n const output: string[] = [];\n\n for (let index = 0; index < lines.length; index += 1) {\n const table = parseTable(lines, index);\n\n if (table != null) {\n output.push(...renderTable(table));\n index = table.endIndex - 1;\n continue;\n }\n\n output.push(renderMarkdownLine(lines[index] ?? ''));\n }\n\n return output.join('\\n');\n}\n\nfunction renderMarkdownLine(line: string): string {\n if (line.startsWith('### ')) {\n return renderInlineMarkdown(`▶ ${line.slice(4)}`);\n }\n\n if (line.startsWith('## ')) {\n return renderInlineMarkdown(`■ ${line.slice(3)}`);\n }\n\n if (line.startsWith('# ')) {\n return renderInlineMarkdown(`█ ${line.slice(2)}`);\n }\n\n const unorderedListItem = line.match(/^(\\s*)[-+*]\\s+(.*)$/);\n if (unorderedListItem) {\n const [, indentation, text = ''] = unorderedListItem;\n return renderInlineMarkdown(\n `${indentation}•${text.length > 0 ? ` ${text}` : ''}`,\n );\n }\n\n if (/^\\d+\\. /.test(line)) {\n return renderInlineMarkdown(line.replace(/^(\\d+)\\. /, '$1. '));\n }\n\n if (line.startsWith('> ')) {\n return renderInlineMarkdown(`│ ${line.slice(2)}`);\n }\n\n return renderInlineMarkdown(line);\n}\n\nfunction renderInlineMarkdown(input: string): string {\n return input\n .replace(/`([^`]+)`/g, '$1')\n .replace(/\\*\\*([^*\\n]+)\\*\\*/g, `${ansi.bold}$1${ansi.boldOff}`)\n .replace(/__([^_\\n]+)__/g, `${ansi.bold}$1${ansi.boldOff}`)\n .replace(/\\*([^*\\n]+)\\*/g, `${ansi.italic}$1${ansi.italicOff}`)\n .replace(/_([^_\\n]+)_/g, `${ansi.italic}$1${ansi.italicOff}`);\n}\n\ntype ParsedTable = {\n alignments: TableAlignment[];\n endIndex: number;\n header: string[];\n rows: string[][];\n};\n\nfunction parseTable(\n lines: string[],\n startIndex: number,\n): ParsedTable | undefined {\n const header = parseTableCells(lines[startIndex] ?? '');\n if (header == null || header.length < 2) {\n return undefined;\n }\n\n const separatorCells = parseTableCells(lines[startIndex + 1] ?? '');\n if (separatorCells == null || separatorCells.length !== header.length) {\n return undefined;\n }\n\n const alignments = parseTableAlignments(separatorCells);\n if (alignments == null) {\n return undefined;\n }\n\n const rows: string[][] = [];\n let endIndex = startIndex + 2;\n\n while (endIndex < lines.length) {\n const row = parseTableCells(lines[endIndex] ?? '');\n if (row == null) {\n break;\n }\n\n rows.push(normalizeTableRow(row, header.length));\n endIndex += 1;\n }\n\n return {\n alignments,\n endIndex,\n header,\n rows,\n };\n}\n\nfunction parseTableCells(line: string): string[] | undefined {\n if (!line.includes('|')) {\n return undefined;\n }\n\n let tableLine = line.trim();\n if (tableLine.startsWith('|')) {\n tableLine = tableLine.slice(1);\n }\n if (tableLine.endsWith('|') && !tableLine.endsWith('\\\\|')) {\n tableLine = tableLine.slice(0, -1);\n }\n\n const cells: string[] = [];\n let cell = '';\n\n for (let index = 0; index < tableLine.length; index += 1) {\n const character = tableLine[index];\n const nextCharacter = tableLine[index + 1];\n\n if (character === '\\\\' && nextCharacter === '|') {\n cell += '|';\n index += 1;\n continue;\n }\n\n if (character === '|') {\n cells.push(cell.trim());\n cell = '';\n continue;\n }\n\n cell += character;\n }\n\n cells.push(cell.trim());\n\n return cells;\n}\n\nfunction parseTableAlignments(cells: string[]): TableAlignment[] | undefined {\n const alignments: TableAlignment[] = [];\n\n for (const cell of cells) {\n const match = cell.match(/^(:)?-{3,}(:)?$/);\n if (match == null) {\n return undefined;\n }\n\n const [, left, right] = match;\n alignments.push(\n left != null && right != null\n ? 'center'\n : right != null\n ? 'right'\n : 'left',\n );\n }\n\n return alignments;\n}\n\nfunction normalizeTableRow(row: string[], length: number): string[] {\n return Array.from({ length }, (_, index) => row[index] ?? '');\n}\n\nfunction renderTable(table: ParsedTable): string[] {\n const header = table.header.map(\n cell => `${ansi.bold}${renderInlineMarkdown(cell)}${ansi.boldOff}`,\n );\n const rows = table.rows.map(row => row.map(renderInlineMarkdown));\n const tableRows = [header, ...rows];\n const widths = table.alignments.map((_, columnIndex) =>\n Math.max(3, ...tableRows.map(row => visibleLength(row[columnIndex] ?? ''))),\n );\n\n return [\n formatTableRow(header, widths, table.alignments),\n widths.map(width => tableSeparator.repeat(width)).join(' '),\n ...rows.map(row => formatTableRow(row, widths, table.alignments)),\n ];\n}\n\nfunction formatTableRow(\n row: string[],\n widths: number[],\n alignments: TableAlignment[],\n): string {\n return row\n .map((cell, index) =>\n alignTableCell(cell, widths[index] ?? 0, alignments[index] ?? 'left'),\n )\n .join(' ');\n}\n\nfunction alignTableCell(\n cell: string,\n width: number,\n alignment: TableAlignment,\n): string {\n const paddingWidth = Math.max(0, width - visibleLength(cell));\n\n if (alignment === 'right') {\n return `${' '.repeat(paddingWidth)}${cell}`;\n }\n\n if (alignment === 'center') {\n const leftPadding = Math.floor(paddingWidth / 2);\n const rightPadding = paddingWidth - leftPadding;\n return `${' '.repeat(leftPadding)}${cell}${' '.repeat(rightPadding)}`;\n }\n\n return `${cell}${' '.repeat(paddingWidth)}`;\n}\n","import { renderMarkdown } from './markdown';\nimport {\n ansiPrefixPattern,\n codePointWidth,\n sliceVisible,\n visibleLength,\n} from './terminal-text';\n\nexport { sliceVisible, stripAnsi, visibleLength } from './terminal-text';\n\nconst horizontal = '─';\n\nexport type TUIScreenState = {\n width: number;\n height: number;\n title: string;\n rightTitle?: string;\n body: string;\n input: string;\n inputActive: boolean;\n inputCursorVisible?: boolean;\n scrollOffset: number;\n status?: string;\n};\n\nexport type TUIScreenLinesState = Omit<TUIScreenState, 'body'> & {\n bodyLines: string[];\n};\n\nexport type TUIScreenViewportState = Omit<\n TUIScreenLinesState,\n 'bodyLines' | 'scrollOffset'\n> & {\n visibleBodyLines: string[];\n};\n\nexport function renderScreen(state: TUIScreenState): string {\n const width = Math.max(20, state.width);\n const contentWidth = width - 4;\n const bodyLines = wrapText(renderMarkdown(state.body), contentWidth);\n\n return renderScreenLines({ ...state, bodyLines });\n}\n\nexport function renderScreenLines(state: TUIScreenLinesState): string {\n const height = Math.max(8, state.height);\n const inputHeight = 3;\n const bodyHeight = height - inputHeight;\n const bodyContentHeight = bodyHeight - 2;\n\n const maxScrollOffset = Math.max(\n 0,\n state.bodyLines.length - bodyContentHeight,\n );\n const scrollOffset = Math.min(\n Math.max(0, state.scrollOffset),\n maxScrollOffset,\n );\n const start = Math.max(\n 0,\n state.bodyLines.length - bodyContentHeight - scrollOffset,\n );\n const visibleBody = state.bodyLines.slice(start, start + bodyContentHeight);\n\n return renderScreenViewport({ ...state, visibleBodyLines: visibleBody });\n}\n\nexport function renderScreenViewport(state: TUIScreenViewportState): string {\n const width = Math.max(20, state.width);\n const height = Math.max(8, state.height);\n const inputHeight = 3;\n const bodyHeight = height - inputHeight;\n const bodyContentHeight = bodyHeight - 2;\n const visibleBody = state.visibleBodyLines.slice(0, bodyContentHeight);\n\n while (visibleBody.length < bodyContentHeight) {\n visibleBody.push('');\n }\n\n const lines = [\n topBorder(width, state.title, state.rightTitle),\n ...visibleBody.map(line => boxLine(line, width)),\n bottomBorder(width),\n topBorder(width, state.inputActive ? 'Input' : 'Status'),\n boxLine(\n state.inputActive\n ? `> ${state.input}${state.inputCursorVisible === false ? ' ' : '█'}`\n : (state.status ?? 'Streaming... ↑/↓ scroll · Ctrl+C quit'),\n width,\n ),\n bottomBorder(width),\n ];\n\n return lines.join('\\n');\n}\n\nexport function wrapText(input: string, width: number): string[] {\n if (width <= 0) {\n return [''];\n }\n\n const output: string[] = [];\n\n for (const rawLine of input.split('\\n')) {\n if (rawLine.length === 0) {\n output.push('');\n continue;\n }\n\n let remaining = rawLine;\n\n while (visibleLength(remaining) > width) {\n const breakAt = findBreakPoint(remaining, width);\n output.push(remaining.slice(0, breakAt).trimEnd());\n remaining = remaining.slice(breakAt).trimStart();\n }\n\n output.push(remaining);\n }\n\n return output;\n}\n\nexport function clampScrollOffset(\n scrollOffset: number,\n body: string,\n bodyHeight: number,\n width: number,\n): number {\n const bodyContentHeight = Math.max(1, bodyHeight - 2);\n const bodyLines = wrapText(renderMarkdown(body), Math.max(1, width - 4));\n const maxScrollOffset = Math.max(0, bodyLines.length - bodyContentHeight);\n\n return Math.min(Math.max(0, scrollOffset), maxScrollOffset);\n}\n\nfunction findBreakPoint(input: string, width: number): number {\n let index = 0;\n let visible = 0;\n let lastSpace = -1;\n\n while (index < input.length && visible < width) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (ansiMatch) {\n index += ansiMatch[0].length;\n continue;\n }\n\n const codePoint = input.codePointAt(index);\n\n if (codePoint == null) {\n break;\n }\n\n const character = String.fromCodePoint(codePoint);\n const characterWidth = codePointWidth(codePoint);\n\n if (characterWidth > 0 && visible + characterWidth > width) {\n break;\n }\n\n if (character === ' ') {\n lastSpace = index;\n }\n\n index += character.length;\n visible += characterWidth;\n }\n\n const nextBreakIndex = indexAfterAnsiSequences(input, index);\n if (visible === width && input.codePointAt(nextBreakIndex) === 0x20) {\n return nextBreakIndex;\n }\n\n if (lastSpace > 0) {\n return lastSpace;\n }\n\n return indexAtVisibleWidth(input, width);\n}\n\nfunction topBorder(width: number, title: string, rightTitle?: string): string {\n const contentWidth = Math.max(0, width - 2);\n const label = title ? sliceVisible(` ${title} `, contentWidth) : '';\n const rightLabel = rightTitle\n ? sliceVisible(\n ` ${rightTitle} `,\n Math.max(0, contentWidth - visibleLength(label)),\n )\n : '';\n const remaining = Math.max(\n 0,\n contentWidth - visibleLength(label) - visibleLength(rightLabel),\n );\n\n return `┌${label}${horizontal.repeat(remaining)}${rightLabel}┐`;\n}\n\nfunction bottomBorder(width: number): string {\n return `└${horizontal.repeat(width - 2)}┘`;\n}\n\nfunction boxLine(line: string, width: number): string {\n const contentWidth = width - 4;\n const visible = sliceVisible(line, contentWidth);\n const padding = ' '.repeat(\n Math.max(0, contentWidth - visibleLength(visible)),\n );\n\n return `│ ${visible}${padding} │`;\n}\n\nfunction indexAtVisibleWidth(input: string, width: number): number {\n let index = 0;\n let visible = 0;\n\n while (index < input.length && visible < width) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (ansiMatch) {\n index += ansiMatch[0].length;\n continue;\n }\n\n const codePoint = input.codePointAt(index);\n\n if (codePoint == null) {\n break;\n }\n\n const character = String.fromCodePoint(codePoint);\n const characterWidth = codePointWidth(codePoint);\n\n if (characterWidth > 0 && visible + characterWidth > width) {\n break;\n }\n\n index += character.length;\n visible += characterWidth;\n }\n\n return index;\n}\n\nfunction indexAfterAnsiSequences(input: string, startIndex: number): number {\n let index = startIndex;\n\n while (index < input.length) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (!ansiMatch) {\n break;\n }\n\n index += ansiMatch[0].length;\n }\n\n return index;\n}\n","export type TerminalFrameOutput = {\n write(\n chunk: string | Uint8Array,\n encodingOrCallback?: BufferEncoding | ((error?: Error | null) => void),\n callback?: (error?: Error | null) => void,\n ): boolean;\n};\n\nexport type TerminalFrameBufferOptions = {\n useSynchronizedUpdates?: boolean;\n};\n\nconst escape = '\\x1b';\nconst cursorHome = `${escape}[H`;\nconst clearScreen = `${escape}[2J`;\nconst clearLine = `${escape}[2K`;\nconst synchronizeStart = `${escape}[?2026h`;\nconst synchronizeEnd = `${escape}[?2026l`;\n\ntype FrameSnapshot = {\n lines: string[];\n};\n\nexport class TerminalFrameBuffer {\n readonly #useSynchronizedUpdates: boolean;\n readonly #originalWrite: TerminalFrameOutput['write'];\n\n #previousFrame?: FrameSnapshot;\n #isWritingFrame = false;\n #externalWriteSinceLastFrame = false;\n\n constructor(\n output: TerminalFrameOutput,\n options?: TerminalFrameBufferOptions,\n ) {\n this.#originalWrite = output.write.bind(output);\n this.#useSynchronizedUpdates = options?.useSynchronizedUpdates ?? true;\n\n output.write = ((\n chunk: string | Uint8Array,\n encodingOrCallback?: BufferEncoding | ((error?: Error | null) => void),\n callback?: (error?: Error | null) => void,\n ) => {\n if (!this.#isWritingFrame) {\n this.#externalWriteSinceLastFrame = true;\n }\n\n return this.#originalWrite(chunk, encodingOrCallback, callback);\n }) as TerminalFrameOutput['write'];\n }\n\n present(frame: string) {\n const nextFrame = snapshotFrame(frame);\n const update =\n this.#previousFrame && !this.#externalWriteSinceLastFrame\n ? diffFrame(this.#previousFrame, nextFrame)\n : `${cursorHome}${clearScreen}${frame}`;\n\n this.#previousFrame = nextFrame;\n this.#externalWriteSinceLastFrame = false;\n\n if (update.length === 0) {\n return;\n }\n\n this.#writeUpdate(update);\n }\n\n reset() {\n this.#previousFrame = undefined;\n }\n\n #writeUpdate(update: string) {\n this.#isWritingFrame = true;\n\n try {\n if (!this.#useSynchronizedUpdates) {\n this.#originalWrite(update);\n return;\n }\n\n this.#originalWrite(`${synchronizeStart}${update}${synchronizeEnd}`);\n } finally {\n this.#isWritingFrame = false;\n }\n }\n}\n\nfunction snapshotFrame(frame: string): FrameSnapshot {\n return { lines: frame.split('\\n') };\n}\n\nfunction diffFrame(previousFrame: FrameSnapshot, nextFrame: FrameSnapshot) {\n let output = '';\n const lineCount = Math.max(\n previousFrame.lines.length,\n nextFrame.lines.length,\n );\n\n for (let index = 0; index < lineCount; index++) {\n const line = nextFrame.lines[index];\n\n if (previousFrame.lines[index] === line) {\n continue;\n }\n\n output += `${escape}[${index + 1};1H${clearLine}${line ?? ''}`;\n }\n\n return output;\n}\n","import type {\n AgentTUIStreamResult,\n AgentTUIToolApprovalRequest,\n AgentTUIToolApprovalResponse,\n} from '../agent-tui-runner';\nimport type {\n ResponseStatisticsMode,\n TerminalPartDisplayMode,\n} from '../run-agent-tui';\nimport { renderScreenViewport, sliceVisible, visibleLength } from './layout';\nimport { renderMarkdown } from './markdown';\nimport { TerminalFrameBuffer } from './terminal-frame-buffer';\nimport {\n getToolName,\n isToolUIPart,\n readUIMessageStream,\n type StepResultPerformance,\n type DynamicToolUIPart,\n type ToolUIPart,\n type UIMessage,\n type UIMessageChunk,\n} from 'ai';\n\nexport type TerminalInput = {\n isTTY?: boolean;\n on(event: 'data', listener: (chunk: Buffer) => void): TerminalInput;\n off(event: 'data', listener: (chunk: Buffer) => void): TerminalInput;\n resume(): TerminalInput;\n pause(): TerminalInput;\n setRawMode?: (mode: boolean) => TerminalInput;\n};\n\nexport type TerminalOutput = {\n columns?: number;\n rows?: number;\n write(\n chunk: string | Uint8Array,\n encodingOrCallback?: BufferEncoding | ((error?: Error | null) => void),\n callback?: (error?: Error | null) => void,\n ): boolean;\n on(event: 'resize', listener: () => void): TerminalOutput;\n off(event: 'resize', listener: () => void): TerminalOutput;\n};\n\nconst defaultResponseStatistics: ResponseStatisticsMode =\n 'outputTokensPerSecond';\n\nexport type TerminalRendererOptions = {\n input?: TerminalInput;\n output?: TerminalOutput;\n frameBuffer?: TerminalFrameBuffer;\n tools?: TerminalPartDisplayMode;\n reasoning?: TerminalPartDisplayMode;\n responseStatistics?: ResponseStatisticsMode;\n contextSize?: number;\n};\n\nexport type TerminalSessionOptions = {\n title?: string;\n initialPrompt?: string;\n submittedPrompt?: string;\n waitForExit?: boolean;\n continueSession?: boolean;\n tools?: TerminalPartDisplayMode;\n reasoning?: TerminalPartDisplayMode;\n responseStatistics?: ResponseStatisticsMode;\n contextSize?: number;\n};\n\nexport type TerminalKey =\n | { type: 'character'; value: string }\n | { type: 'backspace' }\n | { type: 'enter' }\n | { type: 'up' }\n | { type: 'down' }\n | { type: 'page-up' }\n | { type: 'page-down' }\n | { type: 'ctrl-l' }\n | { type: 'ctrl-c' }\n | { type: 'escape' }\n | { type: 'ignore' };\n\ntype ChatSectionKind = 'user' | 'assistant' | 'reasoning' | 'tool' | 'error';\n\ntype ChatSection = {\n kind: ChatSectionKind;\n title: string;\n rightTitle?: string;\n content: string;\n collapsed?: boolean;\n id?: string;\n cache?: RenderedSectionCache;\n};\n\ntype RenderedSectionCache = {\n width: number;\n kind: ChatSectionKind;\n title: string;\n rightTitle?: string;\n content: string;\n collapsed: boolean;\n lines: string[];\n};\n\ntype StreamUsage = {\n totalTokens?: number | { total?: number };\n inputTokens?: number | { total?: number };\n promptTokens?: number;\n outputTokens?: number | { total?: number };\n completionTokens?: number;\n};\n\ntype MessageMetadataWithStats = {\n usage?: StreamUsage;\n performance?: Pick<StepResultPerformance, 'outputTokensPerSecond'>;\n};\n\nconst colors = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n user: '\\x1b[96m',\n assistant: '\\x1b[92m',\n reasoning: '\\x1b[94m',\n tool: '\\x1b[95m',\n error: '\\x1b[91m',\n};\n\nconst sectionStyles: Record<\n ChatSectionKind,\n { color: string; border: string }\n> = {\n user: { color: colors.user, border: '─' },\n assistant: { color: colors.assistant, border: '─' },\n reasoning: { color: colors.reasoning, border: '·' },\n tool: { color: colors.tool, border: '─' },\n error: { color: colors.error, border: '─' },\n};\n\nconst inputCursorBlinkMs = 500;\nconst activeControls = '↑/↓ · PgUp/PgDn · Esc/Ctrl+C';\nconst doneControls = '↑/↓ · PgUp/PgDn · q/Esc/Ctrl+C';\nconst processingStatus = `Processing input... ${activeControls}`;\nconst processingToolResultsStatus = `Processing tool results... ${activeControls}`;\nconst streamingStatus = `Streaming... ${activeControls}`;\nconst executingToolsStatus = `Executing tools... ${activeControls}`;\n\nexport class TerminalRenderer {\n readonly #input: TerminalInput;\n readonly #output: TerminalOutput;\n readonly #frameBuffer: TerminalFrameBuffer;\n readonly #tools: TerminalPartDisplayMode;\n readonly #reasoning: TerminalPartDisplayMode;\n readonly #responseStatistics: ResponseStatisticsMode;\n readonly #defaultContextSize?: number;\n\n #sections: ChatSection[] = [];\n #inputText = '';\n #inputActive = false;\n #scrollOffset = 0;\n #title = '';\n #status = streamingStatus;\n #isInteractive = false;\n #interrupted = false;\n #totalTokens?: number;\n #contextSize?: number;\n #assistantOutputTokens?: number;\n #assistantOutputTokensPerSecond?: number;\n #inputCursorVisible = true;\n #inputCursorTimer?: ReturnType<typeof setInterval>;\n #onData?: (chunk: Buffer) => void;\n #onResize?: () => void;\n #resolveStreamInterrupt?: () => void;\n\n constructor(options?: TerminalRendererOptions) {\n this.#input = options?.input ?? process.stdin;\n this.#output = options?.output ?? process.stdout;\n this.#frameBuffer =\n options?.frameBuffer ?? new TerminalFrameBuffer(this.#output);\n this.#tools = options?.tools ?? 'auto-collapsed';\n this.#reasoning = options?.reasoning ?? 'auto-collapsed';\n this.#responseStatistics =\n options?.responseStatistics ?? defaultResponseStatistics;\n this.#defaultContextSize = options?.contextSize;\n this.#contextSize = options?.contextSize;\n }\n\n async readPrompt(options?: TerminalSessionOptions): Promise<string> {\n this.#start(options);\n this.#inputActive = true;\n this.#inputText = options?.initialPrompt ?? '';\n this.#status = `Type a prompt and press Enter · ${activeControls}`;\n this.#startInputCursorBlink();\n this.#paint();\n\n return await new Promise((resolve, reject) => {\n this.#onData = chunk => {\n const key = parseKey(chunk);\n\n switch (key.type) {\n case 'character':\n this.#inputText += key.value;\n this.#showInputCursor();\n this.#paint();\n break;\n case 'backspace':\n this.#inputText = this.#inputText.slice(0, -1);\n this.#showInputCursor();\n this.#paint();\n break;\n case 'enter': {\n const prompt = this.#inputText;\n this.#inputActive = false;\n this.#stopInputCursorBlink();\n this.#status = processingStatus;\n this.#addUserSection(prompt);\n this.#inputText = '';\n this.#paint();\n this.#detachInput();\n resolve(prompt);\n break;\n }\n case 'up':\n case 'down':\n this.#handleScroll(key.type);\n break;\n case 'page-up':\n case 'page-down':\n this.#handlePageScroll(key.type);\n break;\n case 'ctrl-l':\n this.#repaint();\n break;\n case 'escape':\n case 'ctrl-c':\n this.#stopInputCursorBlink();\n this.#stop();\n reject(interruptedError());\n break;\n case 'ignore':\n break;\n }\n };\n\n this.#attachInput();\n });\n }\n\n async renderStream(\n result: AgentTUIStreamResult,\n options?: TerminalSessionOptions,\n ): Promise<UIMessage | undefined> {\n this.#start(options);\n this.#inputActive = false;\n this.#status = processingStatus;\n this.#addSubmittedPrompt(options?.submittedPrompt);\n this.#interrupted = false;\n this.#totalTokens = undefined;\n this.#assistantOutputTokens = undefined;\n this.#assistantOutputTokensPerSecond = undefined;\n const displayModes = {\n tools: options?.tools ?? this.#tools,\n reasoning: options?.reasoning ?? this.#reasoning,\n responseStatistics:\n options?.responseStatistics ?? this.#responseStatistics,\n };\n this.#paint();\n const streamInterrupted = new Promise<void>(resolve => {\n this.#resolveStreamInterrupt = resolve;\n });\n this.#onData = chunk => this.#handleStreamingKey(chunk);\n this.#attachInput();\n let responseMessage: UIMessage | undefined;\n const stream = toReadableStream(\n this.#observeUIMessageStream(result.uiMessageStream),\n );\n\n try {\n const messages = readUIMessageStream({\n message: result.message,\n stream,\n onError: error =>\n this.#addErrorSection('Error', formatStreamError(error)),\n });\n\n for await (const message of takeUntil(messages, streamInterrupted)) {\n if (this.#interrupted) {\n break;\n }\n\n responseMessage = message;\n this.#renderAssistantMessage(message, displayModes);\n }\n\n if (\n !this.#interrupted &&\n responseMessage &&\n this.#assistantOutputTokens != null\n ) {\n this.#renderAssistantMessage(responseMessage, displayModes);\n }\n } finally {\n this.#resolveStreamInterrupt = undefined;\n if (this.#interrupted) {\n result.abort?.();\n }\n this.#detachInput();\n this.#status = this.#interrupted\n ? 'Interrupted'\n : options?.continueSession\n ? `Done · Enter another prompt · ${activeControls}`\n : `Done · ${doneControls}`;\n this.#paint();\n await this.#waitForExit(options);\n\n if (this.#interrupted || !options?.continueSession) {\n this.#stop();\n }\n }\n\n if (this.#interrupted) {\n throw interruptedError();\n }\n\n return responseMessage;\n }\n\n async readToolApproval(\n request: AgentTUIToolApprovalRequest,\n options?: TerminalSessionOptions,\n ): Promise<AgentTUIToolApprovalResponse> {\n this.#start(options);\n this.#inputActive = false;\n this.#status = `Approve ${formatToolApprovalTitle(request)}? y/n · ${activeControls}`;\n this.#interrupted = false;\n this.#paint();\n\n return await new Promise((resolve, reject) => {\n this.#onData = chunk => {\n const key = parseKey(chunk);\n\n switch (key.type) {\n case 'character': {\n const value = key.value.toLowerCase();\n\n if (value === 'y') {\n this.#status = `Approved · ${processingStatus}`;\n this.#detachInput();\n this.#paint();\n resolve({ approved: true });\n } else if (value === 'n') {\n this.#status = `Denied · ${processingStatus}`;\n this.#detachInput();\n this.#paint();\n resolve({ approved: false, reason: 'Denied by user.' });\n }\n break;\n }\n case 'up':\n case 'down':\n this.#handleScroll(key.type);\n break;\n case 'page-up':\n case 'page-down':\n this.#handlePageScroll(key.type);\n break;\n case 'ctrl-l':\n this.#repaint();\n break;\n case 'escape':\n case 'ctrl-c':\n this.#interrupted = true;\n this.#stop();\n reject(interruptedError());\n break;\n default:\n break;\n }\n };\n\n this.#attachInput();\n });\n }\n\n #start(options?: TerminalSessionOptions) {\n this.#title = options?.title ?? this.#title;\n this.#contextSize = options?.contextSize ?? this.#defaultContextSize;\n\n if (this.#isInteractive) {\n return;\n }\n\n this.#isInteractive = true;\n this.#frameBuffer.reset();\n this.#output.write('\\x1b[?1049h\\x1b[?25l');\n\n if (this.#input.isTTY) {\n this.#input.setRawMode?.(true);\n this.#input.resume();\n }\n\n this.#onResize = () => this.#repaint();\n this.#output.on('resize', this.#onResize);\n }\n\n #stop() {\n this.#detachInput();\n this.#stopInputCursorBlink();\n\n if (!this.#isInteractive) {\n return;\n }\n\n if (this.#input.isTTY) {\n this.#input.setRawMode?.(false);\n this.#input.pause();\n }\n\n if (this.#onResize) {\n this.#output.off('resize', this.#onResize);\n this.#onResize = undefined;\n }\n\n this.#output.write('\\x1b[?25h\\x1b[?1049l');\n this.#frameBuffer.reset();\n this.#isInteractive = false;\n }\n\n #attachInput() {\n if (this.#onData) {\n this.#input.on('data', this.#onData);\n }\n }\n\n #detachInput() {\n if (this.#onData) {\n this.#input.off('data', this.#onData);\n this.#onData = undefined;\n }\n }\n\n #handleStreamingKey(chunk: Buffer) {\n const key = parseKey(chunk);\n\n switch (key.type) {\n case 'up':\n case 'down':\n this.#handleScroll(key.type);\n break;\n case 'page-up':\n case 'page-down':\n this.#handlePageScroll(key.type);\n break;\n case 'ctrl-l':\n this.#repaint();\n break;\n case 'escape':\n case 'ctrl-c':\n this.#interrupted = true;\n this.#resolveStreamInterrupt?.();\n break;\n default:\n break;\n }\n }\n\n #handleScroll(direction: 'up' | 'down', lines = 1) {\n const delta = direction === 'up' ? lines : -lines;\n this.#scrollOffset = this.#clampScrollOffset(this.#scrollOffset + delta);\n this.#paint();\n }\n\n #handlePageScroll(direction: 'page-up' | 'page-down') {\n this.#handleScroll(\n direction === 'page-up' ? 'up' : 'down',\n this.#bodyContentHeight(),\n );\n }\n\n #startInputCursorBlink() {\n this.#stopInputCursorBlink();\n this.#showInputCursor();\n this.#inputCursorTimer = setInterval(() => {\n this.#inputCursorVisible = !this.#inputCursorVisible;\n this.#paint();\n }, inputCursorBlinkMs);\n this.#inputCursorTimer.unref?.();\n }\n\n #stopInputCursorBlink() {\n if (this.#inputCursorTimer) {\n clearInterval(this.#inputCursorTimer);\n this.#inputCursorTimer = undefined;\n }\n\n this.#inputCursorVisible = true;\n }\n\n #showInputCursor() {\n this.#inputCursorVisible = true;\n }\n\n #addSubmittedPrompt(prompt: string | undefined) {\n if (prompt == null) {\n return;\n }\n\n const section = this.#sections.at(-1);\n\n if (section?.kind === 'user' && section.content === prompt) {\n return;\n }\n\n this.#addUserSection(prompt);\n }\n\n #addUserSection(prompt: string) {\n const previousBodyLineCount = this.#bodyLineCount();\n this.#sections.push({ kind: 'user', title: 'User', content: prompt });\n this.#paintAfterBodyChange(previousBodyLineCount);\n }\n\n #renderAssistantMessage(\n message: UIMessage,\n displayModes: {\n tools: TerminalPartDisplayMode;\n reasoning: TerminalPartDisplayMode;\n responseStatistics: ResponseStatisticsMode;\n },\n ) {\n const previousBodyLineCount = this.#bodyLineCount();\n const activeSectionIds = new Set<string>();\n const metadataStats = extractResponseStatisticsFromMetadata(\n message.metadata,\n );\n this.#totalTokens = metadataStats.totalTokens ?? this.#totalTokens;\n this.#assistantOutputTokens =\n metadataStats.outputTokens ?? this.#assistantOutputTokens;\n this.#assistantOutputTokensPerSecond =\n metadataStats.outputTokensPerSecond ??\n this.#assistantOutputTokensPerSecond;\n\n for (const [index, part] of message.parts.entries()) {\n const id = sectionId(message.id, index);\n\n switch (part.type) {\n case 'text': {\n const content = part.text.trim();\n\n if (content.length === 0) {\n break;\n }\n\n activeSectionIds.add(id);\n this.#upsertSection({\n id,\n kind: 'assistant',\n title: 'Assistant',\n rightTitle: formatResponseStatistics(\n {\n totalTokens: this.#totalTokens,\n outputTokens: this.#assistantOutputTokens,\n outputTokensPerSecond: this.#assistantOutputTokensPerSecond,\n },\n displayModes.responseStatistics,\n ),\n content,\n });\n break;\n }\n case 'reasoning': {\n const content = part.text.trim();\n\n if (displayModes.reasoning === 'hidden' || content.length === 0) {\n break;\n }\n\n activeSectionIds.add(id);\n this.#upsertSection({\n id,\n kind: 'reasoning',\n title: 'Reasoning',\n content,\n collapsed: shouldCollapsePart(\n message,\n index,\n displayModes.reasoning,\n displayModes,\n ),\n });\n break;\n }\n default:\n if (isToolUIPart(part)) {\n if (displayModes.tools === 'hidden') {\n break;\n }\n\n activeSectionIds.add(id);\n this.#upsertSection({\n id,\n ...renderToolInvocation(part, {\n mode: displayModes.tools,\n collapsed: shouldCollapsePart(\n message,\n index,\n displayModes.tools,\n displayModes,\n ),\n }),\n });\n }\n break;\n }\n }\n\n this.#removeStaleAssistantSections(message.id, activeSectionIds);\n this.#paintAfterBodyChange(previousBodyLineCount);\n }\n\n #upsertSection(section: ChatSection) {\n const existingSection = section.id\n ? this.#sections.find(candidate => candidate.id === section.id)\n : undefined;\n\n if (existingSection) {\n const cache = existingSection.cache;\n existingSection.kind = section.kind;\n existingSection.title = section.title;\n existingSection.rightTitle = section.rightTitle;\n existingSection.content = section.content;\n existingSection.collapsed = section.collapsed;\n existingSection.cache =\n cache && sectionMatchesCache(section, cache) ? cache : undefined;\n return;\n }\n\n this.#sections.push(section);\n }\n\n #removeStaleAssistantSections(\n messageId: string,\n activeSectionIds: Set<string>,\n ) {\n const prefix = `${messageId}:`;\n this.#sections = this.#sections.filter(\n section =>\n section.id == null ||\n !section.id.startsWith(prefix) ||\n activeSectionIds.has(section.id),\n );\n }\n\n async *#observeUIMessageStream(\n stream: AsyncIterable<UIMessageChunk> | ReadableStream<UIMessageChunk>,\n ): AsyncIterable<UIMessageChunk> {\n let hasPendingToolResults = false;\n\n for await (const chunk of iterateUIMessageStream(stream)) {\n const nextStatus = statusForStreamChunk(chunk, { hasPendingToolResults });\n\n if (chunk.type === 'start-step') {\n hasPendingToolResults = false;\n } else if (finishesToolExecution(chunk)) {\n hasPendingToolResults = true;\n }\n\n if (nextStatus && this.#status !== nextStatus) {\n this.#status = nextStatus;\n this.#paint();\n } else if (\n startsVisibleAssistantStream(chunk) &&\n this.#status !== streamingStatus\n ) {\n this.#status = streamingStatus;\n this.#paint();\n }\n\n if (chunk.type === 'error') {\n this.#addErrorSection('Error', chunk.errorText);\n }\n\n if (chunk.type === 'finish') {\n const stats = extractResponseStatistics(chunk);\n this.#totalTokens = stats.totalTokens;\n this.#assistantOutputTokens = stats.outputTokens;\n this.#assistantOutputTokensPerSecond = stats.outputTokensPerSecond;\n }\n\n yield chunk;\n }\n }\n\n #addErrorSection(title: string, content: string) {\n const previousBodyLineCount = this.#bodyLineCount();\n this.#sections.push({ kind: 'error', title, content });\n this.#paintAfterBodyChange(previousBodyLineCount);\n }\n\n #paintAfterBodyChange(previousBodyLineCount: number) {\n if (this.#scrollOffset !== 0) {\n const bodyLineDelta = this.#bodyLineCount() - previousBodyLineCount;\n this.#scrollOffset = this.#clampScrollOffset(\n this.#scrollOffset + bodyLineDelta,\n );\n }\n\n this.#paint();\n }\n\n #paint() {\n const frame = renderScreenViewport({\n width: this.#width(),\n height: this.#height(),\n title: this.#title,\n rightTitle: formatTokenCount(this.#totalTokens, this.#contextSize),\n visibleBodyLines: this.#visibleBodyLines(),\n input: this.#inputText,\n inputActive: this.#inputActive,\n inputCursorVisible: this.#inputCursorVisible,\n status: this.#status,\n });\n\n this.#frameBuffer.present(frame);\n }\n\n #repaint() {\n this.#frameBuffer.reset();\n this.#paint();\n }\n\n #visibleBodyLines() {\n if (this.#sections.length === 0) {\n return ['Waiting for input...'];\n }\n\n const bodyContentHeight = this.#bodyContentHeight();\n const totalLineCount = this.#bodyLineCount();\n const start = Math.max(\n 0,\n totalLineCount - bodyContentHeight - this.#scrollOffset,\n );\n const end = start + bodyContentHeight;\n const visibleLines: string[] = [];\n let sectionStart = 0;\n\n for (const section of this.#sections) {\n const sectionLines = renderSectionLines(section, this.#width() - 4);\n const sectionEnd = sectionStart + sectionLines.length;\n\n if (sectionEnd > start && sectionStart < end) {\n visibleLines.push(\n ...sectionLines.slice(\n Math.max(0, start - sectionStart),\n end - sectionStart,\n ),\n );\n }\n\n if (visibleLines.length >= bodyContentHeight) {\n break;\n }\n\n sectionStart = sectionEnd;\n }\n\n return visibleLines;\n }\n\n #clampScrollOffset(scrollOffset: number) {\n const maxScrollOffset = Math.max(\n 0,\n this.#bodyLineCount() - this.#bodyContentHeight(),\n );\n\n return Math.min(Math.max(0, scrollOffset), maxScrollOffset);\n }\n\n #bodyLineCount() {\n if (this.#sections.length === 0) {\n return 1;\n }\n\n let count = 0;\n for (const section of this.#sections) {\n count += renderSectionLines(section, this.#width() - 4).length;\n }\n\n return count;\n }\n\n #bodyContentHeight() {\n return Math.max(1, this.#height() - 5);\n }\n\n #width() {\n return Math.max(20, this.#output.columns ?? 80);\n }\n\n #height() {\n return Math.max(8, this.#output.rows ?? 24);\n }\n\n async #waitForExit(options?: TerminalSessionOptions) {\n if (\n options?.waitForExit === false ||\n !this.#input.isTTY ||\n this.#interrupted\n ) {\n return;\n }\n\n await new Promise<void>(resolve => {\n this.#onData = chunk => {\n const key = parseKey(chunk);\n\n switch (key.type) {\n case 'up':\n case 'down':\n this.#handleScroll(key.type);\n break;\n case 'page-up':\n case 'page-down':\n this.#handlePageScroll(key.type);\n break;\n case 'ctrl-l':\n this.#repaint();\n break;\n case 'escape':\n this.#detachInput();\n resolve();\n break;\n case 'character':\n if (key.value === 'q') {\n this.#detachInput();\n resolve();\n }\n break;\n case 'ctrl-c':\n this.#detachInput();\n process.exitCode = 130;\n resolve();\n break;\n default:\n break;\n }\n };\n\n this.#attachInput();\n });\n }\n}\n\nfunction interruptedError() {\n return new Error('Interrupted');\n}\n\nasync function* takeUntil<T>(\n source: AsyncIterable<T>,\n stop: Promise<void>,\n): AsyncIterable<T> {\n const iterator = source[Symbol.asyncIterator]();\n const stopped = stop.then(\n () => ({ done: true, value: undefined as T }) satisfies IteratorResult<T>,\n );\n\n while (true) {\n const nextValue = await Promise.race([iterator.next(), stopped]);\n\n if (nextValue.done) {\n break;\n }\n\n yield nextValue.value;\n }\n}\n\nfunction formatStreamError(error: unknown) {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n return JSON.stringify(error);\n}\n\nfunction renderToolInvocation(\n part: ToolUIPart | DynamicToolUIPart,\n options: {\n mode: Exclude<TerminalPartDisplayMode, 'hidden'>;\n collapsed: boolean;\n },\n): ChatSection {\n const toolName = getToolName(part);\n const title = `Tool · ${part.title ?? toolName}`;\n const input = 'input' in part ? part.input : undefined;\n const inputText =\n input === undefined\n ? 'Input: (streaming...)'\n : `Input:\\n${formatValue(input)}`;\n const status = toolStatus(part);\n\n if (options.collapsed) {\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: '',\n collapsed: true,\n };\n }\n\n switch (part.state) {\n case 'input-streaming':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: inputText,\n };\n case 'input-available':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: inputText,\n };\n case 'approval-requested':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: inputText,\n };\n case 'approval-responded':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: inputText,\n };\n case 'output-available':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: `${inputText}\\n\\nOutput:\\n${formatValue(part.output)}`,\n };\n case 'output-error':\n return {\n kind: 'error',\n title: `Tool Error · ${part.title ?? toolName}`,\n rightTitle: status,\n content: `${inputText}\\n\\nError:\\n${part.errorText}`,\n };\n case 'output-denied':\n return {\n kind: 'error',\n title: `Tool Denied · ${part.title ?? toolName}`,\n rightTitle: status,\n content: `${inputText}\\n\\nReason: ${part.approval.reason ?? 'denied'}`,\n };\n }\n}\n\nfunction shouldCollapsePart(\n message: UIMessage,\n partIndex: number,\n mode: TerminalPartDisplayMode,\n displayModes: {\n tools: TerminalPartDisplayMode;\n reasoning: TerminalPartDisplayMode;\n },\n) {\n switch (mode) {\n case 'collapsed':\n return true;\n case 'auto-collapsed':\n return message.parts\n .slice(partIndex + 1)\n .some(part => isVisibleAssistantPart(part, displayModes));\n case 'full':\n case 'hidden':\n return false;\n }\n}\n\nfunction isVisibleAssistantPart(\n part: UIMessage['parts'][number],\n displayModes: {\n tools: TerminalPartDisplayMode;\n reasoning: TerminalPartDisplayMode;\n },\n) {\n switch (part.type) {\n case 'text':\n return part.text.trim().length > 0;\n case 'reasoning':\n return displayModes.reasoning !== 'hidden' && part.text.trim().length > 0;\n default:\n return isToolUIPart(part) && displayModes.tools !== 'hidden';\n }\n}\n\nfunction startsVisibleAssistantStream(chunk: UIMessageChunk) {\n switch (chunk.type) {\n case 'text-start':\n case 'text-delta':\n case 'reasoning-start':\n case 'reasoning-delta':\n case 'tool-input-start':\n case 'tool-input-delta':\n return true;\n default:\n return false;\n }\n}\n\nfunction statusForStreamChunk(\n chunk: UIMessageChunk,\n { hasPendingToolResults }: { hasPendingToolResults: boolean },\n) {\n switch (chunk.type) {\n case 'start-step':\n return hasPendingToolResults\n ? processingToolResultsStatus\n : processingStatus;\n case 'tool-output-available':\n case 'tool-output-error':\n case 'tool-output-denied':\n return processingToolResultsStatus;\n case 'tool-input-available':\n return executingToolsStatus;\n case 'tool-approval-response':\n return chunk.approved ? executingToolsStatus : undefined;\n default:\n return undefined;\n }\n}\n\nfunction finishesToolExecution(chunk: UIMessageChunk) {\n switch (chunk.type) {\n case 'tool-output-available':\n case 'tool-output-error':\n case 'tool-output-denied':\n return true;\n default:\n return false;\n }\n}\n\nfunction toolStatus(part: ToolUIPart | DynamicToolUIPart) {\n switch (part.state) {\n case 'input-streaming':\n return 'waiting';\n case 'approval-requested':\n return 'approval requested';\n case 'input-available':\n return 'executing';\n case 'approval-responded':\n return part.approval.approved ? 'executing' : 'denied';\n case 'output-available':\n case 'output-error':\n return 'done';\n case 'output-denied':\n return 'denied';\n }\n}\n\nfunction formatValue(value: unknown) {\n if (typeof value === 'string') {\n return value;\n }\n\n return JSON.stringify(value, null, 2);\n}\n\nfunction formatToolApprovalTitle(request: AgentTUIToolApprovalRequest) {\n return `tool ${request.title ?? request.toolName}`;\n}\n\nfunction sectionId(messageId: string, partIndex: number) {\n return `${messageId}:${partIndex}`;\n}\n\nfunction toReadableStream(\n stream: AsyncIterable<UIMessageChunk> | ReadableStream<UIMessageChunk>,\n): ReadableStream<UIMessageChunk> {\n if (stream instanceof ReadableStream) {\n return stream;\n }\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const chunk of stream) {\n controller.enqueue(chunk);\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n}\n\nasync function* iterateUIMessageStream(\n stream: AsyncIterable<UIMessageChunk> | ReadableStream<UIMessageChunk>,\n): AsyncIterable<UIMessageChunk> {\n if (stream instanceof ReadableStream) {\n const reader = stream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n return;\n }\n\n yield value;\n }\n } finally {\n reader.releaseLock();\n }\n\n return;\n }\n\n yield* stream;\n}\n\nfunction renderSectionLines(section: ChatSection, width: number) {\n if (section.cache && sectionMatchesCache(section, section.cache, width)) {\n return section.cache.lines;\n }\n\n const lines = createSectionLines(section, width);\n section.cache = {\n width,\n kind: section.kind,\n title: section.title,\n rightTitle: section.rightTitle,\n content: section.content,\n collapsed: section.collapsed === true,\n lines,\n };\n\n return lines;\n}\n\nfunction sectionMatchesCache(\n section: ChatSection,\n cache: RenderedSectionCache,\n width = cache.width,\n) {\n return (\n cache.width === width &&\n cache.kind === section.kind &&\n cache.title === section.title &&\n cache.rightTitle === section.rightTitle &&\n cache.content === section.content &&\n cache.collapsed === (section.collapsed === true)\n );\n}\n\nfunction createSectionLines(section: ChatSection, width: number) {\n const style = sectionStyles[section.kind];\n const contentWidth = Math.max(1, width - 4);\n const title = ` ${section.title} `;\n const rightTitle = section.rightTitle ? ` ${section.rightTitle} ` : '';\n\n if (section.collapsed) {\n const borderWidth = Math.max(\n 0,\n width - 2 - title.length - rightTitle.length,\n );\n const top = `${style.color}╭${title}${style.border.repeat(borderWidth)}${rightTitle}╮${colors.reset}`;\n const bottom = `${style.color}╰${style.border.repeat(Math.max(0, width - 2))}╯${colors.reset}`;\n\n return [top, bottom];\n }\n\n const borderWidth = Math.max(0, width - 2 - title.length - rightTitle.length);\n const top = `${style.color}╭${title}${style.border.repeat(borderWidth)}${rightTitle}╮${colors.reset}`;\n const bottom = `${style.color}╰${style.border.repeat(Math.max(0, width - 2))}╯${colors.reset}`;\n const content =\n section.content.length > 0\n ? renderMarkdown(section.content)\n : colors.dim + '(streaming...)' + colors.reset;\n const lines = content\n .split('\\n')\n .flatMap(line => wrapVisibleLine(line, contentWidth));\n\n return [\n top,\n ...lines.map(line => sectionLine(line, contentWidth, style.color)),\n bottom,\n ];\n}\n\nfunction sectionLine(line: string, contentWidth: number, color: string) {\n const visible = sliceVisible(line, contentWidth);\n const padding = ' '.repeat(\n Math.max(0, contentWidth - visibleLength(visible)),\n );\n\n return `${color}│${colors.reset} ${visible}${padding} ${color}│${colors.reset}`;\n}\n\nfunction wrapVisibleLine(line: string, width: number): string[] {\n if (line.length === 0) {\n return [''];\n }\n\n const lines: string[] = [];\n let remaining = line;\n\n while (visibleLength(remaining) > width) {\n const breakAt = findVisibleBreakPoint(remaining, width);\n lines.push(remaining.slice(0, breakAt).trimEnd());\n remaining = remaining.slice(breakAt).trimStart();\n }\n\n lines.push(remaining);\n return lines;\n}\n\nfunction findVisibleBreakPoint(input: string, width: number) {\n const slice = sliceVisible(input, width + 1);\n const lastSpace = slice.lastIndexOf(' ');\n\n if (lastSpace > 0) {\n return lastSpace;\n }\n\n return sliceVisible(input, width).length;\n}\n\nfunction extractResponseStatistics(chunk: UIMessageChunk) {\n const usage =\n 'usage' in chunk ? (chunk.usage as StreamUsage | undefined) : undefined;\n const metadataUsage =\n 'messageMetadata' in chunk\n ? (chunk.messageMetadata as MessageMetadataWithStats | undefined)?.usage\n : undefined;\n const metadataPerformance =\n 'messageMetadata' in chunk\n ? (chunk.messageMetadata as MessageMetadataWithStats | undefined)\n ?.performance\n : undefined;\n\n return {\n totalTokens: extractTotalTokenCountFromUsage(usage ?? metadataUsage),\n outputTokens: extractOutputTokenCountFromUsage(usage ?? metadataUsage),\n outputTokensPerSecond: metadataPerformance?.outputTokensPerSecond,\n };\n}\n\nfunction extractResponseStatisticsFromMetadata(metadata: unknown) {\n const stats = metadata as MessageMetadataWithStats | undefined;\n\n return {\n totalTokens: extractTotalTokenCountFromUsage(stats?.usage),\n outputTokens: extractOutputTokenCountFromUsage(stats?.usage),\n outputTokensPerSecond: stats?.performance?.outputTokensPerSecond,\n };\n}\n\nfunction extractTotalTokenCountFromUsage(usage: StreamUsage | undefined) {\n const totalTokens = usage?.totalTokens;\n\n if (typeof totalTokens === 'number') {\n return totalTokens;\n }\n\n if (typeof totalTokens?.total === 'number') {\n return totalTokens.total;\n }\n\n const inputTokens = extractInputTokenCountFromUsage(usage);\n const outputTokens = extractOutputTokenCountFromUsage(usage);\n\n if (inputTokens != null && outputTokens != null) {\n return inputTokens + outputTokens;\n }\n\n return undefined;\n}\n\nfunction extractInputTokenCountFromUsage(usage: StreamUsage | undefined) {\n const inputTokens = usage?.inputTokens;\n\n if (typeof inputTokens === 'number') {\n return inputTokens;\n }\n\n if (typeof inputTokens?.total === 'number') {\n return inputTokens.total;\n }\n\n return usage?.promptTokens;\n}\n\nfunction extractOutputTokenCountFromUsage(usage: StreamUsage | undefined) {\n const outputTokens = usage?.outputTokens;\n\n if (typeof outputTokens === 'number') {\n return outputTokens;\n }\n\n if (typeof outputTokens?.total === 'number') {\n return outputTokens.total;\n }\n\n return usage?.completionTokens;\n}\n\nfunction formatTokenCount(tokens: number | undefined, contextSize?: number) {\n if (tokens == null) {\n return undefined;\n }\n\n const tokenCount = `${tokens.toLocaleString()} ${tokens === 1 ? 'token' : 'tokens'}`;\n const contextPercentage = formatContextPercentage(tokens, contextSize);\n\n return contextPercentage == null\n ? tokenCount\n : `${tokenCount} ${contextPercentage}`;\n}\n\nfunction formatContextPercentage(\n tokens: number,\n contextSize: number | undefined,\n) {\n if (\n contextSize == null ||\n contextSize <= 0 ||\n !Number.isFinite(contextSize)\n ) {\n return undefined;\n }\n\n return `${Math.round((tokens / contextSize) * 100).toLocaleString()}%`;\n}\n\nfunction formatResponseStatistics(\n stats: {\n totalTokens: number | undefined;\n outputTokens: number | undefined;\n outputTokensPerSecond: number | undefined;\n },\n mode: ResponseStatisticsMode,\n) {\n if (mode === 'outputTokensPerSecond') {\n return formatOutputTokensPerSecond(stats.outputTokensPerSecond);\n }\n\n return formatTokenCount(stats.outputTokens);\n}\n\nfunction formatOutputTokensPerSecond(\n outputTokensPerSecond: number | undefined,\n) {\n if (outputTokensPerSecond == null) {\n return undefined;\n }\n\n return `${formatNumber(outputTokensPerSecond)} tok/s`;\n}\n\nfunction formatNumber(value: number) {\n return Number.isInteger(value)\n ? value.toLocaleString()\n : value.toLocaleString(undefined, { maximumFractionDigits: 1 });\n}\n\nexport function parseKey(chunk: Buffer): TerminalKey {\n const value = chunk.toString('utf8');\n\n switch (value) {\n case '\\u000c':\n return { type: 'ctrl-l' };\n case '\\u0003':\n return { type: 'ctrl-c' };\n case '\\x1B':\n return { type: 'escape' };\n case '\\r':\n case '\\n':\n return { type: 'enter' };\n case '\\u007f':\n case '\\b':\n return { type: 'backspace' };\n case '\\x1B[A':\n return { type: 'up' };\n case '\\x1B[B':\n return { type: 'down' };\n case '\\x1B[5~':\n return { type: 'page-up' };\n case '\\x1B[6~':\n return { type: 'page-down' };\n default:\n if (value >= ' ' && value !== '\\x7F') {\n return { type: 'character', value };\n }\n\n return { type: 'ignore' };\n }\n}\n","import type {\n AgentTUIAgent,\n ResponseStatisticsMode,\n RunAgentTUIOptions,\n TerminalPartDisplayMode,\n} from './run-agent-tui';\nimport {\n TerminalRenderer,\n type TerminalInput,\n type TerminalOutput,\n} from './tui/terminal-renderer';\nimport {\n convertToModelMessages,\n getToolName,\n isToolUIPart,\n type StepResultPerformance,\n type Experimental_SandboxSession,\n type LanguageModelUsage,\n type TextStreamPart,\n type ToolSet,\n type UIMessage,\n type UIMessageChunk,\n} from 'ai';\n\nconst defaultResponseStatistics: ResponseStatisticsMode =\n 'outputTokensPerSecond';\n\nexport type AgentTUIStreamResult = {\n uiMessageStream:\n | AsyncIterable<UIMessageChunk>\n | ReadableStream<UIMessageChunk>;\n message?: UIMessage;\n abort?: () => void;\n};\n\nexport type AgentTUIStreamOptions = {\n messages: UIMessage[];\n};\n\nexport type AgentTUISessionOptions = {\n title?: string;\n initialPrompt?: string;\n submittedPrompt?: string;\n waitForExit?: boolean;\n continueSession?: boolean;\n tools?: TerminalPartDisplayMode;\n reasoning?: TerminalPartDisplayMode;\n responseStatistics?: ResponseStatisticsMode;\n contextSize?: number;\n};\n\nexport type AgentTUIToolApprovalRequest = {\n approvalId: string;\n toolCallId: string;\n toolName: string;\n title?: string;\n input: unknown;\n providerExecuted?: boolean;\n messageId: string;\n partIndex: number;\n};\n\nexport type AgentTUIToolApprovalResponse = {\n approved: boolean;\n reason?: string;\n};\n\nexport type AgentTUIRenderer = {\n readPrompt?(options?: AgentTUISessionOptions): Promise<string | undefined>;\n readToolApproval?(\n request: AgentTUIToolApprovalRequest,\n options?: AgentTUISessionOptions,\n ): Promise<AgentTUIToolApprovalResponse>;\n renderStream(\n result: AgentTUIStreamResult,\n options?: AgentTUISessionOptions,\n ): Promise<UIMessage | undefined>;\n};\n\nexport type AgentTUIRunnerOptions<\n TAgent extends AgentTUIAgent = AgentTUIAgent,\n> = Omit<RunAgentTUIOptions, 'agent'> & {\n agent: TAgent;\n renderer?: AgentTUIRenderer;\n screen?: TerminalOutput;\n userInput?: TerminalInput;\n};\n\nexport class AgentTUIRunner<TAgent extends AgentTUIAgent = AgentTUIAgent> {\n private readonly agent: TAgent;\n private readonly renderer: AgentTUIRenderer;\n private readonly title?: string;\n private readonly tools: TerminalPartDisplayMode;\n private readonly reasoning: TerminalPartDisplayMode;\n private readonly responseStatistics: ResponseStatisticsMode;\n private readonly contextSize?: number;\n private readonly sandbox?: Experimental_SandboxSession;\n\n constructor(options: AgentTUIRunnerOptions<TAgent>) {\n this.agent = options.agent;\n this.renderer = createRenderer(options) ?? createDefaultRenderer(options);\n this.title = options.title;\n this.tools = options.tools ?? 'auto-collapsed';\n this.reasoning = options.reasoning ?? 'auto-collapsed';\n this.responseStatistics =\n options.responseStatistics ?? defaultResponseStatistics;\n this.contextSize = options.contextSize;\n this.sandbox = options.sandbox;\n }\n\n async run() {\n const title = this.title;\n const messages: UIMessage[] = [];\n let nextMessageIndex = 0;\n const generateMessageId = () => `message-${++nextMessageIndex}`;\n let prompt: string | undefined;\n let hasRunTurn = false;\n let streamWithoutPrompt = false;\n\n while (true) {\n if (!streamWithoutPrompt) {\n if (prompt == null) {\n if (!this.renderer.readPrompt) {\n if (hasRunTurn) {\n return;\n }\n\n throw new Error(\n 'No prompt was provided and the renderer does not support prompt input.',\n );\n }\n\n try {\n prompt = await this.renderer.readPrompt({ title });\n } catch (error) {\n if (isInterruptedError(error)) {\n return;\n }\n\n throw error;\n }\n\n if (prompt == null) {\n return;\n }\n }\n\n messages.push(createUserMessage(generateMessageId(), prompt));\n hasRunTurn = true;\n }\n\n const result = await this.streamMessages(\n [...messages],\n generateMessageId,\n );\n\n try {\n const responseMessage = await this.renderer.renderStream(result, {\n title,\n submittedPrompt: prompt,\n continueSession: Boolean(this.renderer.readPrompt),\n tools: this.tools,\n reasoning: this.reasoning,\n responseStatistics: this.responseStatistics,\n contextSize: this.contextSize,\n waitForExit: false,\n });\n\n if (responseMessage && responseMessage.parts.length > 0) {\n const approvalRequests =\n findPendingToolApprovalRequests(responseMessage);\n\n if (approvalRequests.length > 0) {\n if (!this.renderer.readToolApproval) {\n throw new Error(\n 'Tool approval was requested, but the renderer does not support tool approval input.',\n );\n }\n\n for (const request of approvalRequests) {\n const response = await this.renderer.readToolApproval(request, {\n title,\n });\n applyToolApprovalResponse(responseMessage, request, response);\n }\n\n upsertResponseMessage(\n messages,\n responseMessage,\n streamWithoutPrompt,\n );\n streamWithoutPrompt = true;\n prompt = undefined;\n continue;\n }\n\n upsertResponseMessage(messages, responseMessage, streamWithoutPrompt);\n }\n } catch (error) {\n if (isInterruptedError(error)) {\n return;\n }\n\n throw error;\n }\n streamWithoutPrompt = false;\n prompt = undefined;\n }\n }\n\n private async streamMessages(\n messages: UIMessage[],\n generateMessageId: () => string,\n ): Promise<AgentTUIStreamResult> {\n const abortController = new AbortController();\n const result = await this.agent.stream({\n prompt: await convertToModelMessages(messages, {\n tools: this.agent.tools as ToolSet,\n }),\n abortSignal: abortController.signal,\n options: undefined,\n experimental_sandbox: this.sandbox,\n });\n\n return {\n uiMessageStream: textStreamToUIMessageStream(\n result.fullStream as AsyncIterable<TextStreamPart<ToolSet>>,\n generateMessageId,\n messages,\n ),\n message: lastAssistantMessage(messages),\n abort: () => abortController.abort(),\n };\n }\n}\n\nfunction createDefaultRenderer(options: AgentTUIRunnerOptions) {\n return options.tools === undefined &&\n options.reasoning === undefined &&\n options.responseStatistics === undefined &&\n options.contextSize === undefined\n ? new TerminalRenderer()\n : new TerminalRenderer({\n tools: options.tools,\n reasoning: options.reasoning,\n responseStatistics: options.responseStatistics,\n contextSize: options.contextSize,\n });\n}\n\nfunction createRenderer(\n options: AgentTUIRunnerOptions,\n): AgentTUIRenderer | undefined {\n if (options.renderer) {\n return options.renderer;\n }\n\n if (!options.screen && !options.userInput) {\n return undefined;\n }\n\n return new TerminalRenderer({\n tools: options.tools,\n reasoning: options.reasoning,\n responseStatistics: options.responseStatistics,\n contextSize: options.contextSize,\n input: options.userInput,\n output: options.screen,\n });\n}\n\nasync function* textStreamToUIMessageStream(\n stream: AsyncIterable<TextStreamPart<ToolSet>>,\n generateMessageId: () => string,\n originalMessages: UIMessage[] = [],\n): AsyncIterable<UIMessageChunk> {\n const openTextParts = new Set<string>();\n const openReasoningParts = new Set<string>();\n const openToolCalls = new Set<string>();\n let latestStepUsage: LanguageModelUsage | undefined;\n let latestPerformance: StepResultPerformance | undefined;\n let sentFinish = false;\n\n yield {\n type: 'start',\n messageId:\n lastAssistantMessage(originalMessages)?.id ?? generateMessageId(),\n };\n\n for await (const part of stream) {\n switch (part.type) {\n case 'text-start':\n openTextParts.add(part.id);\n yield {\n type: 'text-start',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'text-delta':\n if (!openTextParts.has(part.id)) {\n openTextParts.add(part.id);\n yield {\n type: 'text-start',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n }\n yield {\n type: 'text-delta',\n id: part.id,\n delta: part.text,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'text-end':\n openTextParts.delete(part.id);\n yield {\n type: 'text-end',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'reasoning-start':\n openReasoningParts.add(part.id);\n yield {\n type: 'reasoning-start',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'reasoning-delta':\n if (!openReasoningParts.has(part.id)) {\n openReasoningParts.add(part.id);\n yield {\n type: 'reasoning-start',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n }\n yield {\n type: 'reasoning-delta',\n id: part.id,\n delta: part.text,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'reasoning-end':\n openReasoningParts.delete(part.id);\n yield {\n type: 'reasoning-end',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'tool-input-start':\n yield {\n type: 'tool-input-start',\n toolCallId: part.id,\n toolName: part.toolName,\n providerExecuted: part.providerExecuted,\n providerMetadata: part.providerMetadata,\n toolMetadata: part.toolMetadata,\n dynamic: part.dynamic,\n title: part.title,\n };\n break;\n case 'tool-input-delta':\n yield {\n type: 'tool-input-delta',\n toolCallId: part.id,\n inputTextDelta: part.delta,\n };\n break;\n case 'tool-call':\n openToolCalls.add(part.toolCallId);\n yield {\n type: 'tool-input-available',\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n input: part.input,\n providerExecuted: part.providerExecuted,\n providerMetadata: part.providerMetadata,\n toolMetadata: part.toolMetadata,\n dynamic: part.dynamic,\n title: part.title,\n };\n break;\n case 'tool-approval-request':\n if (!openToolCalls.has(part.toolCall.toolCallId)) {\n openToolCalls.add(part.toolCall.toolCallId);\n yield {\n type: 'tool-input-available',\n toolCallId: part.toolCall.toolCallId,\n toolName: part.toolCall.toolName,\n input: part.toolCall.input,\n providerExecuted: part.toolCall.providerExecuted,\n providerMetadata: part.toolCall.providerMetadata,\n toolMetadata: part.toolCall.toolMetadata,\n dynamic: part.toolCall.dynamic,\n title: part.toolCall.title,\n };\n }\n yield {\n type: 'tool-approval-request',\n approvalId: part.approvalId,\n toolCallId: part.toolCall.toolCallId,\n isAutomatic: part.isAutomatic,\n };\n break;\n case 'tool-approval-response':\n yield {\n type: 'tool-approval-response',\n approvalId: part.approvalId,\n approved: part.approved,\n reason: part.reason,\n providerExecuted: part.providerExecuted,\n };\n break;\n case 'tool-result':\n yield {\n type: 'tool-output-available',\n toolCallId: part.toolCallId,\n output: part.output,\n providerExecuted: part.providerExecuted,\n providerMetadata: part.providerMetadata,\n toolMetadata: part.toolMetadata,\n dynamic: part.dynamic,\n preliminary: part.preliminary,\n };\n break;\n case 'tool-error':\n yield {\n type: 'tool-output-error',\n toolCallId: part.toolCallId,\n errorText: formatStreamError(part.error),\n providerExecuted: part.providerExecuted,\n providerMetadata: part.providerMetadata,\n toolMetadata: part.toolMetadata,\n dynamic: part.dynamic,\n };\n break;\n case 'tool-output-denied':\n yield { type: 'tool-output-denied', toolCallId: part.toolCallId };\n break;\n case 'source':\n if (part.sourceType === 'url') {\n yield {\n type: 'source-url',\n sourceId: part.id,\n url: part.url,\n title: part.title,\n providerMetadata: part.providerMetadata,\n };\n } else {\n yield {\n type: 'source-document',\n sourceId: part.id,\n mediaType: part.mediaType,\n title: part.title,\n filename: part.filename,\n providerMetadata: part.providerMetadata,\n };\n }\n break;\n case 'file':\n yield {\n type: 'file',\n url: fileToDataUrl(part.file.mediaType, part.file.base64),\n mediaType: part.file.mediaType,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'reasoning-file':\n yield {\n type: 'reasoning-file',\n url: fileToDataUrl(part.file.mediaType, part.file.base64),\n mediaType: part.file.mediaType,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'start-step':\n yield { type: 'start-step' };\n break;\n case 'finish-step':\n latestStepUsage = part.usage;\n latestPerformance = part.performance;\n yield { type: 'finish-step' };\n break;\n case 'finish':\n yield* closeOpenParts(openTextParts, openReasoningParts);\n sentFinish = true;\n yield {\n type: 'finish',\n finishReason: part.finishReason,\n messageMetadata: createResponseMetadata(\n latestStepUsage ?? part.totalUsage,\n latestPerformance,\n ),\n };\n break;\n case 'abort':\n yield { type: 'abort', reason: part.reason };\n break;\n case 'error':\n yield { type: 'error', errorText: formatStreamError(part.error) };\n break;\n }\n }\n\n if (!sentFinish) {\n yield* closeOpenParts(openTextParts, openReasoningParts);\n yield { type: 'finish' };\n }\n}\n\nfunction createResponseMetadata(\n usage: LanguageModelUsage | undefined,\n performance?: StepResultPerformance,\n): ResponseMetadata | undefined {\n if (\n usage?.totalTokens == null &&\n usage?.outputTokens == null &&\n performance?.outputTokensPerSecond == null\n ) {\n return undefined;\n }\n\n return {\n ...(usage?.totalTokens == null && usage?.outputTokens == null\n ? {}\n : {\n usage: {\n ...(usage.totalTokens == null\n ? {}\n : { totalTokens: usage.totalTokens }),\n ...(usage.outputTokens == null\n ? {}\n : { outputTokens: usage.outputTokens }),\n },\n }),\n ...(performance?.outputTokensPerSecond == null\n ? {}\n : {\n performance: {\n outputTokensPerSecond: performance.outputTokensPerSecond,\n },\n }),\n };\n}\n\ntype ResponseMetadata = {\n usage?: {\n totalTokens?: number;\n outputTokens?: number;\n };\n performance?: Pick<StepResultPerformance, 'outputTokensPerSecond'>;\n};\n\nfunction* closeOpenParts(\n textPartIds: Set<string>,\n reasoningPartIds: Set<string>,\n) {\n for (const id of textPartIds) {\n yield { type: 'text-end', id } satisfies UIMessageChunk;\n }\n textPartIds.clear();\n\n for (const id of reasoningPartIds) {\n yield { type: 'reasoning-end', id } satisfies UIMessageChunk;\n }\n reasoningPartIds.clear();\n}\n\nfunction createUserMessage(id: string, text: string): UIMessage {\n return {\n id,\n role: 'user',\n parts: [{ type: 'text', text }],\n };\n}\n\nfunction upsertResponseMessage(\n messages: UIMessage[],\n responseMessage: UIMessage,\n replaceLast: boolean,\n) {\n if (replaceLast && messages.at(-1)?.role === 'assistant') {\n messages[messages.length - 1] = responseMessage;\n return;\n }\n\n messages.push(responseMessage);\n}\n\nfunction lastAssistantMessage(messages: UIMessage[]) {\n const message = messages.at(-1);\n\n return message?.role === 'assistant' ? message : undefined;\n}\n\nfunction findPendingToolApprovalRequests(\n message: UIMessage,\n): AgentTUIToolApprovalRequest[] {\n const requests: AgentTUIToolApprovalRequest[] = [];\n\n for (const [index, part] of message.parts.entries()) {\n if (\n !isToolUIPart(part) ||\n part.state !== 'approval-requested' ||\n part.approval.isAutomatic === true\n ) {\n continue;\n }\n\n requests.push({\n approvalId: part.approval.id,\n toolCallId: part.toolCallId,\n toolName: getToolName(part),\n title: part.title,\n input: part.input,\n providerExecuted: part.providerExecuted,\n messageId: message.id,\n partIndex: index,\n });\n }\n\n return requests;\n}\n\nfunction applyToolApprovalResponse(\n message: UIMessage,\n request: AgentTUIToolApprovalRequest,\n response: AgentTUIToolApprovalResponse,\n) {\n const part = message.parts[request.partIndex];\n\n if (!part || !isToolUIPart(part) || part.toolCallId !== request.toolCallId) {\n throw new Error(\n `Could not find tool approval request ${request.approvalId}.`,\n );\n }\n\n part.state = 'approval-responded';\n part.approval = {\n id: request.approvalId,\n approved: response.approved,\n ...(response.reason ? { reason: response.reason } : {}),\n };\n}\n\nfunction formatStreamError(error: unknown) {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n return JSON.stringify(error);\n}\n\nfunction fileToDataUrl(mediaType: string, base64: string) {\n return `data:${mediaType};base64,${base64}`;\n}\n\nfunction isInterruptedError(error: unknown) {\n return error instanceof Error && error.message === 'Interrupted';\n}\n","import { AgentTUIRunner } from './agent-tui-runner';\nimport type { Agent, Experimental_SandboxSession } from 'ai';\n\n/**\n * Controls how terminal UI sections for stream parts are displayed.\n *\n * - `full`: show the section header and full content.\n * - `collapsed`: show only the section header.\n * - `auto-collapsed`: show the latest section expanded until another visible\n * section appears, then collapse it.\n * - `hidden`: omit the section entirely.\n */\nexport type TerminalPartDisplayMode =\n | 'full'\n | 'collapsed'\n | 'auto-collapsed'\n | 'hidden';\n\n/**\n * Controls which response statistic is shown.\n *\n * - `outputTokenCount`: show the number of output tokens in the response.\n * - `outputTokensPerSecond`: show output token throughput for the response.\n */\nexport type ResponseStatisticsMode =\n | 'outputTokenCount'\n | 'outputTokensPerSecond';\n\n/**\n * An agent that is compatible with the terminal UI.\n */\nexport type AgentTUIAgent = Agent<any, any, any, any>;\n\n/**\n * Options for starting an agent in the default terminal UI.\n */\nexport type RunAgentTUIOptions = {\n /**\n * The agent to run.\n */\n agent: AgentTUIAgent;\n\n /**\n * The title shown in the terminal UI.\n */\n title?: string;\n\n /**\n * How tool calls should render.\n *\n * @default \"auto-collapsed\"\n */\n tools?: TerminalPartDisplayMode;\n\n /**\n * How reasoning parts should render.\n *\n * @default \"auto-collapsed\"\n */\n reasoning?: TerminalPartDisplayMode;\n\n /**\n * Which response statistic to show.\n *\n * @default \"outputTokensPerSecond\"\n */\n responseStatistics?: ResponseStatisticsMode;\n\n /**\n * The model context window size in tokens.\n *\n * When provided, the terminal UI shows the current total token usage as a\n * percentage of this context window.\n */\n contextSize?: number;\n\n /**\n * Sandbox session that is passed through to agent tool execution.\n */\n sandbox?: Experimental_SandboxSession;\n};\n\n/**\n * Runs an agent in the default terminal UI until the user exits.\n */\nexport async function runAgentTUI(options: RunAgentTUIOptions) {\n await new AgentTUIRunner(options).run();\n}\n"],"mappings":"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","names":["borderWidth","top","bottom","getToolName","isToolUIPart","defaultResponseStatistics","formatStreamError"]}
1
+ {"version":3,"sources":["../src/tui/terminal-text.ts","../src/tui/markdown.ts","../src/tui/layout.ts","../src/tui/terminal-frame-buffer.ts","../src/tui/terminal-renderer.ts","../src/agent-tui-runner.ts","../src/run-agent-tui.ts"],"sourcesContent":["const ansiEscape = String.fromCharCode(27);\n\nexport const ansiPattern = new RegExp(`${ansiEscape}\\\\[[0-?]*[ -/]*[@-~]`, 'g');\nexport const ansiPrefixPattern = new RegExp(\n `^${ansiEscape}\\\\[[0-?]*[ -/]*[@-~]`,\n);\n\nexport function stripAnsi(input: string): string {\n return input.replace(ansiPattern, '');\n}\n\nexport function visibleLength(input: string): number {\n let width = 0;\n let index = 0;\n\n while (index < input.length) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (ansiMatch) {\n index += ansiMatch[0].length;\n continue;\n }\n\n const codePoint = input.codePointAt(index);\n\n if (codePoint == null) {\n break;\n }\n\n const character = String.fromCodePoint(codePoint);\n width += codePointWidth(codePoint);\n index += character.length;\n }\n\n return width;\n}\n\nexport function sliceVisible(input: string, width: number): string {\n if (width <= 0) {\n return '';\n }\n\n let output = '';\n let visible = 0;\n let index = 0;\n\n while (index < input.length && visible < width) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (ansiMatch) {\n output += ansiMatch[0];\n index += ansiMatch[0].length;\n continue;\n }\n\n const codePoint = input.codePointAt(index);\n\n if (codePoint == null) {\n break;\n }\n\n const character = String.fromCodePoint(codePoint);\n const characterWidth = codePointWidth(codePoint);\n\n if (characterWidth > 0 && visible + characterWidth > width) {\n break;\n }\n\n output += character;\n index += character.length;\n visible += characterWidth;\n }\n\n while (index < input.length) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (!ansiMatch) {\n break;\n }\n\n output += ansiMatch[0];\n index += ansiMatch[0].length;\n }\n\n return output;\n}\n\nexport function codePointWidth(codePoint: number): number {\n if (codePoint === 0x09) {\n return 4;\n }\n\n if (codePoint < 0x20 || (codePoint >= 0x7f && codePoint < 0xa0)) {\n return 0;\n }\n\n if (isZeroWidthCodePoint(codePoint)) {\n return 0;\n }\n\n return isWideCodePoint(codePoint) ? 2 : 1;\n}\n\nfunction isZeroWidthCodePoint(codePoint: number): boolean {\n return (\n (codePoint >= 0x0300 && codePoint <= 0x036f) ||\n (codePoint >= 0x0483 && codePoint <= 0x0489) ||\n (codePoint >= 0x0591 && codePoint <= 0x05bd) ||\n codePoint === 0x05bf ||\n (codePoint >= 0x05c1 && codePoint <= 0x05c2) ||\n (codePoint >= 0x05c4 && codePoint <= 0x05c5) ||\n codePoint === 0x05c7 ||\n (codePoint >= 0x0610 && codePoint <= 0x061a) ||\n (codePoint >= 0x064b && codePoint <= 0x065f) ||\n codePoint === 0x0670 ||\n (codePoint >= 0x06d6 && codePoint <= 0x06dc) ||\n (codePoint >= 0x06df && codePoint <= 0x06e4) ||\n (codePoint >= 0x06e7 && codePoint <= 0x06e8) ||\n (codePoint >= 0x06ea && codePoint <= 0x06ed) ||\n codePoint === 0x0711 ||\n (codePoint >= 0x0730 && codePoint <= 0x074a) ||\n (codePoint >= 0x07a6 && codePoint <= 0x07b0) ||\n (codePoint >= 0x07eb && codePoint <= 0x07f3) ||\n (codePoint >= 0x0816 && codePoint <= 0x0819) ||\n (codePoint >= 0x081b && codePoint <= 0x0823) ||\n (codePoint >= 0x0825 && codePoint <= 0x0827) ||\n (codePoint >= 0x0829 && codePoint <= 0x082d) ||\n (codePoint >= 0x0859 && codePoint <= 0x085b) ||\n (codePoint >= 0x08d3 && codePoint <= 0x0902) ||\n codePoint === 0x093a ||\n codePoint === 0x093c ||\n (codePoint >= 0x0941 && codePoint <= 0x0948) ||\n codePoint === 0x094d ||\n (codePoint >= 0x0951 && codePoint <= 0x0957) ||\n codePoint === 0x200d ||\n (codePoint >= 0xfe00 && codePoint <= 0xfe0f) ||\n (codePoint >= 0xe0100 && codePoint <= 0xe01ef)\n );\n}\n\nfunction isWideCodePoint(codePoint: number): boolean {\n return (\n codePoint >= 0x1100 &&\n (codePoint <= 0x115f ||\n codePoint === 0x2329 ||\n codePoint === 0x232a ||\n (codePoint >= 0x2e80 && codePoint <= 0xa4cf && codePoint !== 0x303f) ||\n (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||\n (codePoint >= 0xf900 && codePoint <= 0xfaff) ||\n (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||\n (codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||\n (codePoint >= 0xff00 && codePoint <= 0xff60) ||\n (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||\n (codePoint >= 0x1f300 && codePoint <= 0x1f64f) ||\n (codePoint >= 0x1f900 && codePoint <= 0x1f9ff) ||\n (codePoint >= 0x20000 && codePoint <= 0x3fffd))\n );\n}\n","import { visibleLength } from './terminal-text';\n\nexport type MarkdownToken =\n | { type: 'text'; text: string }\n | { type: 'bold'; text: string }\n | { type: 'italic'; text: string }\n | { type: 'code'; text: string };\n\ntype TableAlignment = 'left' | 'center' | 'right';\n\nconst ansi = {\n bold: '\\x1b[1m',\n boldOff: '\\x1b[22m',\n italic: '\\x1b[3m',\n italicOff: '\\x1b[23m',\n};\n\nconst tableSeparator = '─';\n\nexport function renderMarkdown(input: string): string {\n const lines = input.split('\\n');\n const output: string[] = [];\n\n for (let index = 0; index < lines.length; index += 1) {\n const table = parseTable(lines, index);\n\n if (table != null) {\n output.push(...renderTable(table));\n index = table.endIndex - 1;\n continue;\n }\n\n output.push(renderMarkdownLine(lines[index] ?? ''));\n }\n\n return output.join('\\n');\n}\n\nfunction renderMarkdownLine(line: string): string {\n if (line.startsWith('### ')) {\n return renderInlineMarkdown(`▶ ${line.slice(4)}`);\n }\n\n if (line.startsWith('## ')) {\n return renderInlineMarkdown(`■ ${line.slice(3)}`);\n }\n\n if (line.startsWith('# ')) {\n return renderInlineMarkdown(`█ ${line.slice(2)}`);\n }\n\n const unorderedListItem = line.match(/^(\\s*)[-+*]\\s+(.*)$/);\n if (unorderedListItem) {\n const [, indentation, text = ''] = unorderedListItem;\n return renderInlineMarkdown(\n `${indentation}•${text.length > 0 ? ` ${text}` : ''}`,\n );\n }\n\n if (/^\\d+\\. /.test(line)) {\n return renderInlineMarkdown(line.replace(/^(\\d+)\\. /, '$1. '));\n }\n\n if (line.startsWith('> ')) {\n return renderInlineMarkdown(`│ ${line.slice(2)}`);\n }\n\n return renderInlineMarkdown(line);\n}\n\nfunction renderInlineMarkdown(input: string): string {\n return input\n .replace(/`([^`]+)`/g, '$1')\n .replace(/\\*\\*([^*\\n]+)\\*\\*/g, `${ansi.bold}$1${ansi.boldOff}`)\n .replace(/__([^_\\n]+)__/g, `${ansi.bold}$1${ansi.boldOff}`)\n .replace(/\\*([^*\\n]+)\\*/g, `${ansi.italic}$1${ansi.italicOff}`)\n .replace(/_([^_\\n]+)_/g, `${ansi.italic}$1${ansi.italicOff}`);\n}\n\ntype ParsedTable = {\n alignments: TableAlignment[];\n endIndex: number;\n header: string[];\n rows: string[][];\n};\n\nfunction parseTable(\n lines: string[],\n startIndex: number,\n): ParsedTable | undefined {\n const header = parseTableCells(lines[startIndex] ?? '');\n if (header == null || header.length < 2) {\n return undefined;\n }\n\n const separatorCells = parseTableCells(lines[startIndex + 1] ?? '');\n if (separatorCells == null || separatorCells.length !== header.length) {\n return undefined;\n }\n\n const alignments = parseTableAlignments(separatorCells);\n if (alignments == null) {\n return undefined;\n }\n\n const rows: string[][] = [];\n let endIndex = startIndex + 2;\n\n while (endIndex < lines.length) {\n const row = parseTableCells(lines[endIndex] ?? '');\n if (row == null) {\n break;\n }\n\n rows.push(normalizeTableRow(row, header.length));\n endIndex += 1;\n }\n\n return {\n alignments,\n endIndex,\n header,\n rows,\n };\n}\n\nfunction parseTableCells(line: string): string[] | undefined {\n if (!line.includes('|')) {\n return undefined;\n }\n\n let tableLine = line.trim();\n if (tableLine.startsWith('|')) {\n tableLine = tableLine.slice(1);\n }\n if (tableLine.endsWith('|') && !tableLine.endsWith('\\\\|')) {\n tableLine = tableLine.slice(0, -1);\n }\n\n const cells: string[] = [];\n let cell = '';\n\n for (let index = 0; index < tableLine.length; index += 1) {\n const character = tableLine[index];\n const nextCharacter = tableLine[index + 1];\n\n if (character === '\\\\' && nextCharacter === '|') {\n cell += '|';\n index += 1;\n continue;\n }\n\n if (character === '|') {\n cells.push(cell.trim());\n cell = '';\n continue;\n }\n\n cell += character;\n }\n\n cells.push(cell.trim());\n\n return cells;\n}\n\nfunction parseTableAlignments(cells: string[]): TableAlignment[] | undefined {\n const alignments: TableAlignment[] = [];\n\n for (const cell of cells) {\n const match = cell.match(/^(:)?-{3,}(:)?$/);\n if (match == null) {\n return undefined;\n }\n\n const [, left, right] = match;\n alignments.push(\n left != null && right != null\n ? 'center'\n : right != null\n ? 'right'\n : 'left',\n );\n }\n\n return alignments;\n}\n\nfunction normalizeTableRow(row: string[], length: number): string[] {\n return Array.from({ length }, (_, index) => row[index] ?? '');\n}\n\nfunction renderTable(table: ParsedTable): string[] {\n const header = table.header.map(\n cell => `${ansi.bold}${renderInlineMarkdown(cell)}${ansi.boldOff}`,\n );\n const rows = table.rows.map(row => row.map(renderInlineMarkdown));\n const tableRows = [header, ...rows];\n const widths = table.alignments.map((_, columnIndex) =>\n Math.max(3, ...tableRows.map(row => visibleLength(row[columnIndex] ?? ''))),\n );\n\n return [\n formatTableRow(header, widths, table.alignments),\n widths.map(width => tableSeparator.repeat(width)).join(' '),\n ...rows.map(row => formatTableRow(row, widths, table.alignments)),\n ];\n}\n\nfunction formatTableRow(\n row: string[],\n widths: number[],\n alignments: TableAlignment[],\n): string {\n return row\n .map((cell, index) =>\n alignTableCell(cell, widths[index] ?? 0, alignments[index] ?? 'left'),\n )\n .join(' ');\n}\n\nfunction alignTableCell(\n cell: string,\n width: number,\n alignment: TableAlignment,\n): string {\n const paddingWidth = Math.max(0, width - visibleLength(cell));\n\n if (alignment === 'right') {\n return `${' '.repeat(paddingWidth)}${cell}`;\n }\n\n if (alignment === 'center') {\n const leftPadding = Math.floor(paddingWidth / 2);\n const rightPadding = paddingWidth - leftPadding;\n return `${' '.repeat(leftPadding)}${cell}${' '.repeat(rightPadding)}`;\n }\n\n return `${cell}${' '.repeat(paddingWidth)}`;\n}\n","import { renderMarkdown } from './markdown';\nimport {\n ansiPrefixPattern,\n codePointWidth,\n sliceVisible,\n visibleLength,\n} from './terminal-text';\n\nexport { sliceVisible, stripAnsi, visibleLength } from './terminal-text';\n\nconst horizontal = '─';\n\nexport type TUIScreenState = {\n width: number;\n height: number;\n title: string;\n rightTitle?: string;\n body: string;\n input: string;\n inputActive: boolean;\n inputCursorVisible?: boolean;\n scrollOffset: number;\n status?: string;\n};\n\nexport type TUIScreenLinesState = Omit<TUIScreenState, 'body'> & {\n bodyLines: string[];\n};\n\nexport type TUIScreenViewportState = Omit<\n TUIScreenLinesState,\n 'bodyLines' | 'scrollOffset'\n> & {\n visibleBodyLines: string[];\n};\n\nexport function renderScreen(state: TUIScreenState): string {\n const width = Math.max(20, state.width);\n const contentWidth = width - 4;\n const bodyLines = wrapText(renderMarkdown(state.body), contentWidth);\n\n return renderScreenLines({ ...state, bodyLines });\n}\n\nexport function renderScreenLines(state: TUIScreenLinesState): string {\n const height = Math.max(8, state.height);\n const inputHeight = 3;\n const bodyHeight = height - inputHeight;\n const bodyContentHeight = bodyHeight - 2;\n\n const maxScrollOffset = Math.max(\n 0,\n state.bodyLines.length - bodyContentHeight,\n );\n const scrollOffset = Math.min(\n Math.max(0, state.scrollOffset),\n maxScrollOffset,\n );\n const start = Math.max(\n 0,\n state.bodyLines.length - bodyContentHeight - scrollOffset,\n );\n const visibleBody = state.bodyLines.slice(start, start + bodyContentHeight);\n\n return renderScreenViewport({ ...state, visibleBodyLines: visibleBody });\n}\n\nexport function renderScreenViewport(state: TUIScreenViewportState): string {\n const width = Math.max(20, state.width);\n const height = Math.max(8, state.height);\n const inputHeight = 3;\n const bodyHeight = height - inputHeight;\n const bodyContentHeight = bodyHeight - 2;\n const visibleBody = state.visibleBodyLines.slice(0, bodyContentHeight);\n\n while (visibleBody.length < bodyContentHeight) {\n visibleBody.push('');\n }\n\n const lines = [\n topBorder(width, state.title, state.rightTitle),\n ...visibleBody.map(line => boxLine(line, width)),\n bottomBorder(width),\n topBorder(width, state.inputActive ? 'Input' : 'Status'),\n boxLine(\n state.inputActive\n ? `> ${state.input}${state.inputCursorVisible === false ? ' ' : '█'}`\n : (state.status ?? 'Streaming... ↑/↓ scroll · Ctrl+C quit'),\n width,\n ),\n bottomBorder(width),\n ];\n\n return lines.join('\\n');\n}\n\nexport function wrapText(input: string, width: number): string[] {\n if (width <= 0) {\n return [''];\n }\n\n const output: string[] = [];\n\n for (const rawLine of input.split('\\n')) {\n if (rawLine.length === 0) {\n output.push('');\n continue;\n }\n\n let remaining = rawLine;\n\n while (visibleLength(remaining) > width) {\n const breakAt = findBreakPoint(remaining, width);\n output.push(remaining.slice(0, breakAt).trimEnd());\n remaining = remaining.slice(breakAt).trimStart();\n }\n\n output.push(remaining);\n }\n\n return output;\n}\n\nexport function clampScrollOffset(\n scrollOffset: number,\n body: string,\n bodyHeight: number,\n width: number,\n): number {\n const bodyContentHeight = Math.max(1, bodyHeight - 2);\n const bodyLines = wrapText(renderMarkdown(body), Math.max(1, width - 4));\n const maxScrollOffset = Math.max(0, bodyLines.length - bodyContentHeight);\n\n return Math.min(Math.max(0, scrollOffset), maxScrollOffset);\n}\n\nfunction findBreakPoint(input: string, width: number): number {\n let index = 0;\n let visible = 0;\n let lastSpace = -1;\n\n while (index < input.length && visible < width) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (ansiMatch) {\n index += ansiMatch[0].length;\n continue;\n }\n\n const codePoint = input.codePointAt(index);\n\n if (codePoint == null) {\n break;\n }\n\n const character = String.fromCodePoint(codePoint);\n const characterWidth = codePointWidth(codePoint);\n\n if (characterWidth > 0 && visible + characterWidth > width) {\n break;\n }\n\n if (character === ' ') {\n lastSpace = index;\n }\n\n index += character.length;\n visible += characterWidth;\n }\n\n const nextBreakIndex = indexAfterAnsiSequences(input, index);\n if (visible === width && input.codePointAt(nextBreakIndex) === 0x20) {\n return nextBreakIndex;\n }\n\n if (lastSpace > 0) {\n return lastSpace;\n }\n\n return indexAtVisibleWidth(input, width);\n}\n\nfunction topBorder(width: number, title: string, rightTitle?: string): string {\n const contentWidth = Math.max(0, width - 2);\n const label = title ? sliceVisible(` ${title} `, contentWidth) : '';\n const rightLabel = rightTitle\n ? sliceVisible(\n ` ${rightTitle} `,\n Math.max(0, contentWidth - visibleLength(label)),\n )\n : '';\n const remaining = Math.max(\n 0,\n contentWidth - visibleLength(label) - visibleLength(rightLabel),\n );\n\n return `┌${label}${horizontal.repeat(remaining)}${rightLabel}┐`;\n}\n\nfunction bottomBorder(width: number): string {\n return `└${horizontal.repeat(width - 2)}┘`;\n}\n\nfunction boxLine(line: string, width: number): string {\n const contentWidth = width - 4;\n const visible = sliceVisible(line, contentWidth);\n const padding = ' '.repeat(\n Math.max(0, contentWidth - visibleLength(visible)),\n );\n\n return `│ ${visible}${padding} │`;\n}\n\nfunction indexAtVisibleWidth(input: string, width: number): number {\n let index = 0;\n let visible = 0;\n\n while (index < input.length && visible < width) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (ansiMatch) {\n index += ansiMatch[0].length;\n continue;\n }\n\n const codePoint = input.codePointAt(index);\n\n if (codePoint == null) {\n break;\n }\n\n const character = String.fromCodePoint(codePoint);\n const characterWidth = codePointWidth(codePoint);\n\n if (characterWidth > 0 && visible + characterWidth > width) {\n break;\n }\n\n index += character.length;\n visible += characterWidth;\n }\n\n return index;\n}\n\nfunction indexAfterAnsiSequences(input: string, startIndex: number): number {\n let index = startIndex;\n\n while (index < input.length) {\n const ansiMatch = input.slice(index).match(ansiPrefixPattern);\n\n if (!ansiMatch) {\n break;\n }\n\n index += ansiMatch[0].length;\n }\n\n return index;\n}\n","export type TerminalFrameOutput = {\n write(\n chunk: string | Uint8Array,\n encodingOrCallback?: BufferEncoding | ((error?: Error | null) => void),\n callback?: (error?: Error | null) => void,\n ): boolean;\n};\n\nexport type TerminalFrameBufferOptions = {\n useSynchronizedUpdates?: boolean;\n};\n\nconst escape = '\\x1b';\nconst cursorHome = `${escape}[H`;\nconst clearScreen = `${escape}[2J`;\nconst clearLine = `${escape}[2K`;\nconst synchronizeStart = `${escape}[?2026h`;\nconst synchronizeEnd = `${escape}[?2026l`;\n\ntype FrameSnapshot = {\n lines: string[];\n};\n\nexport class TerminalFrameBuffer {\n readonly #useSynchronizedUpdates: boolean;\n readonly #originalWrite: TerminalFrameOutput['write'];\n\n #previousFrame?: FrameSnapshot;\n #isWritingFrame = false;\n #externalWriteSinceLastFrame = false;\n\n constructor(\n output: TerminalFrameOutput,\n options?: TerminalFrameBufferOptions,\n ) {\n this.#originalWrite = output.write.bind(output);\n this.#useSynchronizedUpdates = options?.useSynchronizedUpdates ?? true;\n\n output.write = ((\n chunk: string | Uint8Array,\n encodingOrCallback?: BufferEncoding | ((error?: Error | null) => void),\n callback?: (error?: Error | null) => void,\n ) => {\n if (!this.#isWritingFrame) {\n this.#externalWriteSinceLastFrame = true;\n }\n\n return this.#originalWrite(chunk, encodingOrCallback, callback);\n }) as TerminalFrameOutput['write'];\n }\n\n present(frame: string) {\n const nextFrame = snapshotFrame(frame);\n const update =\n this.#previousFrame && !this.#externalWriteSinceLastFrame\n ? diffFrame(this.#previousFrame, nextFrame)\n : `${cursorHome}${clearScreen}${frame}`;\n\n this.#previousFrame = nextFrame;\n this.#externalWriteSinceLastFrame = false;\n\n if (update.length === 0) {\n return;\n }\n\n this.#writeUpdate(update);\n }\n\n reset() {\n this.#previousFrame = undefined;\n }\n\n #writeUpdate(update: string) {\n this.#isWritingFrame = true;\n\n try {\n if (!this.#useSynchronizedUpdates) {\n this.#originalWrite(update);\n return;\n }\n\n this.#originalWrite(`${synchronizeStart}${update}${synchronizeEnd}`);\n } finally {\n this.#isWritingFrame = false;\n }\n }\n}\n\nfunction snapshotFrame(frame: string): FrameSnapshot {\n return { lines: frame.split('\\n') };\n}\n\nfunction diffFrame(previousFrame: FrameSnapshot, nextFrame: FrameSnapshot) {\n let output = '';\n const lineCount = Math.max(\n previousFrame.lines.length,\n nextFrame.lines.length,\n );\n\n for (let index = 0; index < lineCount; index++) {\n const line = nextFrame.lines[index];\n\n if (previousFrame.lines[index] === line) {\n continue;\n }\n\n output += `${escape}[${index + 1};1H${clearLine}${line ?? ''}`;\n }\n\n return output;\n}\n","import type {\n AgentTUIStreamResult,\n AgentTUIToolApprovalRequest,\n AgentTUIToolApprovalResponse,\n} from '../agent-tui-runner';\nimport type {\n ResponseStatisticsMode,\n TerminalPartDisplayMode,\n} from '../run-agent-tui';\nimport { renderScreenViewport, sliceVisible, visibleLength } from './layout';\nimport { renderMarkdown } from './markdown';\nimport { TerminalFrameBuffer } from './terminal-frame-buffer';\nimport {\n getToolName,\n isToolUIPart,\n readUIMessageStream,\n type StepResultPerformance,\n type DynamicToolUIPart,\n type ToolUIPart,\n type UIMessage,\n type UIMessageChunk,\n} from 'ai';\n\nexport type TerminalInput = {\n isTTY?: boolean;\n on(event: 'data', listener: (chunk: Buffer) => void): TerminalInput;\n off(event: 'data', listener: (chunk: Buffer) => void): TerminalInput;\n resume(): TerminalInput;\n pause(): TerminalInput;\n setRawMode?: (mode: boolean) => TerminalInput;\n};\n\nexport type TerminalOutput = {\n columns?: number;\n rows?: number;\n write(\n chunk: string | Uint8Array,\n encodingOrCallback?: BufferEncoding | ((error?: Error | null) => void),\n callback?: (error?: Error | null) => void,\n ): boolean;\n on(event: 'resize', listener: () => void): TerminalOutput;\n off(event: 'resize', listener: () => void): TerminalOutput;\n};\n\nconst defaultResponseStatistics: ResponseStatisticsMode =\n 'outputTokensPerSecond';\n\nexport type TerminalRendererOptions = {\n input?: TerminalInput;\n output?: TerminalOutput;\n frameBuffer?: TerminalFrameBuffer;\n tools?: TerminalPartDisplayMode;\n reasoning?: TerminalPartDisplayMode;\n responseStatistics?: ResponseStatisticsMode;\n contextSize?: number;\n};\n\nexport type TerminalSessionOptions = {\n title?: string;\n initialPrompt?: string;\n submittedPrompt?: string;\n waitForExit?: boolean;\n continueSession?: boolean;\n tools?: TerminalPartDisplayMode;\n reasoning?: TerminalPartDisplayMode;\n responseStatistics?: ResponseStatisticsMode;\n contextSize?: number;\n};\n\nexport type TerminalKey =\n | { type: 'character'; value: string }\n | { type: 'backspace' }\n | { type: 'enter' }\n | { type: 'up' }\n | { type: 'down' }\n | { type: 'page-up' }\n | { type: 'page-down' }\n | { type: 'ctrl-l' }\n | { type: 'ctrl-c' }\n | { type: 'escape' }\n | { type: 'ignore' };\n\ntype ChatSectionKind = 'user' | 'assistant' | 'reasoning' | 'tool' | 'error';\n\ntype ChatSection = {\n kind: ChatSectionKind;\n title: string;\n rightTitle?: string;\n content: string;\n collapsed?: boolean;\n id?: string;\n cache?: RenderedSectionCache;\n};\n\ntype RenderedSectionCache = {\n width: number;\n kind: ChatSectionKind;\n title: string;\n rightTitle?: string;\n content: string;\n collapsed: boolean;\n lines: string[];\n};\n\ntype StreamUsage = {\n totalTokens?: number | { total?: number };\n inputTokens?: number | { total?: number };\n promptTokens?: number;\n outputTokens?: number | { total?: number };\n completionTokens?: number;\n};\n\ntype MessageMetadataWithStats = {\n usage?: StreamUsage;\n performance?: Pick<StepResultPerformance, 'outputTokensPerSecond'>;\n};\n\nconst colors = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n user: '\\x1b[96m',\n assistant: '\\x1b[92m',\n reasoning: '\\x1b[94m',\n tool: '\\x1b[95m',\n error: '\\x1b[91m',\n};\n\nconst sectionStyles: Record<\n ChatSectionKind,\n { color: string; border: string }\n> = {\n user: { color: colors.user, border: '─' },\n assistant: { color: colors.assistant, border: '─' },\n reasoning: { color: colors.reasoning, border: '·' },\n tool: { color: colors.tool, border: '─' },\n error: { color: colors.error, border: '─' },\n};\n\nconst inputCursorBlinkMs = 500;\nconst activeControls = '↑/↓ · PgUp/PgDn · Esc/Ctrl+C';\nconst doneControls = '↑/↓ · PgUp/PgDn · q/Esc/Ctrl+C';\nconst processingStatus = `Processing input... ${activeControls}`;\nconst processingToolResultsStatus = `Processing tool results... ${activeControls}`;\nconst streamingStatus = `Streaming... ${activeControls}`;\nconst executingToolsStatus = `Executing tools... ${activeControls}`;\n\nexport class TerminalRenderer {\n readonly #input: TerminalInput;\n readonly #output: TerminalOutput;\n readonly #frameBuffer: TerminalFrameBuffer;\n readonly #tools: TerminalPartDisplayMode;\n readonly #reasoning: TerminalPartDisplayMode;\n readonly #responseStatistics: ResponseStatisticsMode;\n readonly #defaultContextSize?: number;\n\n #sections: ChatSection[] = [];\n #inputText = '';\n #inputActive = false;\n #scrollOffset = 0;\n #title = '';\n #status = streamingStatus;\n #isInteractive = false;\n #interrupted = false;\n #totalTokens?: number;\n #contextSize?: number;\n #assistantOutputTokens?: number;\n #assistantOutputTokensPerSecond?: number;\n #inputCursorVisible = true;\n #inputCursorTimer?: ReturnType<typeof setInterval>;\n #onData?: (chunk: Buffer) => void;\n #onResize?: () => void;\n #resolveStreamInterrupt?: () => void;\n\n constructor(options?: TerminalRendererOptions) {\n this.#input = options?.input ?? process.stdin;\n this.#output = options?.output ?? process.stdout;\n this.#frameBuffer =\n options?.frameBuffer ?? new TerminalFrameBuffer(this.#output);\n this.#tools = options?.tools ?? 'auto-collapsed';\n this.#reasoning = options?.reasoning ?? 'auto-collapsed';\n this.#responseStatistics =\n options?.responseStatistics ?? defaultResponseStatistics;\n this.#defaultContextSize = options?.contextSize;\n this.#contextSize = options?.contextSize;\n }\n\n async readPrompt(options?: TerminalSessionOptions): Promise<string> {\n this.#start(options);\n this.#inputActive = true;\n this.#inputText = options?.initialPrompt ?? '';\n this.#status = `Type a prompt and press Enter · ${activeControls}`;\n this.#startInputCursorBlink();\n this.#paint();\n\n return await new Promise((resolve, reject) => {\n this.#onData = chunk => {\n const key = parseKey(chunk);\n\n switch (key.type) {\n case 'character':\n this.#inputText += key.value;\n this.#showInputCursor();\n this.#paint();\n break;\n case 'backspace':\n this.#inputText = this.#inputText.slice(0, -1);\n this.#showInputCursor();\n this.#paint();\n break;\n case 'enter': {\n const prompt = this.#inputText;\n this.#inputActive = false;\n this.#stopInputCursorBlink();\n this.#status = processingStatus;\n this.#addUserSection(prompt);\n this.#inputText = '';\n this.#paint();\n this.#detachInput();\n resolve(prompt);\n break;\n }\n case 'up':\n case 'down':\n this.#handleScroll(key.type);\n break;\n case 'page-up':\n case 'page-down':\n this.#handlePageScroll(key.type);\n break;\n case 'ctrl-l':\n this.#repaint();\n break;\n case 'escape':\n case 'ctrl-c':\n this.#stopInputCursorBlink();\n this.#stop();\n reject(interruptedError());\n break;\n case 'ignore':\n break;\n }\n };\n\n this.#attachInput();\n });\n }\n\n async renderStream(\n result: AgentTUIStreamResult,\n options?: TerminalSessionOptions,\n ): Promise<UIMessage | undefined> {\n this.#start(options);\n this.#inputActive = false;\n this.#status = processingStatus;\n this.#addSubmittedPrompt(options?.submittedPrompt);\n this.#interrupted = false;\n this.#totalTokens = undefined;\n this.#assistantOutputTokens = undefined;\n this.#assistantOutputTokensPerSecond = undefined;\n const displayModes = {\n tools: options?.tools ?? this.#tools,\n reasoning: options?.reasoning ?? this.#reasoning,\n responseStatistics:\n options?.responseStatistics ?? this.#responseStatistics,\n };\n this.#paint();\n const streamInterrupted = new Promise<void>(resolve => {\n this.#resolveStreamInterrupt = resolve;\n });\n this.#onData = chunk => this.#handleStreamingKey(chunk);\n this.#attachInput();\n let responseMessage: UIMessage | undefined;\n const stream = toReadableStream(\n this.#observeUIMessageStream(result.uiMessageStream),\n );\n\n try {\n const messages = readUIMessageStream({\n message: result.message,\n stream,\n onError: error =>\n this.#addErrorSection('Error', formatStreamError(error)),\n });\n\n for await (const message of takeUntil(messages, streamInterrupted)) {\n if (this.#interrupted) {\n break;\n }\n\n responseMessage = message;\n this.#renderAssistantMessage(message, displayModes);\n }\n\n if (\n !this.#interrupted &&\n responseMessage &&\n this.#assistantOutputTokens != null\n ) {\n this.#renderAssistantMessage(responseMessage, displayModes);\n }\n } finally {\n this.#resolveStreamInterrupt = undefined;\n if (this.#interrupted) {\n result.abort?.();\n }\n this.#detachInput();\n this.#status = this.#interrupted\n ? 'Interrupted'\n : options?.continueSession\n ? `Done · Enter another prompt · ${activeControls}`\n : `Done · ${doneControls}`;\n this.#paint();\n await this.#waitForExit(options);\n\n if (this.#interrupted || !options?.continueSession) {\n this.#stop();\n }\n }\n\n if (this.#interrupted) {\n throw interruptedError();\n }\n\n return responseMessage;\n }\n\n async readToolApproval(\n request: AgentTUIToolApprovalRequest,\n options?: TerminalSessionOptions,\n ): Promise<AgentTUIToolApprovalResponse> {\n this.#start(options);\n this.#inputActive = false;\n this.#status = `Approve ${formatToolApprovalTitle(request)}? y/n · ${activeControls}`;\n this.#interrupted = false;\n this.#paint();\n\n return await new Promise((resolve, reject) => {\n this.#onData = chunk => {\n const key = parseKey(chunk);\n\n switch (key.type) {\n case 'character': {\n const value = key.value.toLowerCase();\n\n if (value === 'y') {\n this.#status = `Approved · ${processingStatus}`;\n this.#detachInput();\n this.#paint();\n resolve({ approved: true });\n } else if (value === 'n') {\n this.#status = `Denied · ${processingStatus}`;\n this.#detachInput();\n this.#paint();\n resolve({ approved: false, reason: 'Denied by user.' });\n }\n break;\n }\n case 'up':\n case 'down':\n this.#handleScroll(key.type);\n break;\n case 'page-up':\n case 'page-down':\n this.#handlePageScroll(key.type);\n break;\n case 'ctrl-l':\n this.#repaint();\n break;\n case 'escape':\n case 'ctrl-c':\n this.#interrupted = true;\n this.#stop();\n reject(interruptedError());\n break;\n default:\n break;\n }\n };\n\n this.#attachInput();\n });\n }\n\n #start(options?: TerminalSessionOptions) {\n this.#title = options?.title ?? this.#title;\n this.#contextSize = options?.contextSize ?? this.#defaultContextSize;\n\n if (this.#isInteractive) {\n return;\n }\n\n this.#isInteractive = true;\n this.#frameBuffer.reset();\n this.#output.write('\\x1b[?1049h\\x1b[?25l');\n\n if (this.#input.isTTY) {\n this.#input.setRawMode?.(true);\n this.#input.resume();\n }\n\n this.#onResize = () => this.#repaint();\n this.#output.on('resize', this.#onResize);\n }\n\n #stop() {\n this.#detachInput();\n this.#stopInputCursorBlink();\n\n if (!this.#isInteractive) {\n return;\n }\n\n if (this.#input.isTTY) {\n this.#input.setRawMode?.(false);\n this.#input.pause();\n }\n\n if (this.#onResize) {\n this.#output.off('resize', this.#onResize);\n this.#onResize = undefined;\n }\n\n this.#output.write('\\x1b[?25h\\x1b[?1049l');\n this.#frameBuffer.reset();\n this.#isInteractive = false;\n }\n\n #attachInput() {\n if (this.#onData) {\n this.#input.on('data', this.#onData);\n }\n }\n\n #detachInput() {\n if (this.#onData) {\n this.#input.off('data', this.#onData);\n this.#onData = undefined;\n }\n }\n\n #handleStreamingKey(chunk: Buffer) {\n const key = parseKey(chunk);\n\n switch (key.type) {\n case 'up':\n case 'down':\n this.#handleScroll(key.type);\n break;\n case 'page-up':\n case 'page-down':\n this.#handlePageScroll(key.type);\n break;\n case 'ctrl-l':\n this.#repaint();\n break;\n case 'escape':\n case 'ctrl-c':\n this.#interrupted = true;\n this.#resolveStreamInterrupt?.();\n break;\n default:\n break;\n }\n }\n\n #handleScroll(direction: 'up' | 'down', lines = 1) {\n const delta = direction === 'up' ? lines : -lines;\n this.#scrollOffset = this.#clampScrollOffset(this.#scrollOffset + delta);\n this.#paint();\n }\n\n #handlePageScroll(direction: 'page-up' | 'page-down') {\n this.#handleScroll(\n direction === 'page-up' ? 'up' : 'down',\n this.#bodyContentHeight(),\n );\n }\n\n #startInputCursorBlink() {\n this.#stopInputCursorBlink();\n this.#showInputCursor();\n this.#inputCursorTimer = setInterval(() => {\n this.#inputCursorVisible = !this.#inputCursorVisible;\n this.#paint();\n }, inputCursorBlinkMs);\n this.#inputCursorTimer.unref?.();\n }\n\n #stopInputCursorBlink() {\n if (this.#inputCursorTimer) {\n clearInterval(this.#inputCursorTimer);\n this.#inputCursorTimer = undefined;\n }\n\n this.#inputCursorVisible = true;\n }\n\n #showInputCursor() {\n this.#inputCursorVisible = true;\n }\n\n #addSubmittedPrompt(prompt: string | undefined) {\n if (prompt == null) {\n return;\n }\n\n const section = this.#sections.at(-1);\n\n if (section?.kind === 'user' && section.content === prompt) {\n return;\n }\n\n this.#addUserSection(prompt);\n }\n\n #addUserSection(prompt: string) {\n const previousBodyLineCount = this.#bodyLineCount();\n this.#sections.push({ kind: 'user', title: 'User', content: prompt });\n this.#paintAfterBodyChange(previousBodyLineCount);\n }\n\n #renderAssistantMessage(\n message: UIMessage,\n displayModes: {\n tools: TerminalPartDisplayMode;\n reasoning: TerminalPartDisplayMode;\n responseStatistics: ResponseStatisticsMode;\n },\n ) {\n const previousBodyLineCount = this.#bodyLineCount();\n const activeSectionIds = new Set<string>();\n const metadataStats = extractResponseStatisticsFromMetadata(\n message.metadata,\n );\n this.#totalTokens = metadataStats.totalTokens ?? this.#totalTokens;\n this.#assistantOutputTokens =\n metadataStats.outputTokens ?? this.#assistantOutputTokens;\n this.#assistantOutputTokensPerSecond =\n metadataStats.outputTokensPerSecond ??\n this.#assistantOutputTokensPerSecond;\n\n for (const [index, part] of message.parts.entries()) {\n const id = sectionId(message.id, index);\n\n switch (part.type) {\n case 'text': {\n const content = part.text.trim();\n\n if (content.length === 0) {\n break;\n }\n\n activeSectionIds.add(id);\n this.#upsertSection({\n id,\n kind: 'assistant',\n title: 'Assistant',\n rightTitle: formatResponseStatistics(\n {\n totalTokens: this.#totalTokens,\n outputTokens: this.#assistantOutputTokens,\n outputTokensPerSecond: this.#assistantOutputTokensPerSecond,\n },\n displayModes.responseStatistics,\n ),\n content,\n });\n break;\n }\n case 'reasoning': {\n const content = part.text.trim();\n\n if (displayModes.reasoning === 'hidden' || content.length === 0) {\n break;\n }\n\n activeSectionIds.add(id);\n this.#upsertSection({\n id,\n kind: 'reasoning',\n title: 'Reasoning',\n content,\n collapsed: shouldCollapsePart(\n message,\n index,\n displayModes.reasoning,\n displayModes,\n ),\n });\n break;\n }\n default:\n if (isToolUIPart(part)) {\n if (displayModes.tools === 'hidden') {\n break;\n }\n\n activeSectionIds.add(id);\n this.#upsertSection({\n id,\n ...renderToolInvocation(part, {\n mode: displayModes.tools,\n collapsed: shouldCollapsePart(\n message,\n index,\n displayModes.tools,\n displayModes,\n ),\n }),\n });\n }\n break;\n }\n }\n\n this.#removeStaleAssistantSections(message.id, activeSectionIds);\n this.#paintAfterBodyChange(previousBodyLineCount);\n }\n\n #upsertSection(section: ChatSection) {\n const existingSection = section.id\n ? this.#sections.find(candidate => candidate.id === section.id)\n : undefined;\n\n if (existingSection) {\n const cache = existingSection.cache;\n existingSection.kind = section.kind;\n existingSection.title = section.title;\n existingSection.rightTitle = section.rightTitle;\n existingSection.content = section.content;\n existingSection.collapsed = section.collapsed;\n existingSection.cache =\n cache && sectionMatchesCache(section, cache) ? cache : undefined;\n return;\n }\n\n this.#sections.push(section);\n }\n\n #removeStaleAssistantSections(\n messageId: string,\n activeSectionIds: Set<string>,\n ) {\n const prefix = `${messageId}:`;\n this.#sections = this.#sections.filter(\n section =>\n section.id == null ||\n !section.id.startsWith(prefix) ||\n activeSectionIds.has(section.id),\n );\n }\n\n async *#observeUIMessageStream(\n stream: AsyncIterable<UIMessageChunk> | ReadableStream<UIMessageChunk>,\n ): AsyncIterable<UIMessageChunk> {\n let hasPendingToolResults = false;\n\n for await (const chunk of iterateUIMessageStream(stream)) {\n const nextStatus = statusForStreamChunk(chunk, { hasPendingToolResults });\n\n if (chunk.type === 'start-step') {\n hasPendingToolResults = false;\n } else if (finishesToolExecution(chunk)) {\n hasPendingToolResults = true;\n }\n\n if (nextStatus && this.#status !== nextStatus) {\n this.#status = nextStatus;\n this.#paint();\n } else if (\n startsVisibleAssistantStream(chunk) &&\n this.#status !== streamingStatus\n ) {\n this.#status = streamingStatus;\n this.#paint();\n }\n\n if (chunk.type === 'error') {\n this.#addErrorSection('Error', chunk.errorText);\n }\n\n if (chunk.type === 'finish') {\n const stats = extractResponseStatistics(chunk);\n this.#totalTokens = stats.totalTokens;\n this.#assistantOutputTokens = stats.outputTokens;\n this.#assistantOutputTokensPerSecond = stats.outputTokensPerSecond;\n }\n\n yield chunk;\n }\n }\n\n #addErrorSection(title: string, content: string) {\n const previousBodyLineCount = this.#bodyLineCount();\n this.#sections.push({ kind: 'error', title, content });\n this.#paintAfterBodyChange(previousBodyLineCount);\n }\n\n #paintAfterBodyChange(previousBodyLineCount: number) {\n if (this.#scrollOffset !== 0) {\n const bodyLineDelta = this.#bodyLineCount() - previousBodyLineCount;\n this.#scrollOffset = this.#clampScrollOffset(\n this.#scrollOffset + bodyLineDelta,\n );\n }\n\n this.#paint();\n }\n\n #paint() {\n const frame = renderScreenViewport({\n width: this.#width(),\n height: this.#height(),\n title: this.#title,\n rightTitle: formatTokenCount(this.#totalTokens, this.#contextSize),\n visibleBodyLines: this.#visibleBodyLines(),\n input: this.#inputText,\n inputActive: this.#inputActive,\n inputCursorVisible: this.#inputCursorVisible,\n status: this.#status,\n });\n\n this.#frameBuffer.present(frame);\n }\n\n #repaint() {\n this.#frameBuffer.reset();\n this.#paint();\n }\n\n #visibleBodyLines() {\n if (this.#sections.length === 0) {\n return ['Waiting for input...'];\n }\n\n const bodyContentHeight = this.#bodyContentHeight();\n const totalLineCount = this.#bodyLineCount();\n const start = Math.max(\n 0,\n totalLineCount - bodyContentHeight - this.#scrollOffset,\n );\n const end = start + bodyContentHeight;\n const visibleLines: string[] = [];\n let sectionStart = 0;\n\n for (const section of this.#sections) {\n const sectionLines = renderSectionLines(section, this.#width() - 4);\n const sectionEnd = sectionStart + sectionLines.length;\n\n if (sectionEnd > start && sectionStart < end) {\n visibleLines.push(\n ...sectionLines.slice(\n Math.max(0, start - sectionStart),\n end - sectionStart,\n ),\n );\n }\n\n if (visibleLines.length >= bodyContentHeight) {\n break;\n }\n\n sectionStart = sectionEnd;\n }\n\n return visibleLines;\n }\n\n #clampScrollOffset(scrollOffset: number) {\n const maxScrollOffset = Math.max(\n 0,\n this.#bodyLineCount() - this.#bodyContentHeight(),\n );\n\n return Math.min(Math.max(0, scrollOffset), maxScrollOffset);\n }\n\n #bodyLineCount() {\n if (this.#sections.length === 0) {\n return 1;\n }\n\n let count = 0;\n for (const section of this.#sections) {\n count += renderSectionLines(section, this.#width() - 4).length;\n }\n\n return count;\n }\n\n #bodyContentHeight() {\n return Math.max(1, this.#height() - 5);\n }\n\n #width() {\n return Math.max(20, this.#output.columns ?? 80);\n }\n\n #height() {\n return Math.max(8, this.#output.rows ?? 24);\n }\n\n async #waitForExit(options?: TerminalSessionOptions) {\n if (\n options?.waitForExit === false ||\n !this.#input.isTTY ||\n this.#interrupted\n ) {\n return;\n }\n\n await new Promise<void>(resolve => {\n this.#onData = chunk => {\n const key = parseKey(chunk);\n\n switch (key.type) {\n case 'up':\n case 'down':\n this.#handleScroll(key.type);\n break;\n case 'page-up':\n case 'page-down':\n this.#handlePageScroll(key.type);\n break;\n case 'ctrl-l':\n this.#repaint();\n break;\n case 'escape':\n this.#detachInput();\n resolve();\n break;\n case 'character':\n if (key.value === 'q') {\n this.#detachInput();\n resolve();\n }\n break;\n case 'ctrl-c':\n this.#detachInput();\n process.exitCode = 130;\n resolve();\n break;\n default:\n break;\n }\n };\n\n this.#attachInput();\n });\n }\n}\n\nfunction interruptedError() {\n return new Error('Interrupted');\n}\n\nasync function* takeUntil<T>(\n source: AsyncIterable<T>,\n stop: Promise<void>,\n): AsyncIterable<T> {\n const iterator = source[Symbol.asyncIterator]();\n const stopped = stop.then(\n () => ({ done: true, value: undefined as T }) satisfies IteratorResult<T>,\n );\n\n while (true) {\n const nextValue = await Promise.race([iterator.next(), stopped]);\n\n if (nextValue.done) {\n break;\n }\n\n yield nextValue.value;\n }\n}\n\nfunction formatStreamError(error: unknown) {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n return JSON.stringify(error);\n}\n\nfunction renderToolInvocation(\n part: ToolUIPart | DynamicToolUIPart,\n options: {\n mode: Exclude<TerminalPartDisplayMode, 'hidden'>;\n collapsed: boolean;\n },\n): ChatSection {\n const toolName = getToolName(part);\n const title = `Tool · ${part.title ?? toolName}`;\n const input = 'input' in part ? part.input : undefined;\n const inputText =\n input === undefined\n ? 'Input: (streaming...)'\n : `Input:\\n${formatValue(input)}`;\n const status = toolStatus(part);\n\n if (options.collapsed) {\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: '',\n collapsed: true,\n };\n }\n\n switch (part.state) {\n case 'input-streaming':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: inputText,\n };\n case 'input-available':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: inputText,\n };\n case 'approval-requested':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: inputText,\n };\n case 'approval-responded':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: inputText,\n };\n case 'output-available':\n return {\n kind: 'tool',\n title,\n rightTitle: status,\n content: `${inputText}\\n\\nOutput:\\n${formatValue(part.output)}`,\n };\n case 'output-error':\n return {\n kind: 'error',\n title: `Tool Error · ${part.title ?? toolName}`,\n rightTitle: status,\n content: `${inputText}\\n\\nError:\\n${part.errorText}`,\n };\n case 'output-denied':\n return {\n kind: 'error',\n title: `Tool Denied · ${part.title ?? toolName}`,\n rightTitle: status,\n content: `${inputText}\\n\\nReason: ${part.approval.reason ?? 'denied'}`,\n };\n }\n}\n\nfunction shouldCollapsePart(\n message: UIMessage,\n partIndex: number,\n mode: TerminalPartDisplayMode,\n displayModes: {\n tools: TerminalPartDisplayMode;\n reasoning: TerminalPartDisplayMode;\n },\n) {\n switch (mode) {\n case 'collapsed':\n return true;\n case 'auto-collapsed':\n return message.parts\n .slice(partIndex + 1)\n .some(part => isVisibleAssistantPart(part, displayModes));\n case 'full':\n case 'hidden':\n return false;\n }\n}\n\nfunction isVisibleAssistantPart(\n part: UIMessage['parts'][number],\n displayModes: {\n tools: TerminalPartDisplayMode;\n reasoning: TerminalPartDisplayMode;\n },\n) {\n switch (part.type) {\n case 'text':\n return part.text.trim().length > 0;\n case 'reasoning':\n return displayModes.reasoning !== 'hidden' && part.text.trim().length > 0;\n default:\n return isToolUIPart(part) && displayModes.tools !== 'hidden';\n }\n}\n\nfunction startsVisibleAssistantStream(chunk: UIMessageChunk) {\n switch (chunk.type) {\n case 'text-start':\n case 'text-delta':\n case 'reasoning-start':\n case 'reasoning-delta':\n case 'tool-input-start':\n case 'tool-input-delta':\n return true;\n default:\n return false;\n }\n}\n\nfunction statusForStreamChunk(\n chunk: UIMessageChunk,\n { hasPendingToolResults }: { hasPendingToolResults: boolean },\n) {\n switch (chunk.type) {\n case 'start-step':\n return hasPendingToolResults\n ? processingToolResultsStatus\n : processingStatus;\n case 'tool-output-available':\n case 'tool-output-error':\n case 'tool-output-denied':\n return processingToolResultsStatus;\n case 'tool-input-available':\n return executingToolsStatus;\n case 'tool-approval-response':\n return chunk.approved ? executingToolsStatus : undefined;\n default:\n return undefined;\n }\n}\n\nfunction finishesToolExecution(chunk: UIMessageChunk) {\n switch (chunk.type) {\n case 'tool-output-available':\n case 'tool-output-error':\n case 'tool-output-denied':\n return true;\n default:\n return false;\n }\n}\n\nfunction toolStatus(part: ToolUIPart | DynamicToolUIPart) {\n switch (part.state) {\n case 'input-streaming':\n return 'waiting';\n case 'approval-requested':\n return 'approval requested';\n case 'input-available':\n return 'executing';\n case 'approval-responded':\n return part.approval.approved ? 'executing' : 'denied';\n case 'output-available':\n case 'output-error':\n return 'done';\n case 'output-denied':\n return 'denied';\n }\n}\n\nfunction formatValue(value: unknown) {\n if (typeof value === 'string') {\n return value;\n }\n\n return JSON.stringify(value, null, 2);\n}\n\nfunction formatToolApprovalTitle(request: AgentTUIToolApprovalRequest) {\n return `tool ${request.title ?? request.toolName}`;\n}\n\nfunction sectionId(messageId: string, partIndex: number) {\n return `${messageId}:${partIndex}`;\n}\n\nfunction toReadableStream(\n stream: AsyncIterable<UIMessageChunk> | ReadableStream<UIMessageChunk>,\n): ReadableStream<UIMessageChunk> {\n if (stream instanceof ReadableStream) {\n return stream;\n }\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const chunk of stream) {\n controller.enqueue(chunk);\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n}\n\nasync function* iterateUIMessageStream(\n stream: AsyncIterable<UIMessageChunk> | ReadableStream<UIMessageChunk>,\n): AsyncIterable<UIMessageChunk> {\n if (stream instanceof ReadableStream) {\n const reader = stream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n return;\n }\n\n yield value;\n }\n } finally {\n reader.releaseLock();\n }\n\n return;\n }\n\n yield* stream;\n}\n\nfunction renderSectionLines(section: ChatSection, width: number) {\n if (section.cache && sectionMatchesCache(section, section.cache, width)) {\n return section.cache.lines;\n }\n\n const lines = createSectionLines(section, width);\n section.cache = {\n width,\n kind: section.kind,\n title: section.title,\n rightTitle: section.rightTitle,\n content: section.content,\n collapsed: section.collapsed === true,\n lines,\n };\n\n return lines;\n}\n\nfunction sectionMatchesCache(\n section: ChatSection,\n cache: RenderedSectionCache,\n width = cache.width,\n) {\n return (\n cache.width === width &&\n cache.kind === section.kind &&\n cache.title === section.title &&\n cache.rightTitle === section.rightTitle &&\n cache.content === section.content &&\n cache.collapsed === (section.collapsed === true)\n );\n}\n\nfunction createSectionLines(section: ChatSection, width: number) {\n const style = sectionStyles[section.kind];\n const contentWidth = Math.max(1, width - 4);\n const title = ` ${section.title} `;\n const rightTitle = section.rightTitle ? ` ${section.rightTitle} ` : '';\n\n if (section.collapsed) {\n const borderWidth = Math.max(\n 0,\n width - 2 - title.length - rightTitle.length,\n );\n const top = `${style.color}╭${title}${style.border.repeat(borderWidth)}${rightTitle}╮${colors.reset}`;\n const bottom = `${style.color}╰${style.border.repeat(Math.max(0, width - 2))}╯${colors.reset}`;\n\n return [top, bottom];\n }\n\n const borderWidth = Math.max(0, width - 2 - title.length - rightTitle.length);\n const top = `${style.color}╭${title}${style.border.repeat(borderWidth)}${rightTitle}╮${colors.reset}`;\n const bottom = `${style.color}╰${style.border.repeat(Math.max(0, width - 2))}╯${colors.reset}`;\n const content =\n section.content.length > 0\n ? renderMarkdown(section.content)\n : colors.dim + '(streaming...)' + colors.reset;\n const lines = content\n .split('\\n')\n .flatMap(line => wrapVisibleLine(line, contentWidth));\n\n return [\n top,\n ...lines.map(line => sectionLine(line, contentWidth, style.color)),\n bottom,\n ];\n}\n\nfunction sectionLine(line: string, contentWidth: number, color: string) {\n const visible = sliceVisible(line, contentWidth);\n const padding = ' '.repeat(\n Math.max(0, contentWidth - visibleLength(visible)),\n );\n\n return `${color}│${colors.reset} ${visible}${padding} ${color}│${colors.reset}`;\n}\n\nfunction wrapVisibleLine(line: string, width: number): string[] {\n if (line.length === 0) {\n return [''];\n }\n\n const lines: string[] = [];\n let remaining = line;\n\n while (visibleLength(remaining) > width) {\n const breakAt = findVisibleBreakPoint(remaining, width);\n lines.push(remaining.slice(0, breakAt).trimEnd());\n remaining = remaining.slice(breakAt).trimStart();\n }\n\n lines.push(remaining);\n return lines;\n}\n\nfunction findVisibleBreakPoint(input: string, width: number) {\n const slice = sliceVisible(input, width + 1);\n const lastSpace = slice.lastIndexOf(' ');\n\n if (lastSpace > 0) {\n return lastSpace;\n }\n\n return sliceVisible(input, width).length;\n}\n\nfunction extractResponseStatistics(chunk: UIMessageChunk) {\n const usage =\n 'usage' in chunk ? (chunk.usage as StreamUsage | undefined) : undefined;\n const metadataUsage =\n 'messageMetadata' in chunk\n ? (chunk.messageMetadata as MessageMetadataWithStats | undefined)?.usage\n : undefined;\n const metadataPerformance =\n 'messageMetadata' in chunk\n ? (chunk.messageMetadata as MessageMetadataWithStats | undefined)\n ?.performance\n : undefined;\n\n return {\n totalTokens: extractTotalTokenCountFromUsage(usage ?? metadataUsage),\n outputTokens: extractOutputTokenCountFromUsage(usage ?? metadataUsage),\n outputTokensPerSecond: metadataPerformance?.outputTokensPerSecond,\n };\n}\n\nfunction extractResponseStatisticsFromMetadata(metadata: unknown) {\n const stats = metadata as MessageMetadataWithStats | undefined;\n\n return {\n totalTokens: extractTotalTokenCountFromUsage(stats?.usage),\n outputTokens: extractOutputTokenCountFromUsage(stats?.usage),\n outputTokensPerSecond: stats?.performance?.outputTokensPerSecond,\n };\n}\n\nfunction extractTotalTokenCountFromUsage(usage: StreamUsage | undefined) {\n const totalTokens = usage?.totalTokens;\n\n if (typeof totalTokens === 'number') {\n return totalTokens;\n }\n\n if (typeof totalTokens?.total === 'number') {\n return totalTokens.total;\n }\n\n const inputTokens = extractInputTokenCountFromUsage(usage);\n const outputTokens = extractOutputTokenCountFromUsage(usage);\n\n if (inputTokens != null && outputTokens != null) {\n return inputTokens + outputTokens;\n }\n\n return undefined;\n}\n\nfunction extractInputTokenCountFromUsage(usage: StreamUsage | undefined) {\n const inputTokens = usage?.inputTokens;\n\n if (typeof inputTokens === 'number') {\n return inputTokens;\n }\n\n if (typeof inputTokens?.total === 'number') {\n return inputTokens.total;\n }\n\n return usage?.promptTokens;\n}\n\nfunction extractOutputTokenCountFromUsage(usage: StreamUsage | undefined) {\n const outputTokens = usage?.outputTokens;\n\n if (typeof outputTokens === 'number') {\n return outputTokens;\n }\n\n if (typeof outputTokens?.total === 'number') {\n return outputTokens.total;\n }\n\n return usage?.completionTokens;\n}\n\nfunction formatTokenCount(tokens: number | undefined, contextSize?: number) {\n if (tokens == null) {\n return undefined;\n }\n\n const tokenCount = `${tokens.toLocaleString()} ${tokens === 1 ? 'token' : 'tokens'}`;\n const contextPercentage = formatContextPercentage(tokens, contextSize);\n\n return contextPercentage == null\n ? tokenCount\n : `${tokenCount} ${contextPercentage}`;\n}\n\nfunction formatContextPercentage(\n tokens: number,\n contextSize: number | undefined,\n) {\n if (\n contextSize == null ||\n contextSize <= 0 ||\n !Number.isFinite(contextSize)\n ) {\n return undefined;\n }\n\n return `${Math.round((tokens / contextSize) * 100).toLocaleString()}%`;\n}\n\nfunction formatResponseStatistics(\n stats: {\n totalTokens: number | undefined;\n outputTokens: number | undefined;\n outputTokensPerSecond: number | undefined;\n },\n mode: ResponseStatisticsMode,\n) {\n if (mode === 'outputTokensPerSecond') {\n return formatOutputTokensPerSecond(stats.outputTokensPerSecond);\n }\n\n return formatTokenCount(stats.outputTokens);\n}\n\nfunction formatOutputTokensPerSecond(\n outputTokensPerSecond: number | undefined,\n) {\n if (outputTokensPerSecond == null) {\n return undefined;\n }\n\n return `${formatNumber(outputTokensPerSecond)} tok/s`;\n}\n\nfunction formatNumber(value: number) {\n return Number.isInteger(value)\n ? value.toLocaleString()\n : value.toLocaleString(undefined, { maximumFractionDigits: 1 });\n}\n\nexport function parseKey(chunk: Buffer): TerminalKey {\n const value = chunk.toString('utf8');\n\n switch (value) {\n case '\\u000c':\n return { type: 'ctrl-l' };\n case '\\u0003':\n return { type: 'ctrl-c' };\n case '\\x1B':\n return { type: 'escape' };\n case '\\r':\n case '\\n':\n return { type: 'enter' };\n case '\\u007f':\n case '\\b':\n return { type: 'backspace' };\n case '\\x1B[A':\n return { type: 'up' };\n case '\\x1B[B':\n return { type: 'down' };\n case '\\x1B[5~':\n return { type: 'page-up' };\n case '\\x1B[6~':\n return { type: 'page-down' };\n default:\n if (value >= ' ' && value !== '\\x7F') {\n return { type: 'character', value };\n }\n\n return { type: 'ignore' };\n }\n}\n","import type {\n AgentTUIAgent,\n ResponseStatisticsMode,\n RunAgentTUIOptions,\n TerminalPartDisplayMode,\n} from './run-agent-tui';\nimport {\n TerminalRenderer,\n type TerminalInput,\n type TerminalOutput,\n} from './tui/terminal-renderer';\nimport {\n convertToModelMessages,\n generateId,\n getToolName,\n isToolUIPart,\n type ChatTransport,\n type StepResultPerformance,\n type Experimental_SandboxSession,\n type LanguageModelUsage,\n type TextStreamPart,\n type ToolSet,\n type UIMessage,\n type UIMessageChunk,\n} from 'ai';\n\nconst defaultResponseStatistics: ResponseStatisticsMode =\n 'outputTokensPerSecond';\n\nexport type AgentTUIStreamResult = {\n uiMessageStream:\n | AsyncIterable<UIMessageChunk>\n | ReadableStream<UIMessageChunk>;\n message?: UIMessage;\n abort?: () => void;\n};\n\nexport type AgentTUIStreamOptions = {\n messages: UIMessage[];\n};\n\nexport type AgentTUISessionOptions = {\n title?: string;\n initialPrompt?: string;\n submittedPrompt?: string;\n waitForExit?: boolean;\n continueSession?: boolean;\n tools?: TerminalPartDisplayMode;\n reasoning?: TerminalPartDisplayMode;\n responseStatistics?: ResponseStatisticsMode;\n contextSize?: number;\n};\n\nexport type AgentTUIToolApprovalRequest = {\n approvalId: string;\n toolCallId: string;\n toolName: string;\n title?: string;\n input: unknown;\n providerExecuted?: boolean;\n messageId: string;\n partIndex: number;\n};\n\nexport type AgentTUIToolApprovalResponse = {\n approved: boolean;\n reason?: string;\n};\n\nexport type AgentTUIRenderer = {\n readPrompt?(options?: AgentTUISessionOptions): Promise<string | undefined>;\n readToolApproval?(\n request: AgentTUIToolApprovalRequest,\n options?: AgentTUISessionOptions,\n ): Promise<AgentTUIToolApprovalResponse>;\n renderStream(\n result: AgentTUIStreamResult,\n options?: AgentTUISessionOptions,\n ): Promise<UIMessage | undefined>;\n};\n\nexport type AgentTUIRunnerOptions = RunAgentTUIOptions & {\n renderer?: AgentTUIRenderer;\n screen?: TerminalOutput;\n userInput?: TerminalInput;\n};\n\nexport class AgentTUIRunner {\n private readonly agent?: AgentTUIAgent;\n private readonly transport?: ChatTransport<UIMessage>;\n private readonly chatId = generateId();\n private readonly renderer: AgentTUIRenderer;\n private readonly title?: string;\n private readonly tools: TerminalPartDisplayMode;\n private readonly reasoning: TerminalPartDisplayMode;\n private readonly responseStatistics: ResponseStatisticsMode;\n private readonly contextSize?: number;\n private readonly sandbox?: Experimental_SandboxSession;\n\n constructor(options: AgentTUIRunnerOptions) {\n this.agent = options.agent;\n this.transport = options.transport;\n this.renderer = createRenderer(options) ?? createDefaultRenderer(options);\n this.title = options.title;\n this.tools = options.tools ?? 'auto-collapsed';\n this.reasoning = options.reasoning ?? 'auto-collapsed';\n this.responseStatistics =\n options.responseStatistics ?? defaultResponseStatistics;\n this.contextSize = options.contextSize;\n this.sandbox = options.sandbox;\n }\n\n async run() {\n const title = this.title;\n const messages: UIMessage[] = [];\n let nextMessageIndex = 0;\n const generateMessageId = () => `message-${++nextMessageIndex}`;\n let prompt: string | undefined;\n let hasRunTurn = false;\n let streamWithoutPrompt = false;\n\n while (true) {\n if (!streamWithoutPrompt) {\n if (prompt == null) {\n if (!this.renderer.readPrompt) {\n if (hasRunTurn) {\n return;\n }\n\n throw new Error(\n 'No prompt was provided and the renderer does not support prompt input.',\n );\n }\n\n try {\n prompt = await this.renderer.readPrompt({ title });\n } catch (error) {\n if (isInterruptedError(error)) {\n return;\n }\n\n throw error;\n }\n\n if (prompt == null) {\n return;\n }\n }\n\n messages.push(createUserMessage(generateMessageId(), prompt));\n hasRunTurn = true;\n }\n\n const result = await this.streamMessages(\n [...messages],\n generateMessageId,\n );\n\n try {\n const responseMessage = await this.renderer.renderStream(result, {\n title,\n submittedPrompt: prompt,\n continueSession: Boolean(this.renderer.readPrompt),\n tools: this.tools,\n reasoning: this.reasoning,\n responseStatistics: this.responseStatistics,\n contextSize: this.contextSize,\n waitForExit: false,\n });\n\n if (responseMessage && responseMessage.parts.length > 0) {\n const approvalRequests =\n findPendingToolApprovalRequests(responseMessage);\n\n if (approvalRequests.length > 0) {\n if (!this.renderer.readToolApproval) {\n throw new Error(\n 'Tool approval was requested, but the renderer does not support tool approval input.',\n );\n }\n\n for (const request of approvalRequests) {\n const response = await this.renderer.readToolApproval(request, {\n title,\n });\n applyToolApprovalResponse(responseMessage, request, response);\n }\n\n upsertResponseMessage(\n messages,\n responseMessage,\n streamWithoutPrompt,\n );\n streamWithoutPrompt = true;\n prompt = undefined;\n continue;\n }\n\n upsertResponseMessage(messages, responseMessage, streamWithoutPrompt);\n }\n } catch (error) {\n if (isInterruptedError(error)) {\n return;\n }\n\n throw error;\n }\n streamWithoutPrompt = false;\n prompt = undefined;\n }\n }\n\n private async streamMessages(\n messages: UIMessage[],\n generateMessageId: () => string,\n ): Promise<AgentTUIStreamResult> {\n const abortController = new AbortController();\n const abort = () => abortController.abort();\n\n if (this.transport) {\n return {\n uiMessageStream: await this.transport.sendMessages({\n trigger: 'submit-message',\n chatId: this.chatId,\n messageId: undefined,\n messages,\n abortSignal: abortController.signal,\n }),\n message: lastAssistantMessage(messages),\n abort,\n };\n }\n\n const agent = this.agent!;\n const result = await agent.stream({\n prompt: await convertToModelMessages(messages, {\n tools: agent.tools as ToolSet,\n }),\n abortSignal: abortController.signal,\n options: undefined,\n experimental_sandbox: this.sandbox,\n });\n\n return {\n uiMessageStream: textStreamToUIMessageStream(\n result.fullStream as AsyncIterable<TextStreamPart<ToolSet>>,\n generateMessageId,\n messages,\n ),\n message: lastAssistantMessage(messages),\n abort,\n };\n }\n}\n\nfunction createDefaultRenderer(options: AgentTUIRunnerOptions) {\n return options.tools === undefined &&\n options.reasoning === undefined &&\n options.responseStatistics === undefined &&\n options.contextSize === undefined\n ? new TerminalRenderer()\n : new TerminalRenderer({\n tools: options.tools,\n reasoning: options.reasoning,\n responseStatistics: options.responseStatistics,\n contextSize: options.contextSize,\n });\n}\n\nfunction createRenderer(\n options: AgentTUIRunnerOptions,\n): AgentTUIRenderer | undefined {\n if (options.renderer) {\n return options.renderer;\n }\n\n if (!options.screen && !options.userInput) {\n return undefined;\n }\n\n return new TerminalRenderer({\n tools: options.tools,\n reasoning: options.reasoning,\n responseStatistics: options.responseStatistics,\n contextSize: options.contextSize,\n input: options.userInput,\n output: options.screen,\n });\n}\n\nasync function* textStreamToUIMessageStream(\n stream: AsyncIterable<TextStreamPart<ToolSet>>,\n generateMessageId: () => string,\n originalMessages: UIMessage[] = [],\n): AsyncIterable<UIMessageChunk> {\n const openTextParts = new Set<string>();\n const openReasoningParts = new Set<string>();\n const openToolCalls = new Set<string>();\n let latestStepUsage: LanguageModelUsage | undefined;\n let latestPerformance: StepResultPerformance | undefined;\n let sentFinish = false;\n\n yield {\n type: 'start',\n messageId:\n lastAssistantMessage(originalMessages)?.id ?? generateMessageId(),\n };\n\n for await (const part of stream) {\n switch (part.type) {\n case 'text-start':\n openTextParts.add(part.id);\n yield {\n type: 'text-start',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'text-delta':\n if (!openTextParts.has(part.id)) {\n openTextParts.add(part.id);\n yield {\n type: 'text-start',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n }\n yield {\n type: 'text-delta',\n id: part.id,\n delta: part.text,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'text-end':\n openTextParts.delete(part.id);\n yield {\n type: 'text-end',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'reasoning-start':\n openReasoningParts.add(part.id);\n yield {\n type: 'reasoning-start',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'reasoning-delta':\n if (!openReasoningParts.has(part.id)) {\n openReasoningParts.add(part.id);\n yield {\n type: 'reasoning-start',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n }\n yield {\n type: 'reasoning-delta',\n id: part.id,\n delta: part.text,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'reasoning-end':\n openReasoningParts.delete(part.id);\n yield {\n type: 'reasoning-end',\n id: part.id,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'tool-input-start':\n yield {\n type: 'tool-input-start',\n toolCallId: part.id,\n toolName: part.toolName,\n providerExecuted: part.providerExecuted,\n providerMetadata: part.providerMetadata,\n toolMetadata: part.toolMetadata,\n dynamic: part.dynamic,\n title: part.title,\n };\n break;\n case 'tool-input-delta':\n yield {\n type: 'tool-input-delta',\n toolCallId: part.id,\n inputTextDelta: part.delta,\n };\n break;\n case 'tool-call':\n openToolCalls.add(part.toolCallId);\n yield {\n type: 'tool-input-available',\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n input: part.input,\n providerExecuted: part.providerExecuted,\n providerMetadata: part.providerMetadata,\n toolMetadata: part.toolMetadata,\n dynamic: part.dynamic,\n title: part.title,\n };\n break;\n case 'tool-approval-request':\n if (!openToolCalls.has(part.toolCall.toolCallId)) {\n openToolCalls.add(part.toolCall.toolCallId);\n yield {\n type: 'tool-input-available',\n toolCallId: part.toolCall.toolCallId,\n toolName: part.toolCall.toolName,\n input: part.toolCall.input,\n providerExecuted: part.toolCall.providerExecuted,\n providerMetadata: part.toolCall.providerMetadata,\n toolMetadata: part.toolCall.toolMetadata,\n dynamic: part.toolCall.dynamic,\n title: part.toolCall.title,\n };\n }\n yield {\n type: 'tool-approval-request',\n approvalId: part.approvalId,\n toolCallId: part.toolCall.toolCallId,\n isAutomatic: part.isAutomatic,\n };\n break;\n case 'tool-approval-response':\n yield {\n type: 'tool-approval-response',\n approvalId: part.approvalId,\n approved: part.approved,\n reason: part.reason,\n providerExecuted: part.providerExecuted,\n };\n break;\n case 'tool-result':\n yield {\n type: 'tool-output-available',\n toolCallId: part.toolCallId,\n output: part.output,\n providerExecuted: part.providerExecuted,\n providerMetadata: part.providerMetadata,\n toolMetadata: part.toolMetadata,\n dynamic: part.dynamic,\n preliminary: part.preliminary,\n };\n break;\n case 'tool-error':\n yield {\n type: 'tool-output-error',\n toolCallId: part.toolCallId,\n errorText: formatStreamError(part.error),\n providerExecuted: part.providerExecuted,\n providerMetadata: part.providerMetadata,\n toolMetadata: part.toolMetadata,\n dynamic: part.dynamic,\n };\n break;\n case 'tool-output-denied':\n yield { type: 'tool-output-denied', toolCallId: part.toolCallId };\n break;\n case 'source':\n if (part.sourceType === 'url') {\n yield {\n type: 'source-url',\n sourceId: part.id,\n url: part.url,\n title: part.title,\n providerMetadata: part.providerMetadata,\n };\n } else {\n yield {\n type: 'source-document',\n sourceId: part.id,\n mediaType: part.mediaType,\n title: part.title,\n filename: part.filename,\n providerMetadata: part.providerMetadata,\n };\n }\n break;\n case 'file':\n yield {\n type: 'file',\n url: fileToDataUrl(part.file.mediaType, part.file.base64),\n mediaType: part.file.mediaType,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'reasoning-file':\n yield {\n type: 'reasoning-file',\n url: fileToDataUrl(part.file.mediaType, part.file.base64),\n mediaType: part.file.mediaType,\n providerMetadata: part.providerMetadata,\n };\n break;\n case 'start-step':\n yield { type: 'start-step' };\n break;\n case 'finish-step':\n latestStepUsage = part.usage;\n latestPerformance = part.performance;\n yield { type: 'finish-step' };\n break;\n case 'finish':\n yield* closeOpenParts(openTextParts, openReasoningParts);\n sentFinish = true;\n yield {\n type: 'finish',\n finishReason: part.finishReason,\n messageMetadata: createResponseMetadata(\n latestStepUsage ?? part.totalUsage,\n latestPerformance,\n ),\n };\n break;\n case 'abort':\n yield { type: 'abort', reason: part.reason };\n break;\n case 'error':\n yield { type: 'error', errorText: formatStreamError(part.error) };\n break;\n }\n }\n\n if (!sentFinish) {\n yield* closeOpenParts(openTextParts, openReasoningParts);\n yield { type: 'finish' };\n }\n}\n\nfunction createResponseMetadata(\n usage: LanguageModelUsage | undefined,\n performance?: StepResultPerformance,\n): ResponseMetadata | undefined {\n if (\n usage?.totalTokens == null &&\n usage?.outputTokens == null &&\n performance?.outputTokensPerSecond == null\n ) {\n return undefined;\n }\n\n return {\n ...(usage?.totalTokens == null && usage?.outputTokens == null\n ? {}\n : {\n usage: {\n ...(usage.totalTokens == null\n ? {}\n : { totalTokens: usage.totalTokens }),\n ...(usage.outputTokens == null\n ? {}\n : { outputTokens: usage.outputTokens }),\n },\n }),\n ...(performance?.outputTokensPerSecond == null\n ? {}\n : {\n performance: {\n outputTokensPerSecond: performance.outputTokensPerSecond,\n },\n }),\n };\n}\n\ntype ResponseMetadata = {\n usage?: {\n totalTokens?: number;\n outputTokens?: number;\n };\n performance?: Pick<StepResultPerformance, 'outputTokensPerSecond'>;\n};\n\nfunction* closeOpenParts(\n textPartIds: Set<string>,\n reasoningPartIds: Set<string>,\n) {\n for (const id of textPartIds) {\n yield { type: 'text-end', id } satisfies UIMessageChunk;\n }\n textPartIds.clear();\n\n for (const id of reasoningPartIds) {\n yield { type: 'reasoning-end', id } satisfies UIMessageChunk;\n }\n reasoningPartIds.clear();\n}\n\nfunction createUserMessage(id: string, text: string): UIMessage {\n return {\n id,\n role: 'user',\n parts: [{ type: 'text', text }],\n };\n}\n\nfunction upsertResponseMessage(\n messages: UIMessage[],\n responseMessage: UIMessage,\n replaceLast: boolean,\n) {\n if (replaceLast && messages.at(-1)?.role === 'assistant') {\n messages[messages.length - 1] = responseMessage;\n return;\n }\n\n messages.push(responseMessage);\n}\n\nfunction lastAssistantMessage(messages: UIMessage[]) {\n const message = messages.at(-1);\n\n return message?.role === 'assistant' ? message : undefined;\n}\n\nfunction findPendingToolApprovalRequests(\n message: UIMessage,\n): AgentTUIToolApprovalRequest[] {\n const requests: AgentTUIToolApprovalRequest[] = [];\n\n for (const [index, part] of message.parts.entries()) {\n if (\n !isToolUIPart(part) ||\n part.state !== 'approval-requested' ||\n part.approval.isAutomatic === true\n ) {\n continue;\n }\n\n requests.push({\n approvalId: part.approval.id,\n toolCallId: part.toolCallId,\n toolName: getToolName(part),\n title: part.title,\n input: part.input,\n providerExecuted: part.providerExecuted,\n messageId: message.id,\n partIndex: index,\n });\n }\n\n return requests;\n}\n\nfunction applyToolApprovalResponse(\n message: UIMessage,\n request: AgentTUIToolApprovalRequest,\n response: AgentTUIToolApprovalResponse,\n) {\n const part = message.parts[request.partIndex];\n\n if (!part || !isToolUIPart(part) || part.toolCallId !== request.toolCallId) {\n throw new Error(\n `Could not find tool approval request ${request.approvalId}.`,\n );\n }\n\n part.state = 'approval-responded';\n part.approval = {\n id: request.approvalId,\n approved: response.approved,\n ...(response.reason ? { reason: response.reason } : {}),\n };\n}\n\nfunction formatStreamError(error: unknown) {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n return JSON.stringify(error);\n}\n\nfunction fileToDataUrl(mediaType: string, base64: string) {\n return `data:${mediaType};base64,${base64}`;\n}\n\nfunction isInterruptedError(error: unknown) {\n return error instanceof Error && error.message === 'Interrupted';\n}\n","import { AgentTUIRunner } from './agent-tui-runner';\nimport type {\n Agent,\n ChatTransport,\n Experimental_SandboxSession,\n UIMessage,\n} from 'ai';\n\n/**\n * Controls how terminal UI sections for stream parts are displayed.\n *\n * - `full`: show the section header and full content.\n * - `collapsed`: show only the section header.\n * - `auto-collapsed`: show the latest section expanded until another visible\n * section appears, then collapse it.\n * - `hidden`: omit the section entirely.\n */\nexport type TerminalPartDisplayMode =\n | 'full'\n | 'collapsed'\n | 'auto-collapsed'\n | 'hidden';\n\n/**\n * Controls which response statistic is shown.\n *\n * - `outputTokenCount`: show the number of output tokens in the response.\n * - `outputTokensPerSecond`: show output token throughput for the response.\n */\nexport type ResponseStatisticsMode =\n | 'outputTokenCount'\n | 'outputTokensPerSecond';\n\n/**\n * An agent that is compatible with the terminal UI.\n */\nexport type AgentTUIAgent = Agent<any, any, any, any>;\n\n/**\n * Options for starting an agent in the default terminal UI.\n */\nexport type RunAgentTUIOptions = {\n /**\n * The title shown in the terminal UI.\n */\n title?: string;\n\n /**\n * How tool calls should render.\n *\n * @default \"auto-collapsed\"\n */\n tools?: TerminalPartDisplayMode;\n\n /**\n * How reasoning parts should render.\n *\n * @default \"auto-collapsed\"\n */\n reasoning?: TerminalPartDisplayMode;\n\n /**\n * Which response statistic to show.\n *\n * @default \"outputTokensPerSecond\"\n */\n responseStatistics?: ResponseStatisticsMode;\n\n /**\n * The model context window size in tokens.\n *\n * When provided, the terminal UI shows the current total token usage as a\n * percentage of this context window.\n */\n contextSize?: number;\n} & (\n | {\n /**\n * The agent to run.\n */\n agent: AgentTUIAgent;\n transport?: never;\n\n /**\n * Sandbox session that is passed through to agent tool execution.\n */\n sandbox?: Experimental_SandboxSession;\n }\n | {\n agent?: never;\n\n /**\n * The transport used to communicate with a remote agent.\n */\n transport: ChatTransport<UIMessage>;\n sandbox?: never;\n }\n);\n\n/**\n * Runs an agent in the default terminal UI until the user exits.\n */\nexport async function runAgentTUI(options: RunAgentTUIOptions) {\n await new AgentTUIRunner(options).run();\n}\n"],"mappings":"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","names":["borderWidth","top","bottom","getToolName","isToolUIPart","defaultResponseStatistics","formatStreamError"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/tui",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "type": "module",
5
5
  "description": "Run AI SDK agents in a terminal UI.",
6
6
  "license": "Apache-2.0",
@@ -28,7 +28,7 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "ai": "7.0.27"
31
+ "ai": "7.0.28"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "22.19.19",
@@ -11,8 +11,10 @@ import {
11
11
  } from './tui/terminal-renderer';
12
12
  import {
13
13
  convertToModelMessages,
14
+ generateId,
14
15
  getToolName,
15
16
  isToolUIPart,
17
+ type ChatTransport,
16
18
  type StepResultPerformance,
17
19
  type Experimental_SandboxSession,
18
20
  type LanguageModelUsage,
@@ -77,17 +79,16 @@ export type AgentTUIRenderer = {
77
79
  ): Promise<UIMessage | undefined>;
78
80
  };
79
81
 
80
- export type AgentTUIRunnerOptions<
81
- TAgent extends AgentTUIAgent = AgentTUIAgent,
82
- > = Omit<RunAgentTUIOptions, 'agent'> & {
83
- agent: TAgent;
82
+ export type AgentTUIRunnerOptions = RunAgentTUIOptions & {
84
83
  renderer?: AgentTUIRenderer;
85
84
  screen?: TerminalOutput;
86
85
  userInput?: TerminalInput;
87
86
  };
88
87
 
89
- export class AgentTUIRunner<TAgent extends AgentTUIAgent = AgentTUIAgent> {
90
- private readonly agent: TAgent;
88
+ export class AgentTUIRunner {
89
+ private readonly agent?: AgentTUIAgent;
90
+ private readonly transport?: ChatTransport<UIMessage>;
91
+ private readonly chatId = generateId();
91
92
  private readonly renderer: AgentTUIRenderer;
92
93
  private readonly title?: string;
93
94
  private readonly tools: TerminalPartDisplayMode;
@@ -96,8 +97,9 @@ export class AgentTUIRunner<TAgent extends AgentTUIAgent = AgentTUIAgent> {
96
97
  private readonly contextSize?: number;
97
98
  private readonly sandbox?: Experimental_SandboxSession;
98
99
 
99
- constructor(options: AgentTUIRunnerOptions<TAgent>) {
100
+ constructor(options: AgentTUIRunnerOptions) {
100
101
  this.agent = options.agent;
102
+ this.transport = options.transport;
101
103
  this.renderer = createRenderer(options) ?? createDefaultRenderer(options);
102
104
  this.title = options.title;
103
105
  this.tools = options.tools ?? 'auto-collapsed';
@@ -213,9 +215,26 @@ export class AgentTUIRunner<TAgent extends AgentTUIAgent = AgentTUIAgent> {
213
215
  generateMessageId: () => string,
214
216
  ): Promise<AgentTUIStreamResult> {
215
217
  const abortController = new AbortController();
216
- const result = await this.agent.stream({
218
+ const abort = () => abortController.abort();
219
+
220
+ if (this.transport) {
221
+ return {
222
+ uiMessageStream: await this.transport.sendMessages({
223
+ trigger: 'submit-message',
224
+ chatId: this.chatId,
225
+ messageId: undefined,
226
+ messages,
227
+ abortSignal: abortController.signal,
228
+ }),
229
+ message: lastAssistantMessage(messages),
230
+ abort,
231
+ };
232
+ }
233
+
234
+ const agent = this.agent!;
235
+ const result = await agent.stream({
217
236
  prompt: await convertToModelMessages(messages, {
218
- tools: this.agent.tools as ToolSet,
237
+ tools: agent.tools as ToolSet,
219
238
  }),
220
239
  abortSignal: abortController.signal,
221
240
  options: undefined,
@@ -229,7 +248,7 @@ export class AgentTUIRunner<TAgent extends AgentTUIAgent = AgentTUIAgent> {
229
248
  messages,
230
249
  ),
231
250
  message: lastAssistantMessage(messages),
232
- abort: () => abortController.abort(),
251
+ abort,
233
252
  };
234
253
  }
235
254
  }
@@ -1,5 +1,10 @@
1
1
  import { AgentTUIRunner } from './agent-tui-runner';
2
- import type { Agent, Experimental_SandboxSession } from 'ai';
2
+ import type {
3
+ Agent,
4
+ ChatTransport,
5
+ Experimental_SandboxSession,
6
+ UIMessage,
7
+ } from 'ai';
3
8
 
4
9
  /**
5
10
  * Controls how terminal UI sections for stream parts are displayed.
@@ -35,11 +40,6 @@ export type AgentTUIAgent = Agent<any, any, any, any>;
35
40
  * Options for starting an agent in the default terminal UI.
36
41
  */
37
42
  export type RunAgentTUIOptions = {
38
- /**
39
- * The agent to run.
40
- */
41
- agent: AgentTUIAgent;
42
-
43
43
  /**
44
44
  * The title shown in the terminal UI.
45
45
  */
@@ -73,12 +73,29 @@ export type RunAgentTUIOptions = {
73
73
  * percentage of this context window.
74
74
  */
75
75
  contextSize?: number;
76
+ } & (
77
+ | {
78
+ /**
79
+ * The agent to run.
80
+ */
81
+ agent: AgentTUIAgent;
82
+ transport?: never;
76
83
 
77
- /**
78
- * Sandbox session that is passed through to agent tool execution.
79
- */
80
- sandbox?: Experimental_SandboxSession;
81
- };
84
+ /**
85
+ * Sandbox session that is passed through to agent tool execution.
86
+ */
87
+ sandbox?: Experimental_SandboxSession;
88
+ }
89
+ | {
90
+ agent?: never;
91
+
92
+ /**
93
+ * The transport used to communicate with a remote agent.
94
+ */
95
+ transport: ChatTransport<UIMessage>;
96
+ sandbox?: never;
97
+ }
98
+ );
82
99
 
83
100
  /**
84
101
  * Runs an agent in the default terminal UI until the user exits.