@berrydev-ai/parlor
v0.1.0
Published
Rich-like console rendering library for TypeScript with streaming support for AI agent responses
Maintainers
Readme
Parlor
A TypeScript library for rich, interactive console output - like Python's Rich library, optimized for AI agent responses with streaming support.
Features
- Beautiful Panels - Bordered boxes with titles, matching Agno's aesthetic
- Streaming Support - Real-time updates from async iterators (perfect for LLM responses)
- Markdown Rendering - Code blocks with syntax highlighting and dark backgrounds
- Fast & Lightweight - Built on Ink (React for terminals)
- TypeScript First - Full type safety
- Flexible - Works with Bun, Node.js, and Deno
- Themed Components - Pre-styled panels for messages, responses, reasoning, tool calls
Installation
bun add parlor
# or
npm install parlor
# or
pnpm add parlorQuick Start
Basic Panel
import { render } from 'ink';
import { MessagePanel, ResponsePanel } from 'parlor';
render(
<>
<MessagePanel>
<Text>What is the meaning of life?</Text>
</MessagePanel>
<ResponsePanel elapsed={2.5}>
<Text>42</Text>
</ResponsePanel>
</>
);Streaming Response
import { render } from 'ink';
import { SimpleResponse } from 'parlor';
// Your LLM stream (OpenAI, Anthropic, etc.)
const stream = openai.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: 'Hello!' }],
stream: true,
});
render(
<SimpleResponse
responseStream={stream}
extractContent={(chunk) => chunk.choices[0]?.delta?.content || ''}
/>
);Complete Agent Response
import { render } from 'ink';
import { AgentResponse } from 'parlor';
render(
<AgentResponse
message="Solve the trolley problem"
responseStream={llmStream}
showReasoning={true}
reasoning="Analyzing ethical frameworks..."
toolCalls={[
{ name: 'search_web', args: { query: 'trolley problem' } }
]}
/>
);Markdown with Syntax Highlighting
Content passed to panels automatically renders markdown with syntax highlighting:
import { render } from 'ink';
import { ResponsePanel } from 'parlor';
const content = `Here's a Python example:
\`\`\`python
def hello():
print("Hello, World!")
\`\`\`
And some **bold** and *italic* text.`;
render(
<ResponsePanel>
<Text>{content}</Text>
</ResponsePanel>
);Code blocks are rendered with:
- Dark background (VS Code-style)
- Syntax highlighting for 100+ languages
- Full-width backgrounds
- Language labels
Components
Core Components
Panel- Base bordered panel componentMessagePanel- Cyan-bordered panel for user inputResponsePanel- Blue-bordered panel for AI responses (with elapsed time)ReasoningPanel- Green-bordered panel for thinking/reasoningToolCallsPanel- Yellow-bordered panel for tool executionErrorPanel- Red-bordered panel for errorsWarningPanel- Yellow-bordered panel for warnings
Spinners
ProgressSpinner- Custom animated progress barDotsSpinner- Dots spinner animation
Presets
AgentResponse- Complete agent response layout with all panelsSimpleResponse- Just the response panel with streaming
Hooks
useStreamingContent
Hook for consuming async iterators with state tracking:
const { content, isStreaming, elapsed, error } = useStreamingContent({
iterator: stream,
extractContent: (chunk) => chunk.content,
onComplete: (fullText) => console.log('Done!'),
});useTimer
Simple elapsed time tracker:
const elapsed = useTimer(isActive);Customization
Custom Themes
import { Panel } from 'parlor';
<Panel
title="Custom Panel"
borderColor="magenta"
borderStyle="double"
padding={2}
>
Your content here
</Panel>Border Styles
Available styles: heavy (default), single, double, rounded, bold
import { Panel, HEAVY, SINGLE, DOUBLE, ROUNDED, BOLD } from 'parlor';Examples
See the examples/ directory for complete working examples:
examples/basic.tsx- All panel typesexamples/streaming.tsx- Streaming response with markdownexamples/agent-response.tsx- Complete agent workflow
Run examples:
bun run example:basic
bun run example:streaming
bun run example:agentAPI Reference
Panel Props
interface PanelProps {
children: React.ReactNode;
title?: string;
titleAlign?: 'left' | 'center' | 'right';
borderStyle?: 'heavy' | 'single' | 'double' | 'rounded' | 'bold';
borderColor?: string;
padding?: number | [number, number];
expand?: boolean;
width?: number;
}AgentResponse Props
interface AgentResponseProps<T> {
message?: string;
responseStream?: AsyncIterator<T> | AsyncIterable<T>;
showMessage?: boolean;
showReasoning?: boolean;
reasoning?: string;
toolCalls?: Array<{ name: string; args: Record<string, unknown> }>;
theme?: Theme;
extractContent?: (chunk: T) => string;
}Comparison with Python Rich
| Feature | Parlor | Python Rich | |---------|--------|-------------| | Panels | Yes | Yes | | Live Updates | Yes | Yes | | Streaming | Yes | Yes | | Spinners | Yes | Yes | | Markdown | Yes | Yes | | Syntax Highlighting | Yes | Yes | | Tables | Planned | Yes |
Development
# Install dependencies
bun install
# Build
bun run build
# Watch mode
bun run dev
# Run tests
bun test
# Lint
bun run lint
# Format
bun run format
# Type check
bun run typecheckContributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Run tests and linting (
bun test && bun run lint) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
MIT - see LICENSE for details.
Credits
Inspired by:
- Python Rich by Will McGugan
- Agno - AI agent framework
- Ink - React for terminals
