Download packages/coding-agent/src/modes/interactive/components/custom-message.ts from SaylorTwift/pi: direct link, hf CLI and curl.
- Browser
- Download file 3.1 kB
-
https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/src/modes/interactive/components/custom-message.ts
- Command line
-
hf download hf://SaylorTwift/pi/packages/coding-agent/src/modes/interactive/components/custom-message.ts
-
curl -L -o custom-message.ts https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/src/modes/interactive/components/custom-message.ts
3.1 kB
| import type { TextContent } from "@earendil-works/pi-ai"; | |
| import type { Component } from "@earendil-works/pi-tui"; | |
| import { Box, Container, Markdown, type MarkdownTheme, Spacer, Text } from "@earendil-works/pi-tui"; | |
| import type { MessageRenderer } from "../../../core/extensions/types.ts"; | |
| import type { CustomMessage } from "../../../core/messages.ts"; | |
| import { getMarkdownTheme, theme } from "../theme/theme.ts"; | |
| /** | |
| * Component that renders a custom message entry from extensions. | |
| * Uses distinct styling to differentiate from user messages. | |
| */ | |
| export class CustomMessageComponent extends Container { | |
| private message: CustomMessage<unknown>; | |
| private customRenderer?: MessageRenderer; | |
| private box: Box; | |
| private customComponent?: Component; | |
| private markdownTheme: MarkdownTheme; | |
| private _expanded = false; | |
| private outputPad: number; | |
| constructor( | |
| message: CustomMessage<unknown>, | |
| customRenderer?: MessageRenderer, | |
| markdownTheme: MarkdownTheme = getMarkdownTheme(), | |
| outputPad = 1, | |
| ) { | |
| super(); | |
| this.message = message; | |
| this.customRenderer = customRenderer; | |
| this.markdownTheme = markdownTheme; | |
| this.outputPad = outputPad; | |
| this.addChild(new Spacer(1)); | |
| // Create box with purple background (used for default rendering) | |
| this.box = new Box(1, 1, (t) => theme.bg("customMessageBg", t)); | |
| this.rebuild(); | |
| } | |
| setExpanded(expanded: boolean): void { | |
| if (this._expanded !== expanded) { | |
| this._expanded = expanded; | |
| this.rebuild(); | |
| } | |
| } | |
| setOutputPad(outputPad: number): void { | |
| if (this.outputPad !== outputPad) { | |
| this.outputPad = outputPad; | |
| this.rebuild(); | |
| } | |
| } | |
| override invalidate(): void { | |
| super.invalidate(); | |
| this.rebuild(); | |
| } | |
| private rebuild(): void { | |
| // Remove previous content component | |
| if (this.customComponent) { | |
| this.removeChild(this.customComponent); | |
| this.customComponent = undefined; | |
| } | |
| this.removeChild(this.box); | |
| // Try custom renderer first - it handles its own styling | |
| if (this.customRenderer) { | |
| try { | |
| const component = this.customRenderer( | |
| this.message, | |
| { expanded: this._expanded, outputPad: this.outputPad }, | |
| theme, | |
| ); | |
| if (component) { | |
| // Custom renderer provides its own styled component | |
| this.customComponent = component; | |
| this.addChild(component); | |
| return; | |
| } | |
| } catch { | |
| // Fall through to default rendering | |
| } | |
| } | |
| // Default rendering uses our box | |
| this.addChild(this.box); | |
| this.box.clear(); | |
| // Default rendering: label + content | |
| const label = theme.fg("customMessageLabel", `\x1b[1m[${this.message.customType}]\x1b[22m`); | |
| this.box.addChild(new Text(label, 0, 0)); | |
| this.box.addChild(new Spacer(1)); | |
| // Extract text content | |
| let text: string; | |
| if (typeof this.message.content === "string") { | |
| text = this.message.content; | |
| } else { | |
| text = this.message.content | |
| .filter((c): c is TextContent => c.type === "text") | |
| .map((c) => c.text) | |
| .join("\n"); | |
| } | |
| this.box.addChild( | |
| new Markdown(text, 0, 0, this.markdownTheme, { | |
| color: (text: string) => theme.fg("customMessageText", text), | |
| }), | |
| ); | |
| } | |
| } | |