尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Pi Coding Agent 自定义渲染指南:用 renderCall / renderResult 与自定义消息渲染器完全控制 TUI 界面

Pi Coding Agent 自定义渲染指南:用 renderCall / renderResult 与自定义消息渲染器完全控制 TUI 界面 人工智能AI Agent代码智能体Agent 编排CLIAI 应用【免费下载链接】gsd-2A powerful meta-prompting, context engineering and spec-driven development system that enables agents to work for long periods of time autonomously without losing track of the big picture项目地址https://gitcode.com/gh_mirrors/gs/gsd-2点击查看免费下载自定义渲染Custom Rendering是 gsd-2 的 Pi Coding Agent 扩展体系赋予第三方扩展开发者的“界面控制权”通过renderCall/renderResult钩子接管工具调用与结果的显示方式通过registerMessageRenderer为自定义消息类型注册专属渲染器并借助统一的theme颜色系统与highlightCode语法高亮能力让 TUI终端用户界面中呈现的信息密度、视觉层次和可读性完全由扩展自己决定。本文以 docs/dev/extending-pi/14-custom-rendering-controlling-what-the-user-sees.md 为骨架结合 packages/pi-coding-agent/src/core/extensions/types.ts 等源码实现与测试用例深入讲解三种自定义渲染手段的用法、渲染管线底层原理与常见落地技巧。读完本文你将能够为自己的扩展实现“类原生”的工具展示、结构化消息流与高亮代码块。渲染管线的三种入口工具调用、工具结果与自定义消息在 Pi Coding Agent 的交互式 TUI 中所有展示内容最终都经由“组件Component 主题Theme”两层模型输出到终端。扩展开发者有且只有三类官方渲染入口入口注册方式控制的对象工具调用渲染pi.registerTool({ ..., renderCall })工具调用瞬间、参数尚未执行时的展示工具结果渲染pi.registerTool({ ..., renderResult })工具执行完成后结果内容的展示自定义消息渲染pi.registerMessageRenderer(customType, renderer)通过pi.sendMessage发送的扩展自定义消息从源码结构看这三类入口都汇聚到同一套“工具定义ToolDefinition 主题Theme→ 组件Component”的管线之上渲染函数接收结构化数据与theme返回一个可渲染的组件通常是new Text(text, 0, 0)再由上层 TUI 组件树负责排版、折叠、展开与缓存失效。因此无论你控制的是哪一种展示核心心智模型都是“把数据翻译成带主题的组件”。工具渲染让每一次调用与结果都符合你的语义工具的renderCall与renderResult是ToolDefinition上的可选钩子。查看 types.ts 中的定义/** Custom rendering for tool call display */ renderCall?: (args: StaticTParams, theme: Theme) Component | undefined; /** Custom rendering for tool result display */ renderResult?: ( result: AgentToolResultTDetails, options: ToolRenderResultOptions, theme: Theme, ) Component | undefined;两个钩子的行为差异体现在“输入”上renderCall拿到的是工具入参args即 TypeBox schema 校验后的参数对象renderResult拿到的是工具结果AgentToolResult含content/details/isError等字段以及一个ToolRenderResultOptions见 types.ts其中expanded: boolean—— 当前结果视图是否处于展开状态isPartial: boolean—— 是否为流式/部分结果例如长任务执行过程中的阶段性输出。下面是一个同时实现两个钩子的完整示例摘自关联文档它展示了三种典型的渲染决策调用时用toolTitle加粗工具名、以muted显示动作参数结果未完成时显示warning色的“Processing...”占位结果展开后逐行列出details.itemsimport { Text } from gsd/pi-tui; import { keyHint } from gsd/pi-coding-agent; pi.registerTool({ name: my_tool, // ... renderCall(args, theme) { let text theme.fg(toolTitle, theme.bold(my_tool )); text theme.fg(muted, args.action); return new Text(text, 0, 0); // 0,0 padding — Box handles it }, renderResult(result, { expanded, isPartial }, theme) { if (isPartial) { return new Text(theme.fg(warning, Processing...), 0, 0); } let text theme.fg(success, ✓ Done); if (!expanded) { text (${keyHint(expandTools, to expand)}); } if (expanded result.details?.items) { for (const item of result.details.items) { text \n theme.fg(dim, item); } } return new Text(text, 0, 0); }, });返回值语义与回退机制两个钩子都允许返回undefined或直接抛错TUI 会据此回退到内置渲染而不是让界面崩溃。查看实际渲染管线的实现 tool-execution.ts 可以确认调用端若renderCall返回undefined或抛出异常组件会回退到“工具名标题toolTitlebold 精美化参数”的默认展示结果端若renderResult返回undefined或抛错则回退为原始文本输出toolOutput色没有注册renderResult时也会直接展示getTextOutput()的原始输出未注册任何自定义渲染器、但工具确实在工具库中注册过的自定义工具同样有内置兜底标题取自toolDefinition.label或“gsd_前缀剥离 标题化”的默认行为参见测试用例 tool-execution.test.ts。也就是说自定义渲染是可渐进式采用的增强你可以只为renderCall写渲染器结果沿用默认也可以全部接管。测试 tool-execution.test.ts 还验证了一个关键细节失败结果的状态会原样透传给自定义渲染器——result.isError为true时渲染器能据此输出“custom saw error”之类的差异化文案而不会与内置“failed”状态冲突。keyHint把折叠提示交给标准键位上面的例子使用了keyHint(expandTools, to expand)这是从gsd/pi-coding-agent导入的小工具。它的作用是把“展开/折叠工具”的绑定键位名渲染进提示文案例如(⏎ to expand)。使用它的好处是即便用户自定义了键位绑定提示也会跟随实际键位显示避免硬编码按键造成误导。自定义消息渲染为扩展自己的“消息类型”定制外观如果说工具渲染管的是“动作”那么registerMessageRenderer管的就是“状态与事件流”。扩展可以通过pi.sendMessage发送带customType的自定义消息再为这一类型注册渲染器从而在对话流中插入结构化的状态卡片。关联文档给出的完整对渲染器 发送方如下import { Text } from gsd/pi-tui; pi.registerMessageRenderer(my-extension, (message, options, theme) { const { expanded } options; let text theme.fg(accent, [${message.customType}] ) message.content; if (expanded message.details) { text \n theme.fg(dim, JSON.stringify(message.details, null, 2)); } return new Text(text, 0, 0); }); // Send messages that use this renderer: pi.sendMessage({ customType: my-extension, // Matches the renderer content: Status update, display: true, details: { foo: bar }, });从类型定义看types.ts渲染器签名为(message: CustomMessageT, options: MessageRenderOptions, theme: Theme) Component | undefined其中MessageRenderOptions目前只包含expanded。而注册与派发的底层机制在 loader.ts 中实现每个扩展实例持有一个messageRenderers: Mapstring, MessageRenderer见 types.tsregisterMessageRenderer(customType, renderer)就是把渲染器放入这张映射表key 正是customType。使用时的三条关键约定customType是匹配键sendMessage时传入的customType必须与注册时的字符串严格一致否则找不到渲染器display: true决定是否进入消息流只有display为true时该消息才会显示在界面上文档中该字段用于控制消息对用户可见性未置位则可视为“仅记录”的内部消息details是可选的富数据载荷由于消息渲染器能读到expanded状态常见的做法就是像示例一样折叠态只显示一行摘要展开态再输出JSON.stringify(details, null, 2)的完整结构——这与工具结果渲染的展开/折叠模式完全同构。Theme 颜色系统让输出遵循统一的视觉规范无论是工具渲染器还是消息渲染器第三个参数都是同一个Theme对象。它提供了三组能力前景色theme.fg(color, text)、背景色theme.bg(color, text)与文本样式bold/italic/strikethrough。关联文档完整收录了可用的颜色令牌全部整理如下。前景色theme.fg(color, text)text | accent | muted | dim // General success | error | warning // Status border | borderAccent | borderMuted // Borders toolTitle | toolOutput // Tools toolDiffAdded | toolDiffRemoved // Diffs mdHeading | mdLink | mdCode // Markdown syntaxKeyword | syntaxFunction | syntaxString // Syntax背景色theme.bg(color, text)selectedBg | userMessageBg | customMessageBg toolPendingBg | toolSuccessBg | toolErrorBg文本样式theme.bold(text) theme.italic(text) theme.strikethrough(text)这些令牌的底层实现在 theme.tsfg/bg依据语义色名映射到具体的 ANSI 颜色bold/italic/strikethrough则直接委托给chalk的对应方法。换句话说你写渲染器时使用的并不是某个写死的十六进制颜色而是“语义角色”——当用户在设置中切换主题如经典浅色主题或深色主题时同一段渲染代码会自动跟随新配色无需改动。选择颜色令牌时的实践建议状态语义成功用success、失败用error、进行中用warning与 TUI 内置工具的视觉语言保持一致层级语义标题与工具名用toolTitlebold次要信息用muted更弱化用dim避免整个界面都是最高亮度不要硬编码 ANSI 转义直接在渲染器中写\x1b[31m会绕过主题系统导致主题切换后你的扩展颜色“失联”。在渲染器里做语法高亮highlightCode 与 getLanguageFromPath工具结果或自定义消息常常需要展示代码片段。gsd/pi-coding-agent提供了两个开箱即用的辅助函数均在包入口 index.ts 导出import { highlightCode, getLanguageFromPath } from gsd/pi-coding-agent; const lang getLanguageFromPath(/path/to/file.rs); // rust const highlighted highlightCode(code, lang, theme);getLanguageFromPath(path)根据文件扩展名推断语言标识如file.rs→rust方便你在“读文件类工具”的结果渲染中直接拿到语言highlightCode(code, lang, theme)对代码片段做语法高亮返回已用主题令牌着色的文本。这两者组合后典型的用法是在renderResult中读取某个文件后直接把内容高亮展示pi.registerTool({ name: my_read_tool, // ... renderResult(result, { expanded }, theme) { const lang getLanguageFromPath(result.details.path); const highlighted highlightCode(result.details.content, lang, theme); return new Text(highlighted, 0, 0); }, });从主题实现的源码看语法高亮的分词覆盖了关键字syntaxKeyword、函数syntaxFunction、字符串syntaxString、数字、注释等类别见 theme.ts 附近的扫描逻辑并且 markdown 渲染侧也复用了mdHeading/mdLink/mdCode等令牌theme.ts因此代码块的配色与界面其他区域是一致的。从 TUI 到 HTML 导出自定义渲染器的复用价值值得注意的是自定义渲染器并不仅服务于实时 TUI。仓库中存在一个“工具 HTML 渲染器” tool-renderer.ts它会在导出 HTML 会话记录时查表找到工具的ToolDefinition再次调用同一个renderCall/renderResult把返回的组件按固定宽度默认 100 列渲染成 ANSI 行再经ansiLinesToHtml转成 HTML。折叠态与展开态会分别渲染对应 HTML 导出的折叠/展开交互。这意味着你的自定义渲染器天然具备“一次编写、TUI 与导出双端复用”的价值若工具没有自定义渲染器HTML 导出端会返回undefined并退回到 JSON 兜底见 tool-renderer.ts 的注释与实现若渲染器内部抛错同样会走回退路径不会拖垮整份导出。因此渲染器里请避免副作用不要发起网络请求、不要修改全局状态它可能被以任意宽度、任意次数调用折叠/展开各一次应当是纯“数据 → 组件”的函数。渲染器编写清单常见坑与自查要点综合关联文档、源码实现与测试用例编写自定义渲染器时建议逐条自查始终返回Text或组件或undefinedundefined表示“交给内置回退”不要返回空字符串然后期待框架帮你美化Text的0, 0是标准写法如文档示例注释所说“0,0 padding — Box handles it”组件放入外层Box后由容器负责定位与换行不必自行计算坐标利用expanded/isPartial做分级展示折叠态给摘要展开态给全量列表、JSON、代码流式执行中给占位文案这是 TUI 交互的核心体验isError要透传处理测试证明失败结果会带上isError: true进入renderResult请基于它输出错误语义的颜色与文案而不是一律显示成功所有颜色走theme令牌禁止手写 ANSI 码保证主题可切换性渲染器保持纯函数TUI 与 HTML 导出双端可能以不同宽度/次数调用它customType字符串全局唯一消息渲染器按精确字符串匹配命名冲突会导致串台建议沿用扩展名作为前缀如my-extension。延伸阅读扩展机制总览与开发入门extending-pi/03-getting-started.md、extending-pi/05-extension-structure-styles.md主题与样式体系pi-ui-tui/11-theming-colors-and-styles.md完整 UI API 速查pi-ui-tui/22-quick-reference-all-ui-apis.md工具自定义能力总览含渲染钩子的定位extending-pi/10-custom-tools-giving-the-llm-new-abilities.md可运行的真实扩展示例extensions/google-search其index.ts与extension-manifest.json展示了注册工具与资源的标准写法关键实现文件packages/pi-coding-agent/src/core/extensions/types.ts、packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts、packages/pi-coding-agent/src/modes/interactive/theme/theme.ts赞分享人工智能AI Agent代码智能体Agent 编排CLIAI 应用【免费下载链接】gsd-2A powerful meta-prompting, context engineering and spec-driven development system that enables agents to work for long periods of time autonomously without losing track of the big picture项目地址https://gitcode.com/gh_mirrors/gs/gsd-2点击查看免费下载相关推荐突破ExoPlayer渲染边界自定义渲染器开发终极指南突破ExoPlayer渲染边界自定义渲染器开发终极指南 ExoPlayer作为Android平台上功能强大的媒体播放库其高度可定制的渲染架构为开发者提供了无音视频移动开发OpenAI Responses Starter App部署指南从开发到生产的完整流程OpenAI Responses Starter App部署指南从开发到生产的完整流程 OpenAI Responses Starter App是一个基于NeJupyter Notebook 自定义 CSS 完全指南通过 custom.css 定制界面与 Markdown 渲染样式Jupyter Notebook 自定义 CSS 完全指南通过 custom.css 定制界面与 Markdown 渲染样式 Jupyter Notebook后端前端数据科学上一篇企业级Blazor应用状态管理终极指南ant-design-blazor集成方案下一篇从配置地狱到自动扫描mini-spring组件扫描核心技术解密创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表