<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: OpenTiny</title>
    <description>The latest articles on DEV Community by OpenTiny (@opentiny).</description>
    <link>https://dev.to/opentiny</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1126927%2F5c9dea02-e03a-4d7e-9c45-51d558b2abf9.png</url>
      <title>DEV Community: OpenTiny</title>
      <link>https://dev.to/opentiny</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/opentiny"/>
    <language>en</language>
    <item>
      <title>TinyVue v3.31 Released: New Components &amp; Optimized Documentation With Multiple Practical Feature Upgrades</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Wed, 12 Aug 2026 06:28:49 +0000</pubDate>
      <link>https://dev.to/opentiny/tinyvue-v331-released-new-components-optimized-documentation-with-multiple-practical-feature-clf</link>
      <guid>https://dev.to/opentiny/tinyvue-v331-released-new-components-optimized-documentation-with-multiple-practical-feature-clf</guid>
      <description>&lt;h2&gt;
  
  
  Release Overview
&lt;/h2&gt;

&lt;p&gt;TinyVue v3.31.0 is officially launched, bringing the following updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New Component: SliderButtonGroup (1 new component)&lt;/li&gt;
&lt;li&gt;New Features &amp;amp; Prop Enhancements (6 items): Modal &lt;code&gt;before-close&lt;/code&gt;, Drawer &lt;code&gt;destroyOnClose&lt;/code&gt;, SVG URL encoding for Image, Tag &lt;code&gt;round&lt;/code&gt;, resizable Alert sizes, Switch &lt;code&gt;display-only&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Docs &amp;amp; Demos: Complete API docs and examples for Flowchart component&lt;/li&gt;
&lt;li&gt;Bug Fixes: 52 bug fixes for improved overall stability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full detailed Release Notes: TinyVue v3.31.0 Release Notes&lt;/p&gt;

&lt;h2&gt;
  
  
  New Contributors
&lt;/h2&gt;

&lt;p&gt;We have 3 first-time contributors for this release: @Malusnow, @xuxiao1797, @cfljue. They contributed fixes for dialog-select multi-selection sync, wildcard support for file-upload, and fluent-editor line height formatting respectively. A big welcome to our new partners, and sincere thanks to all new &amp;amp; existing contributors for their hard work on TinyVue 👏&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Breakdown
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. New Component: SliderButtonGroup
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;SliderButtonGroup&lt;/code&gt; is a brand-new component introduced in v3.31.0. Similar to ButtonGroup, it contains multiple SliderButton items. An animated white background slider indicates the active option. When users switch selections, the highlight block slides smoothly between buttons. It supports text &amp;amp; icon variants, plus small / medium / large size options, ideal for page mode switching scenarios.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;tiny-slider-button-group&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"value"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tiny-slider-button&lt;/span&gt; &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Today&lt;span class="nt"&gt;&amp;lt;/tiny-slider-button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tiny-slider-button&lt;/span&gt; &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This Week&lt;span class="nt"&gt;&amp;lt;/tiny-slider-button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tiny-slider-button&lt;/span&gt; &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This Month&lt;span class="nt"&gt;&amp;lt;/tiny-slider-button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/tiny-slider-button-group&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TinySliderButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TinySliderButtonGroup&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@opentiny/vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TinySliderButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TinySliderButtonGroup&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi9jpqnqezrjkm1diwcib.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi9jpqnqezrjkm1diwcib.gif" alt=" " width="634" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Flowchart Component Docs &amp;amp; Examples Completed
&lt;/h3&gt;

&lt;p&gt;We have fully supplemented API documentation and demo cases for the Flowchart component.&lt;br&gt;
Flowchart enables custom workflow diagram creation without third-party libraries. It supports stateful nodes &amp;amp; links, click events on nodes/links/blank canvas areas, and custom node templates via slots. Link styles can be configured through dedicated settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;tiny-flowchart&lt;/span&gt; &lt;span class="na"&gt;:data=&lt;/span&gt;&lt;span class="s"&gt;"data"&lt;/span&gt; &lt;span class="na"&gt;:config=&lt;/span&gt;&lt;span class="s"&gt;"config"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TinyFlowchart&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@opentiny/vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createLink&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TinyFlowchart&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createConfig&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;960&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;createNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submit Application&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2024-01-01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;createNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Supervisor Approval&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2024-01-02&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;createNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Process Completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;createLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 r2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;solid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;createLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 r2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;solid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike traditional DOM-based components, Flowchart renders via Canvas and provides multiple static helper methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;createNode&lt;/code&gt;: Quickly generate node objects&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;createLink&lt;/code&gt;: Generate connection line objects&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;createConfig&lt;/code&gt;: Set canvas width, height and global configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Structured array data can be directly mapped from backend responses without manual coordinate maintenance on the presentation layer.&lt;br&gt;
Supported use cases include basic workflows, card-style branch diagrams, grid route charts, dynamic approval progress updates, click event handling, approver roster display with &lt;code&gt;createItem&lt;/code&gt;, and fully customized node slots.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fquovpl4m0svtfsm1uvw6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fquovpl4m0svtfsm1uvw6.png" alt=" " width="748" height="990"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Existing Component Enhancements
&lt;/h3&gt;

&lt;p&gt;This release delivers multiple practical prop upgrades. The most noteworthy improvement is modal close interception logic: Previously, un-saved form validation logic needed to be handled in outer parent components. Now Modal provides a native &lt;code&gt;before-close&lt;/code&gt; callback to centralize close confirmation workflows.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;New Prop&lt;/th&gt;
&lt;th&gt;Usage Scenario&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Modal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;before-close&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Intercept close actions to prompt users about unsaved edits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drawer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;destroyOnClose&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Destroy internal content on close to retain no residual form state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image&lt;/td&gt;
&lt;td&gt;SVG URL encoding&lt;/td&gt;
&lt;td&gt;Directly render SVG images with special characters in URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tag&lt;/td&gt;
&lt;td&gt;&lt;code&gt;round&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fully rounded tag style&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alert&lt;/td&gt;
&lt;td&gt;size (small / medium)&lt;/td&gt;
&lt;td&gt;Compact alert banner variants&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;display-only&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read-only static display of switch status&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These upgrades require no changes to your business data structures; you can adopt them per component on a page-by-page basis during version upgrade.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Bug Fixes
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Fixed issue where &lt;code&gt;size&lt;/code&gt; prop failed to take effect for buttons inside form-item (PR #4206); adjusted &lt;code&gt;padding-top&lt;/code&gt; of inline form-item to 12px&lt;/li&gt;
&lt;li&gt;DatePicker: Fixed blank panel after half-selection clearing; resolved one-day date offset bug across multi-timezone environments for DatePicker / DatePanel&lt;/li&gt;
&lt;li&gt;FileUpload: Added wildcard support for &lt;code&gt;video/*&lt;/code&gt; and &lt;code&gt;audio/*&lt;/code&gt; MIME types to align with HTTP standards; fixed errors triggered when &lt;code&gt;webkitGetAsEntry()&lt;/code&gt; returns null (PR #4226)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  About OpenTiny NEXT
&lt;/h2&gt;

&lt;p&gt;OpenTiny NEXT is an enterprise-grade intelligent frontend solution built on Generative UI and WebMCP core technologies. It delivers intelligent upgrades for legacy products including the TinyVue component library and TinyEngine low-code engine, while launching Agent-native products such as front-end NEXT-SDKs, AI Extension, TinyRobot AI Assistant and GenUI. The suite empowers AI to interpret user intentions and complete tasks autonomously, accelerating intelligent transformation for enterprise applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the OpenTiny Open Source Community
&lt;/h3&gt;

&lt;p&gt;WeChat Assistant: opentiny-official&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design" rel="noopener noreferrer"&gt;https://opentiny.design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TinyVue Repository: &lt;a href="https://github.com/opentiny/vue" rel="noopener noreferrer"&gt;https://github.com/opentiny/vue&lt;/a&gt; (Star ⭐ appreciated)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you wish to contribute, locate issues tagged &lt;code&gt;good first issue&lt;/code&gt; in the repository. Feel free to leave comments with any questions or feedback!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>GenUI SDK v1.3.0 Released: Cross-Framework Compatibility, One-Click Component Library Switch, Fully Enhanced Renderer &amp; Playground</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Wed, 12 Aug 2026 03:15:47 +0000</pubDate>
      <link>https://dev.to/opentiny/genui-sdk-v130-released-cross-framework-compatibility-one-click-component-library-switch-fully-2nlm</link>
      <guid>https://dev.to/opentiny/genui-sdk-v130-released-cross-framework-compatibility-one-click-component-library-switch-fully-2nlm</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;GenUI SDK is a solution built by the OpenTiny team based on Generative UI concepts, designed to boost display and interactive capabilities of large language models. The SDK delivers integrated front-end &amp;amp; back-end capabilities fully compliant with OpenAI specifications, with built-in Vue and Angular renderers. It supports custom component libraries, interactive behaviors and theme styles. Developers can build AI chat applications from scratch rapidly, or embed Generative UI capabilities into existing business systems.&lt;/p&gt;

&lt;p&gt;We are thrilled to announce the official launch of &lt;strong&gt;GenUI SDK v1.3.0&lt;/strong&gt;. This version iterates around five core directions: decoupled core packages, pluggable material systems, enhanced renderer capabilities, cross-frame collaborative rendering, and comprehensive Playground upgrades. It thoroughly resolves pain points such as tight coupling, weak framework compatibility and limited custom extensibility in earlier releases, making the SDK more flexible, stable and better suited for enterprise intelligent implementation scenarios.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Source Repository: &lt;a href="https://github.com/opentiny/genui-sdk" rel="noopener noreferrer"&gt;https://github.com/opentiny/genui-sdk&lt;/a&gt; (Star ⭐ appreciated!)&lt;/li&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design/genui-sdk" rel="noopener noreferrer"&gt;https://opentiny.design/genui-sdk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Version Feature Overview
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📦 Independent Core Packages &amp;amp; Pluggable Material System
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Standalone core package: &lt;code&gt;@opentiny/genui-sdk-core&lt;/code&gt; published to npm. Low-level core utilities including protocol definitions, prompt generation, streaming Schema parsing, Delta incremental patches and JSON repair can be imported independently for custom Agents and server pipelines.&lt;/li&gt;
&lt;li&gt;Fully decoupled materials: UI materials are completely separated from renderers. Multiple independently publishable material packages are released, supporting one-click switching between OpenTiny and Element Plus component libraries.&lt;/li&gt;
&lt;li&gt;Smooth legacy compatibility: Legacy components are provided for both Vue and Angular, enabling incremental upgrades without massive refactoring of old projects.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ⚡ Renderer Capability Enhancements
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Auto-fill default props: Unified automatic default value injection for Vue and Angular, acting as fallback for streaming rendering.&lt;/li&gt;
&lt;li&gt;New &lt;code&gt;refs&lt;/code&gt; support: Schema can define &lt;code&gt;refs&lt;/code&gt; to directly call component instance methods (e.g. form validation) within methods and event handlers.&lt;/li&gt;
&lt;li&gt;Enhanced custom Actions: Custom interactive Actions support asynchronous execution and transparent return value passing for flexible complex dialogue workflow orchestration.&lt;/li&gt;
&lt;li&gt;New lifecycle hooks: &lt;code&gt;onMounted&lt;/code&gt; and &lt;code&gt;onUnmounted&lt;/code&gt; added to the renderer protocol.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🚀 Cross-Framework Renderer &amp;amp; Full Playground Upgrades
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;One-click switch between Vue and Angular in Playground; mixed framework cards supported within the same chat session.&lt;/li&gt;
&lt;li&gt;A2A v1.0 protocol supported, with automatic fallback to older versions for incompatible external Agents.&lt;/li&gt;
&lt;li&gt;One-click conversion of OpenAPI docs into reusable chat tools.&lt;/li&gt;
&lt;li&gt;Template mode with Schema editing, version history viewing and built-in version control.&lt;/li&gt;
&lt;li&gt;Optional Mini / Standard prompt versions for Vue stacks.&lt;/li&gt;
&lt;li&gt;Chinese &amp;amp; English bilingual UI with persistent language preference memory.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🛡️ Experience &amp;amp; Stability Improvements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bug fixes for notification payload rendering, plain Markdown display, JSON patch logic and more.&lt;/li&gt;
&lt;li&gt;Image content types aligned with OpenAI specifications.&lt;/li&gt;
&lt;li&gt;Clearer prompt rules for API parameter formatting.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧪 Early Access Preview
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Beta React renderer released for early testing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Detailed New Feature Breakdown
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Independent Core Package for Reusable Low-Level Capabilities
&lt;/h3&gt;

&lt;p&gt;In previous versions, all core logic was tightly coupled inside the main SDK bundle, restricting custom development. v1.3.0 fully extracts underlying logic into the standalone &lt;code&gt;@opentiny/genui-sdk-core&lt;/code&gt; package, exposing a complete set of core modules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standardized protocol type definitions&lt;/li&gt;
&lt;li&gt;Intelligent prompt generation logic&lt;/li&gt;
&lt;li&gt;Real-time streaming Schema extraction for LLMs&lt;/li&gt;
&lt;li&gt;Front-end Delta incremental rendering patches&lt;/li&gt;
&lt;li&gt;Automatic JSON repair for AI outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers can utilize core logic separately on servers, custom Agents and AI pipelines without relying on renderers. For example, generate system prompts by combining core utilities and material metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;genPrompt&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/genui-sdk-core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;materialsMeta&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/genui-sdk-materials-vue-element-plus/meta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;systemPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;genPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;materialsMeta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;customActions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submitForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Submit form data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;return&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full signature of &lt;code&gt;genPrompt&lt;/code&gt;:&lt;br&gt;
&lt;code&gt;genPrompt(framework, materialsMeta, customConfig?, options?)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;framework&lt;/code&gt; parameter accepts string literals (&lt;code&gt;'Vue'&lt;/code&gt; / &lt;code&gt;'Angular'&lt;/code&gt;) or custom framework configurations for extended support.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;customConfig&lt;/code&gt; supports injection of custom components, code snippets and custom Actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refer to the Core library documentation for full usage details.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Pluggable Material Architecture: One-Click Switch Between Component Libraries
&lt;/h3&gt;

&lt;p&gt;v1.3.0 completely decouples renderers from UI materials. &lt;code&gt;GenuiChat&lt;/code&gt; and &lt;code&gt;GenuiRenderer&lt;/code&gt; no longer ship with built-in fixed components. All material sets are injected uniformly via &lt;code&gt;GenuiConfigProvider&lt;/code&gt;, realizing a single rendering engine with interchangeable UI material packages.&lt;/p&gt;

&lt;p&gt;Three official material packages are available now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpd9xje6uw7xu6xcurlco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpd9xje6uw7xu6xcurlco.png" alt=" " width="478" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sample integration for Element Plus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;element-plus/dist/index.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GenuiConfigProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GenuiChat&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/genui-sdk-vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;materials&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/genui-sdk-materials-vue-element-plus/materials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;GenuiConfigProvider&lt;/span&gt; &lt;span class="na"&gt;:materials=&lt;/span&gt;&lt;span class="s"&gt;"materials"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;GenuiChat&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/GenuiConfigProvider&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Legacy compatible components are provided for incremental migration of existing projects without full refactoring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;GenuiLegacyRenderer&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;GenuiConfigProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;GenuiLegacyChat&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;GenuiChat&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/genui-sdk-vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. New Chart Components
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;@opentiny/genui-sdk-materials-vue-opentiny-vue&lt;/code&gt; has upgraded its chart suite with multiple new chart types, enabling richer UI layouts. Legacy components also receive matching chart upgrades:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Funnel Chart&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2sh9pj29f3nkpwz5n5um.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2sh9pj29f3nkpwz5n5um.png" alt=" " width="800" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Scatter Chart&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flgzr12u9civ3zdljxxtv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flgzr12u9civ3zdljxxtv.png" alt=" " width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Waterfall Chart&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffqybo41hw8jrrs7vsvqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffqybo41hw8jrrs7vsvqg.png" alt=" " width="800" height="614"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Topology Graph&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgiu3h29xlbjd5z713697.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgiu3h29xlbjd5z713697.png" alt=" " width="799" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gauge Chart&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F15zxiimueahu86mj2whl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F15zxiimueahu86mj2whl.png" alt=" " width="800" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Major Renderer Capability Upgrades
&lt;/h3&gt;

&lt;p&gt;Four key renderer enhancements are delivered to support complex business workflows: default props auto-fill, refs binding, asynchronous custom Actions and lifecycle hooks.&lt;/p&gt;

&lt;h4&gt;
  
  
  (1) Auto-Fill Default Props for Streaming Render Fallback
&lt;/h4&gt;

&lt;p&gt;Many legacy component libraries were not designed for streaming LLM output. When generating Schema incrementally, required props such as &lt;code&gt;options&lt;/code&gt; for Select components may be missing, triggering runtime errors.&lt;/p&gt;

&lt;p&gt;v1.3.0 builds a &lt;code&gt;defaultPropsMap&lt;/code&gt; from material metadata to automatically inject fallback values without overriding user-defined props. Developers can customize baseline defaults (e.g. all buttons default to primary type). LLMs only need to output differentiated configuration instead of full property sets.&lt;/p&gt;

&lt;h4&gt;
  
  
  (2) Refs + Asynchronous Actions for Frontend &amp;amp; Backend Form Validation
&lt;/h4&gt;

&lt;p&gt;Two new optional fields are added to custom Action definitions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;return&lt;/code&gt;: JSON Schema defining return value format (omitted for void actions)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;async&lt;/code&gt;: If set to true, the &lt;code&gt;execute&lt;/code&gt; function returns a Promise; &lt;code&gt;this.callAction()&lt;/code&gt; also returns a Promise, enabling &lt;code&gt;await&lt;/code&gt; / &lt;code&gt;.then()&lt;/code&gt; workflow orchestration for LLMs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sample custom Action for duplicate username backend validation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customActions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;checkUsernameDuplicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;checkUsernameDuplicate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Call backend API to verify whether the username exists&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Username to validate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;return&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;True if username is available&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Validation&lt;/span&gt; &lt;span class="nx"&gt;feedback&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;valid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/user/check-username?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This username is already taken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Username available&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;refs&lt;/code&gt; can be declared on root Schema nodes and bound to component instances via the &lt;code&gt;ref&lt;/code&gt; prop. Instance native APIs such as form validation can be called directly within events and custom JS methods.&lt;/p&gt;

&lt;p&gt;Full registration example for a registration form combining frontend form validation and backend duplicate checking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Page"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"formData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"refs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"formRef"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"methods"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"validateForm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSFunction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"function() { return this.refs.formRef.validate(); }"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"checkUsername"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSFunction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"async function() { return this.callAction('checkUsernameDuplicate', { username: this.state.formData }); }"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"handleSubmit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSFunction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"async function() { try { const formValid = await this.methods.validateForm(); if (!formValid) return; const result = await this.methods.checkUsername(); if (!result.valid) { console.log(result.message); return; } this.callAction('continueChat', { message: 'Registration succeeded, username: ' + this.state.formData.username }); } catch (e) {} }"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"children"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TinyForm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"props"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSExpression"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"this.state.formData"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSExpression"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"this.refs.formRef"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Please enter username"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Username must be longer than 5 characters"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Please enter password"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Password must be longer than 5 characters"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"children"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TinyFormItem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"props"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"prop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"username"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"children"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TinyInput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"props"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"placeholder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enter username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"modelValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSExpression"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"this.state.formData.username"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TinyFormItem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"props"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"prop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"children"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TinyInput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"props"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"placeholder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enter password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"modelValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSExpression"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"this.state.formData.password"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TinyFormItem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"children"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TinyButton"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"props"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Register"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"onClick"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSFunction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"function() { this.methods.handleSubmit(); }"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  (3) Lifecycle Hooks for Business Data Loading
&lt;/h4&gt;

&lt;p&gt;Two new lifecycle hooks &lt;code&gt;onMounted&lt;/code&gt; and &lt;code&gt;onUnmounted&lt;/code&gt; are added to the renderer protocol to enable AI-generated pages to actively request backend data.&lt;br&gt;
Streamed Schema chunks render incrementally, but lifecycle logic only executes once after the full Schema payload is received.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;onMounted&lt;/code&gt;: Trigger page initialization logic such as data fetching&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onUnmounted&lt;/code&gt;: Clean up requests and event listeners to prevent memory leaks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sample table page loading employee data on mount:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Page"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"tableData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"methods"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"loadTableData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSFunction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"async function() { const result = await this.callAction('fetchEmployeeList'); this.state.tableData = result.data; }"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lifeCycles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"onMounted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSFunction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"function() { this.methods.loadTableData(); }"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"children"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"componentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TinyGrid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"props"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JSExpression"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"this.state.tableData"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"columns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Employee ID"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Department"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Comprehensive Playground Upgrades
&lt;/h3&gt;

&lt;p&gt;Following Skill and A2A support in v1.2.0, v1.30 optimizes the overall Playground user experience with multiple major features:&lt;/p&gt;

&lt;h4&gt;
  
  
  (1) Cross-Framework One-Click Switch &amp;amp; Mixed Sessions
&lt;/h4&gt;

&lt;p&gt;The unified base engine supports both Vue and Angular without forced stack selection.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-click framework toggle, with prompt generation and rendering engine auto-adaptation. Framework preference persists across sessions.&lt;/li&gt;
&lt;li&gt;Mixed framework cards supported within a single chat session for side-by-side comparison of UI and code output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5curcfu1uhpu0381vk6x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5curcfu1uhpu0381vk6x.gif" alt=" " width="760" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  (2) A2A v1.0 Protocol Support
&lt;/h4&gt;

&lt;p&gt;Playground fully implements the official A2A v1.0 standard, enabling standardized communication between Agents and applications.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;External third-party Agents can be registered as reusable tools to assemble multi-AI workflows.&lt;/li&gt;
&lt;li&gt;Built-in version fallback logic: Automatically downgrade protocol compatibility if external Agents run older A2A versions without manual conditional logic.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5cizyckfzt9edr4htu35.gif" alt=" " width="600" height="285"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sample external Agent link for specification Q&amp;amp;A:&lt;br&gt;
&lt;code&gt;https://specification.website/.well-known/agent-card.json&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  (3) OpenAPI to Tool Conversion
&lt;/h4&gt;

&lt;p&gt;Native OpenAPI parser integrated into Playground. Three import modes supported: input document URL, paste raw content or upload local files.&lt;br&gt;
All defined APIs are auto-converted into callable chat tools with one click. Custom request headers and service base URLs can be configured for authentication, eliminating backend refactoring requirements to integrate business systems into AI chat workflows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwyvd7ye9pc2lkcappjs8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwyvd7ye9pc2lkcappjs8.gif" alt=" " width="600" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  (4) Template Version Control
&lt;/h4&gt;

&lt;p&gt;Template mode supports inline Schema editing and real-time previews. New version history feature:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auto-save each Schema iteration as a separate version card&lt;/li&gt;
&lt;li&gt;Visual diff comparison between revisions&lt;/li&gt;
&lt;li&gt;One-click rollback to historical templates
Simplifies debugging, cross-team scheme comparison and version traceability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnywpdkzs4vxaxeriaf8k.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnywpdkzs4vxaxeriaf8k.gif" alt=" " width="560" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  (5) Optional Vue Prompt Versions
&lt;/h4&gt;

&lt;p&gt;Two prompt suites available for Vue development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mini: Lightweight, only includes core form &amp;amp; table components to cut token consumption&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe4jbnudgs60di2sbneuz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe4jbnudgs60di2sbneuz.png" alt=" " width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard: Adds full chart component support for data visualization scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ficv9zxmxa2lipna9abj3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ficv9zxmxa2lipna9abj3.png" alt=" " width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  (6) Bilingual Internationalization
&lt;/h4&gt;

&lt;p&gt;Playground UI supports Chinese / English switch via bottom-left control. Language preferences are automatically saved and restored for new sessions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwmewnnaqpz5g3kiwm2hu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwmewnnaqpz5g3kiwm2hu.gif" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Beta React Renderer Release
&lt;/h2&gt;

&lt;p&gt;The official alpha React renderer is launched, paired with Ant Design material packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Core package: &lt;code&gt;@opentiny/genui-sdk-react@1.3.0-alpha.1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Material package: &lt;code&gt;@opentiny/genui-sdk-materials-react-antd@1.3.0-alpha.1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prompt Generation Sample
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;genPrompt&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/genui-sdk-core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;materialsMeta&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/genui-sdk-materials-react-antd/meta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;systemPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;genPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;React&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;materialsMeta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Component Usage Sample
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GenuiConfigProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GenuiRenderer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/genui-sdk-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSchema&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GenuiConfigProvider&lt;/span&gt; &lt;span class="na"&gt;materials&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;materials&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GenuiRenderer&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rendererKey&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;GenuiConfigProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6rgwtbyfkbaxrhxddk4s.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6rgwtbyfkbaxrhxddk4s.gif" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Stability Fixes &amp;amp; Optimizations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Optimized plain Markdown fallback rendering for pages without UI components&lt;/li&gt;
&lt;li&gt;Hardened JSON Patch incremental rendering logic, standardized component ID allocation to avoid layout corruption&lt;/li&gt;
&lt;li&gt;Image schema formats fully aligned with OpenAI standards for universal LLM compatibility&lt;/li&gt;
&lt;li&gt;Stricter prompt parameter validation rules to reduce invalid model outputs&lt;/li&gt;
&lt;li&gt;Fixed runtime errors when &lt;code&gt;refs&lt;/code&gt; returns empty objects during streaming rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Version Summary
&lt;/h2&gt;

&lt;p&gt;GenUI SDK v1.3.0 is a major architectural overhaul combining decoupling, capability expansion and UX upgrades:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Core independent packages + pluggable material architecture drastically improve SDK extensibility&lt;/li&gt;
&lt;li&gt;Renderer layer optimizations resolve critical production pain points for streaming and complex interactive UIs&lt;/li&gt;
&lt;li&gt;Playground upgrades lower development barriers, with forward-looking support for React and A2A v1.0 to fully meet enterprise intelligent transformation demands&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All developers are welcome to upgrade and test. Submit bugs or feature requests via GitHub Issues, and star the repository to support open-source collaboration!&lt;br&gt;
Full release notes: v1.3.0 Release Page&lt;/p&gt;

&lt;h2&gt;
  
  
  About OpenTiny NEXT
&lt;/h2&gt;

&lt;p&gt;OpenTiny NEXT is an enterprise intelligent front-end solution built on Generative UI and WebMCP core technologies. It delivers intelligent upgrades for legacy products including the TinyVue component library and TinyEngine low-code engine, while launching Agent-native products such as front-end NEXT-SDKs, AI Extension, TinyRobot AI Assistant and GenUI. It enables AI to interpret user intentions and complete tasks autonomously, accelerating enterprise intelligent transformation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the OpenTiny Open Source Community
&lt;/h3&gt;

&lt;p&gt;WeChat Assistant: opentiny-official&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design" rel="noopener noreferrer"&gt;https://opentiny.design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GenUI SDK Repository: &lt;a href="https://github.com/opentiny/genui-sdk" rel="noopener noreferrer"&gt;https://github.com/opentiny/genui-sdk&lt;/a&gt; (Star ⭐ appreciated)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To contribute, locate issues tagged &lt;code&gt;good first issue&lt;/code&gt; in the repository. Feel free to share questions and feedback in comment sections!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Bloat-Free Extensibility: The Evolution of TinyRobot — From a Simple AI Input Box to a Fully-Featured AI Input Console</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Fri, 31 Jul 2026 07:47:11 +0000</pubDate>
      <link>https://dev.to/opentiny/bloat-free-extensibility-the-evolution-of-tinyrobot-from-a-simple-ai-input-box-to-a-1nig</link>
      <guid>https://dev.to/opentiny/bloat-free-extensibility-the-evolution-of-tinyrobot-from-a-simple-ai-input-box-to-a-1nig</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;At the very beginning of AI chat development, an input box plus a send button was all you needed. But as AI capabilities expanded to support file uploads, voice input, LLM switching, web search, deep reasoning and more, the bottom input area gradually turned into an all-in-one AI console.&lt;/p&gt;

&lt;p&gt;This article uses TinyRobot’s &lt;code&gt;Sender&lt;/code&gt; component as an example. We break down how the component’s scope expanded alongside evolving business requirements, and discuss architectural improvements that boost component flexibility and adaptability.&lt;/p&gt;

&lt;h2&gt;
  
  
  I. Sender Component Bloats As Requirements Pile Up
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stage 1: Minimalist Basic AI Input Box
&lt;/h3&gt;

&lt;p&gt;In early project phases, requirements were simple — only core chat functionality was needed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Type messages and send with one click&lt;/li&gt;
&lt;li&gt;Interrupt AI output mid-generation&lt;/li&gt;
&lt;li&gt;Clear input content in one tap, with maximum character limit to avoid overly long text&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu9vda5xrfw7gdh39xea0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu9vda5xrfw7gdh39xea0.png" alt=" " width="797" height="128"&gt;&lt;/a&gt;&lt;br&gt;
Minimal sample code (size &amp;amp; debug configurations omitted):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;TrSender&lt;/span&gt;
  &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;
  &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Send a message to AI..."&lt;/span&gt;
  &lt;span class="na"&gt;:loading=&lt;/span&gt;&lt;span class="s"&gt;"loading"&lt;/span&gt;
  &lt;span class="na"&gt;clearable&lt;/span&gt;
  &lt;span class="na"&gt;show-word-limit&lt;/span&gt;
  &lt;span class="na"&gt;:max-length=&lt;/span&gt;&lt;span class="s"&gt;"2000"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit=&lt;/span&gt;&lt;span class="s"&gt;"sendMessage"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;cancel=&lt;/span&gt;&lt;span class="s"&gt;"stopGeneration"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this stage, the &lt;code&gt;Sender&lt;/code&gt; only handled text input, character counting, and content clearing. The send button automatically switches to a stop button when the AI streams responses — nothing more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 2: Feature Explosion — Input Box Becomes AI Console
&lt;/h3&gt;

&lt;p&gt;As business iteration accelerated, plain text chat was no longer sufficient. A full suite of auxiliary capabilities was added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File &amp;amp; image upload with preview (&lt;code&gt;TrUploadButton&lt;/code&gt;, &lt;code&gt;TrAttachments&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Voice-to-text input (&lt;code&gt;TrVoiceButton&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Dynamic LLM model switching (&lt;code&gt;ModelSelector&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;One-click deep reasoning mode (&lt;code&gt;DeepThinking&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Real-time web search for up-to-date information (&lt;code&gt;WebSearch&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1b2z7ahkslwowbthwzxu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1b2z7ahkslwowbthwzxu.png" alt=" " width="798" height="131"&gt;&lt;/a&gt;&lt;br&gt;
All features are embedded via component slots. Key code snippet extracted from live demos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Core TinyRobot Sender Component --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;TrSender&lt;/span&gt;
  &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;
  &lt;span class="na"&gt;mode=&lt;/span&gt;&lt;span class="s"&gt;"multiple"&lt;/span&gt;
  &lt;span class="na"&gt;:has-external-content=&lt;/span&gt;&lt;span class="s"&gt;"attachments.length &amp;gt; 0"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- Top Slot: Attachment Display --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;#header&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"attachments.length"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TrAttachments&lt;/span&gt; &lt;span class="na"&gt;v-model:items=&lt;/span&gt;&lt;span class="s"&gt;"attachments"&lt;/span&gt; &lt;span class="na"&gt;:actions=&lt;/span&gt;&lt;span class="s"&gt;"[]"&lt;/span&gt; &lt;span class="na"&gt;variant=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt; &lt;span class="na"&gt;wrap&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Bottom Left Slot: Model &amp;amp; Feature Toggles --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;#footer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ModelSelector&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;DeepThinking&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;WebSearch&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Bottom Right Slot: Upload &amp;amp; Voice Buttons --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;#footer-right&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TrUploadButton&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"addFiles"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TrVoiceButton&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/TrSender&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While features were split into standalone sub-components embedded via slots (to avoid bloated props lists and enable reuse across pages), critical limitations remained:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fixed slot positions: Upload/voice buttons cannot be rearranged; DOM hierarchy is locked inside the Sender.&lt;/li&gt;
&lt;li&gt;Manual state sync: Developers must manually pass the &lt;code&gt;has-external-content&lt;/code&gt; flag to notify the Sender of attachments.&lt;/li&gt;
&lt;li&gt;Constant API expansion: New features require new slots and props as functionality grows.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In short: Although TinyRobot split discrete sub-components, the overall page layout and element positions remained controlled by the Sender, limiting full customization for business scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 3: Severe UI Divergence Between PC &amp;amp; Mobile
&lt;/h3&gt;

&lt;p&gt;Desktop screens have ample space to display all buttons in full text, while mobile interfaces demand compact, condensed layouts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PC: Full text buttons for model selection, reasoning and search; upload/voice buttons fully visible&lt;/li&gt;
&lt;li&gt;Mobile: Only icons for core features; attachments hidden inside an expandable menu; tap microphone to switch to full-screen long-press voice input, tap keyboard icon to revert to text typing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1ggbyws9ga7u0f41znse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1ggbyws9ga7u0f41znse.png" alt=" " width="800" height="424"&gt;&lt;/a&gt;&lt;br&gt;
This forced heavy conditional logic with repeated &lt;code&gt;isMobile&lt;/code&gt; checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;TrSender&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="na"&gt;mode=&lt;/span&gt;&lt;span class="s"&gt;"multiple"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- Replace text input with voice panel on mobile --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;#content&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"isMobile &amp;amp;&amp;amp; voiceMode"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;VoiceHoldButton&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Differentiated Footer Toolbar for PC/Mobile --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;#footer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"isMobile"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;MoreActions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;TrUploadButton&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"addFiles"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/MoreActions&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ModelSelector&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt; &lt;span class="na"&gt;compact&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;DeepThinking&lt;/span&gt; &lt;span class="na"&gt;icon-only&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;WebSearch&lt;/span&gt; &lt;span class="na"&gt;icon-only&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ModelSelector&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;DeepThinking&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;WebSearch&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Right-Side Action Bar Split by Device --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;#footer-right&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"isMobile"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;InputModeToggle&lt;/span&gt; &lt;span class="na"&gt;:mode=&lt;/span&gt;&lt;span class="s"&gt;"voiceMode ? 'keyboard' : 'voice'"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"voiceMode = !voiceMode"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;TrUploadButton&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"addFiles"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;TrVoiceButton&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/TrSender&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary of Early Pain Points
&lt;/h3&gt;

&lt;p&gt;Stage 2 already introduced rigid UI structures and tedious manual state synchronization. Mobile adaptation in Stage 3 amplified these issues, resulting in bloated, hard-to-maintain conditional code. Three core problems needed a fundamental refactor:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Share unified state &amp;amp; logic across PC/mobile without duplicate input/submit implementations&lt;/li&gt;
&lt;li&gt;Auto-detect attachments and external content without manual boolean flags&lt;/li&gt;
&lt;li&gt;Avoid continuous additions of props/slots when supporting new features or device types&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following sections detail architectural refactors that resolve these three core limitations.&lt;/p&gt;

&lt;h2&gt;
  
  
  II. Separate Logic &amp;amp; Layout: Shared Core Capabilities, Independent Terminal UI
&lt;/h2&gt;

&lt;p&gt;The original Sender tightly coupled state, interaction logic and DOM layout. The key improvement decouples them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SenderRoot&lt;/code&gt;: Acts as the core capability container, solely responsible for input, submission, loading and underlying logic&lt;/li&gt;
&lt;li&gt;Layout structure, button positioning and visual design are fully controlled by business developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PC and mobile share identical core functionality (text input, message submission, stream interruption, attachment management, model switching, reasoning/search toggles, text/voice toggle) — the only difference is layout arrangement due to screen size constraints.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desktop Layout (Sufficient Screen Space, All Buttons Fully Visible)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SenderRoot&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;SenderAttachments&lt;/span&gt; &lt;span class="na"&gt;v-model:items=&lt;/span&gt;&lt;span class="s"&gt;"attachments"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;SenderEditor&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;footer&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"desktop-toolbar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ModelSelector&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;DeepThinking&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;WebSearch&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"desktop-actions"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SenderUploadButton&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"addFiles"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SenderVoiceButton&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SenderSubmit&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/SenderRoot&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mobile Layout (Compact Space, Foldable Low-Frequency Features)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SenderRoot&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;SenderAttachments&lt;/span&gt; &lt;span class="na"&gt;v-model:items&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- Toggle between text editor and voice long-press panel --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;SenderEditor&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"inputMode === 'text'"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;VoiceHoldButton&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;footer&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mobile-toolbar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;MoreActionsTrigger&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ModelSelector&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt; &lt;span class="na"&gt;compact&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;DeepThinking&lt;/span&gt; &lt;span class="na"&gt;icon-only&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;WebSearch&lt;/span&gt; &lt;span class="na"&gt;icon-only&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;InputModeToggle&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SenderSubmit&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Expandable upload menu --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;MoreActions&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"moreActionsOpen"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SenderUploadButton&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"addFiles"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/MoreActions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/SenderRoot&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cross-Device Implementation
&lt;/h3&gt;

&lt;p&gt;For documentation demonstration, both layouts can coexist with device detection logic; in production, render only the matching layout inside &lt;code&gt;SenderRoot&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SenderRoot&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="na"&gt;:loading=&lt;/span&gt;&lt;span class="s"&gt;"loading"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"isDesktop"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Full desktop layout code above --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Compact mobile layout code above --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/SenderRoot&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switching devices only swaps DOM markup — message text, attachments, selected LLM and loading state remain unchanged and will not reset. Temporary UI states (panel expansion) reset when components unmount.&lt;/p&gt;

&lt;p&gt;Key advantage: No new props or slots required for multi-terminal support; identical underlying logic with fully customizable layout arrangements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate Summary
&lt;/h3&gt;

&lt;p&gt;This composable architecture resolves two original pain points:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reuse identical state &amp;amp; logic across PC/mobile with fully customizable layouts&lt;/li&gt;
&lt;li&gt;No breaking API changes or new slots when adapting to new devices&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, a new issue emerged: If PC/mobile layouts are extracted into standalone components, attachment and model state must be passed down layer by layer, leading to bloated props lists again. Further decoupling via Context is required.&lt;/p&gt;

&lt;h2&gt;
  
  
  III. Decouple via Layered Context: Eliminate Prop Drilling
&lt;/h2&gt;

&lt;p&gt;While separate desktop/mobile layouts clean up code, extracting them into independent &lt;code&gt;DesktopSenderLayout&lt;/code&gt; and &lt;code&gt;MobileSenderLayout&lt;/code&gt; introduces heavy prop drilling for attachments, selected models and disabled states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SenderRoot&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="na"&gt;:loading=&lt;/span&gt;&lt;span class="s"&gt;"loading"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;DesktopSenderLayout&lt;/span&gt;
    &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"isDesktop"&lt;/span&gt;
    &lt;span class="na"&gt;v-model:attachments=&lt;/span&gt;&lt;span class="s"&gt;"attachments"&lt;/span&gt;
    &lt;span class="na"&gt;v-model:model=&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt;
    &lt;span class="na"&gt;:disabled=&lt;/span&gt;&lt;span class="s"&gt;"disabled"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;MobileSenderLayout&lt;/span&gt;
    &lt;span class="na"&gt;v-else&lt;/span&gt;
    &lt;span class="na"&gt;v-model:attachments=&lt;/span&gt;&lt;span class="s"&gt;"attachments"&lt;/span&gt;
    &lt;span class="na"&gt;v-model:model=&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt;
    &lt;span class="na"&gt;:disabled=&lt;/span&gt;&lt;span class="s"&gt;"disabled"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/SenderRoot&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As features expand, the layout components accumulate dozens of props. The solution splits state into two Context layers: universal core capabilities and domain-specific business data, shared across all child components without prop drilling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: Global Sender Context for Universal Core Logic
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;SenderRoot&lt;/code&gt; injects a global context exposing core chat functionality (text binding, loading, submission, clearing, stream cancellation) accessible to all descendant components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Inside SenderRoot&lt;/span&gt;
&lt;span class="nf"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;senderContextKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;maxLength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;canSubmit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;SenderEditor&lt;/code&gt; input component no longer requires bound values passed from parents; it directly consumes the context for text binding, keyboard submission and line break logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Inside SenderEditor&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxLength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSenderContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLTextAreaElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleKeydown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;KeyboardEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shiftKey&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isComposing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SenderEditor&lt;/code&gt; can be placed anywhere inside the SenderRoot DOM tree, with no fixed slot constraints. Only presentation-specific props such as &lt;code&gt;placeholder&lt;/code&gt; remain. Layout components no longer need to forward core state, eliminating massive prop lists. Model selection and reasoning toggles remain business logic and are not injected into the global context to avoid bloating SenderRoot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Domain-specific Context, Independent Closed-loop Management of Attachment States
&lt;/h3&gt;

&lt;p&gt;The SenderRoot Context eliminates the transparent transmission of common capabilities such as input, loading, and submission, but attachments still need to be shared between the upload button, the attachment list, and the two Layouts. If external Refs are still used, each Layout would need to receive the same attachment Props and events:&lt;br&gt;&lt;br&gt;
This is because SenderAttachments is the consumer of the attachments, while SenderUploadButton is the producer of the attachments. When they are used as sibling nodes, the business logic needs to connect them using Refs and events.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbgqgrrt1q2hfz9467f38.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbgqgrrt1q2hfz9467f38.png" alt=" " width="799" height="315"&gt;&lt;/a&gt;&lt;br&gt;
The &lt;code&gt;attachmentsRef&lt;/code&gt; and &lt;code&gt;addFiles&lt;/code&gt; in this context actually belong to the attachment domain. Currently, they are held by the business layer solely to connect the producers and consumers of attachments. If each business logic repeatedly writes this layer of wiring, composable components still do not encapsulate a complete collaborative attachment capability.  &lt;/p&gt;

&lt;p&gt;Therefore, a &lt;code&gt;SenderAttachmentProvider&lt;/code&gt; can be introduced. It uniformly holds the attachment state and operation methods and provides them to descendant components through the Context. The Provider is placed on the smallest common ancestor of the producer and consumer, establishing only the data scope without dictating their DOM positions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SenderRoot&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;SenderAttachmentProvider&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SenderAttachments&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SenderEditor&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SenderUploadButton&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SenderSubmit&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/SenderAttachmentProvider&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/SenderRoot&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Attachment context interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SenderAttachmentContext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Attachment&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;addFiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;File&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
  &lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
  &lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Upload buttons call &lt;code&gt;addFiles&lt;/code&gt; to append files&lt;/li&gt;
&lt;li&gt;Attachment lists read &lt;code&gt;items&lt;/code&gt; and trigger &lt;code&gt;remove&lt;/code&gt; for deletion&lt;/li&gt;
&lt;li&gt;All attachment state logic is encapsulated within the provider, no manual state sync required for business code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Unified Submission Registry Protocol
&lt;/h3&gt;

&lt;p&gt;Early designs required manual &lt;code&gt;has-external-content&lt;/code&gt; boolean flags to notify the Sender of attachments. We introduced a content registration protocol where all external data sources self-register to SenderRoot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SenderContentRegistry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;registerContent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MaybeRefOrGetter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;source&lt;/code&gt;: Data type identifier (attachments, knowledge base, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;payload&lt;/code&gt;: Complete structured data&lt;/li&gt;
&lt;li&gt;Return: Cleanup function auto-unregistered when components unmount&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The attachment provider automatically registers attachment data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;unregister&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;registerContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;attachments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On submission, the &lt;code&gt;submit&lt;/code&gt; event returns all registered external data alongside text content in one payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contents&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;SenderSubmission&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;attachments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;attachments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fully resolves the three original core challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Unified state &amp;amp; logic reused across PC/mobile with fully customizable layouts&lt;/li&gt;
&lt;li&gt;Attachments auto-included in submission logic without manual boolean flags&lt;/li&gt;
&lt;li&gt;New data types only require new source identifiers, no breaking changes to Sender APIs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Final clean layout code after layered context refactor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SenderRoot&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="na"&gt;:loading=&lt;/span&gt;&lt;span class="s"&gt;"loading"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;SenderAttachmentProvider&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;DesktopSenderLayout&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"isDesktop"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;MobileSenderLayout&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/SenderAttachmentProvider&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/SenderRoot&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Model selection and other business modules can still pass props directly when appropriate. General rule: Share data across multiple components via dedicated Provider; independent simple components use direct props. State ownership belongs to the nearest common ancestor of all consuming components.&lt;/p&gt;

&lt;h2&gt;
  
  
  IV. Two-Tier API: Balance Flexibility &amp;amp; Development Speed
&lt;/h2&gt;

&lt;p&gt;The fully composable atomic architecture delivers maximum layout freedom, but requires assembling dozens of components for simple use cases — similar to headless UI design patterns (e.g. shadcn/ui). TinyRobot implements a dual-layer API system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Low-Level Composable Atomic Components: &lt;code&gt;SenderRoot&lt;/code&gt;, &lt;code&gt;SenderEditor&lt;/code&gt;, &lt;code&gt;SenderAttachments&lt;/code&gt; etc. For deeply customized, highly differentiated multi-terminal scenarios with full layout control.&lt;/li&gt;
&lt;li&gt;High-Level Wrapped Preset Component: The original &lt;code&gt;Sender&lt;/code&gt; component with built-in standard layouts for rapid out-of-box development.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both layers share identical underlying core logic with no separate codebases. Simple projects use the wrapped component for fast integration; complex cross-terminal projects can drop down to atomic building blocks for unlimited customization.&lt;/p&gt;

&lt;p&gt;Core principle: Preset components accelerate rapid development, while composable atomic components enable unlimited structural modification.&lt;/p&gt;

&lt;h2&gt;
  
  
  About OpenTiny NEXT
&lt;/h2&gt;

&lt;p&gt;OpenTiny NEXT is an enterprise-grade intelligent frontend solution built on Generative UI and WebMCP core technologies. It delivers intelligent upgrades for legacy products including the TinyVue component library and TinyEngine low-code engine, while launching Agent-native products such as frontend NEXT-SDKs, AI Extension, TinyRobot AI Assistant and GenUI. The platform enables AI to interpret user intentions and complete tasks autonomously, accelerating enterprise intelligent transformation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the OpenTiny Open Source Community
&lt;/h3&gt;

&lt;p&gt;WeChat Assistant: opentiny-official&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TinyRobot Official Website: &lt;a href="https://opentiny.design/tiny-robot" rel="noopener noreferrer"&gt;https://opentiny.design/tiny-robot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TinyRobot GitHub Repository: &lt;a href="https://github.com/opentiny/tiny-robot" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-robot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you wish to contribute, look for issues tagged &lt;code&gt;good first issue&lt;/code&gt; within the repository. Feel free to leave comments with any questions or feedback!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>TinyRobot v0.5.0 Released: Brand-New Capabilities Including Agent Skills, Navigation &amp; Custom Layouts Launched Simultaneously</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Tue, 21 Jul 2026 07:48:33 +0000</pubDate>
      <link>https://dev.to/opentiny/tinyrobot-v050-released-brand-new-capabilities-including-agent-skills-navigation-custom-5856</link>
      <guid>https://dev.to/opentiny/tinyrobot-v050-released-brand-new-capabilities-including-agent-skills-navigation-custom-5856</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;TinyRobot is a front-end interaction framework exclusively built for AI applications. It empowers teams to rapidly build enterprise AI assistants, intelligent customer service platforms and multi-turn dialogue systems. Built on the OpenTiny design system, Tiny delivers full capabilities covering dialogue UI, streaming rendering and session management. Developers can build consistent, extensible AI products without developing complex interaction logic from scratch — functional AI applications can be finished within hours from initial prototypes.&lt;/p&gt;

&lt;p&gt;We are proud to announce the official release of &lt;strong&gt;TinyRobot v0.5.0&lt;/strong&gt;. This release is far more than just a handful of new components; it drastically simplifies the entire workflow of building AI chat applications.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Source Repository: &lt;a href="https://github.com/opentiny/tiny-robot" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-robot&lt;/a&gt; (Star ⭐ appreciated!)&lt;/li&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design/tiny-robot" rel="noopener noreferrer"&gt;https://opentiny.design/tiny-robot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to test this version. If you have suggestions, ideas or issues during usage, submit feedback via GitHub Issues, PRs or discussion threads to help us refine TinyRobot together.&lt;/p&gt;

&lt;h2&gt;
  
  
  v0.5.0 Feature Overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[New Feature] Agent Skills support added&lt;/li&gt;
&lt;li&gt;[New Component] Anchor: content navigation component for lengthy answers &amp;amp; dialogues&lt;/li&gt;
&lt;li&gt;[New Component] Layout: layout component supporting standard &amp;amp; floating modes&lt;/li&gt;
&lt;li&gt;[New Tool] CLI scaffolding: spin up a TinyRobot project with one single command&lt;/li&gt;
&lt;li&gt;Miscellaneous interaction refinements &amp;amp; bug fixes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In-Depth Breakdown of TinyRobot v0.5.0 New Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. New Feature: Agent Skills Support
&lt;/h3&gt;

&lt;p&gt;Agent Skills is a lightweight, open format designed to extend AI Agent capabilities via professional domain knowledge and standardized workflows. Each Skill is a directory containing a &lt;code&gt;SKILL.md&lt;/code&gt; file, which records skill name, description and task specifications. The directory may also attach reference documents and template files.&lt;/p&gt;

&lt;p&gt;Within TinyRobot Kit, Skills from different sources are normalized into unified &lt;code&gt;SkillDefinition&lt;/code&gt; objects. Applications can activate appropriate Skills based on current scenarios, guiding LLMs to follow defined rules when answering questions or executing tasks. Teams can isolate business logic and task requirements as reusable Skills across multiple projects and chat scenarios.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdlqsa4tnm7jyejslalv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdlqsa4tnm7jyejslalv2.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a Skill is enabled for a conversation, &lt;code&gt;skillPlugin&lt;/code&gt; parses the target Skill and generates corresponding instruction prompts and runtime tools. The plugin does not hardcode how instructions are passed to LLMs; developers can inject instructions into system messages, user messages or dedicated request fields based on the LLM provider’s protocol. If a Skill includes reference files, the model can fetch file content on demand via built-in runtime tools.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: &lt;code&gt;vue-best-practices&lt;/code&gt; Skill
&lt;/h4&gt;

&lt;p&gt;After enabling this Skill on the frontend, users can ask Vue development questions, and the LLM will strictly follow standardized Vue specifications. When users need deeper details about reactivity, single-file components or component data flow, the model can retrieve attached reference materials from the Skill directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkh133w85zg9u4tyhofvu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkh133w85zg9u4tyhofvu.gif" alt=" " width="760" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1.1 Load Skills From Multiple Sources
&lt;/h4&gt;

&lt;p&gt;TinyRobot Kit supports loading Skills from browser local files, Node.js file systems and GitHub repositories. Developers can let users select local Skill folders on the page, load preconfigured Skill directories from the server, or directly use centrally maintained repository Skills.&lt;br&gt;
All Skill sources will be normalized into identical definition structures after loading, so the chat workflow logic does not need to distinguish their original origins. This design fits both quick local testing and centralized team version control via code repositories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2he27cxshcqhmo020due.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2he27cxshcqhmo020due.png" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  1.2 Persist &amp;amp; Reuse Skills
&lt;/h4&gt;

&lt;p&gt;TinyRobot provides multiple storage adapters for different runtime environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memory Storage: for temporary preview and testing&lt;/li&gt;
&lt;li&gt;IndexedDB Storage: persist user-imported Skills across browser sessions&lt;/li&gt;
&lt;li&gt;File System Storage: for Node.js services and projects with local directory structures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Applications can import and save Skills first, then load them by name for subsequent chat sessions. Skill persistence status is decoupled from UI toggle states — developers can implement custom interaction controls such as checkboxes or dropdowns to activate Skills freely.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1km9lggea6vl2n24lqzk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1km9lggea6vl2n24lqzk.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  1.3 Integrate Skills Into Chat Workflows
&lt;/h4&gt;

&lt;p&gt;In chat scenarios, applications can either activate user-selected Skills directly, or pass candidate Skills to the LLM for automatic matching based on user queries. Once matching Skills are confirmed, &lt;code&gt;skillPlugin&lt;/code&gt; generates standardized instructions. If the Skill contains attached documents, runtime tools like &lt;code&gt;list_skill_files&lt;/code&gt; and &lt;code&gt;read_skill_file&lt;/code&gt; will be exposed, and &lt;code&gt;toolPlugin&lt;/code&gt; collects &amp;amp; executes all tool calls returned by the model.&lt;/p&gt;

&lt;p&gt;Vue applications can integrate this capability through &lt;code&gt;skillPlugin&lt;/code&gt;. Active Skill configurations update with UI state in real time. There is no need to recreate entire chat instances every time users switch Skills.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9yqacolhstiq1tyuf8hy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9yqacolhstiq1tyuf8hy.png" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Skills are not merely a set of low-level APIs — they introduce a standardized organizational paradigm for chat applications. Task logic, reference materials and execution rules can be decoupled from page code and reused across multiple projects.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. New Component: Anchor — Navigation For Long Content
&lt;/h3&gt;

&lt;p&gt;The new &lt;code&gt;Anchor&lt;/code&gt; anchor component generates table-of-contents navigation for lengthy articles, long dialogue threads and content-heavy pages, supporting quick jumps, scroll-based highlighting and directory search to help users locate target information instantly.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.1 Generate Table of Contents
&lt;/h4&gt;

&lt;p&gt;Integrating Anchor is straightforward: define directory items and map them to corresponding page content blocks, and the component will automatically organize all long content into a navigable sidebar directory.&lt;br&gt;
This component works seamlessly for both article pages and chat interfaces with segmented content.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.2 Jump &amp;amp; Scroll Highlight
&lt;/h4&gt;

&lt;p&gt;Users can click directory items to scroll directly to matching content blocks. The active directory entry will automatically highlight as users scroll the page.&lt;br&gt;
After jumping to a section, the target content will flash a temporary highlight for better visibility, delivering a smoother reading experience for long-form content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fal2mte9j36renvclv6c3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fal2mte9j36renvclv6c3.gif" alt=" " width="637" height="482"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2.3 Search &amp;amp; Collapse Controls
&lt;/h4&gt;

&lt;p&gt;When directory lists grow lengthy, users can filter entries via built-in search functionality to quickly locate target sections.&lt;br&gt;
The directory panel supports expand/collapse toggles and left/right docking modes. It can function as a lightweight persistent sidebar or a temporary auxiliary navigation panel, compatible with all mainstream page layouts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsasdzdefhkfwzss9dw36.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsasdzdefhkfwzss9dw36.gif" alt=" " width="585" height="435"&gt;&lt;/a&gt;&lt;br&gt;
Anchor encapsulates directory generation, fast jumping, scroll tracking and keyword search into a unified navigation solution, drastically improving readability for long content pages.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. New Component: Layout — Standard &amp;amp; Floating Layout Modes
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;Layout&lt;/code&gt; component provides standardized page structures, collapsible sidebars and floating workspace containers, ideal for chat interfaces, dashboards and complex editing pages. Complex pages with multi-region interaction (navigation, main content, auxiliary info, temporary panels) often suffer fragmented layout logic without unified layout management, which Layout solves thoroughly.&lt;/p&gt;
&lt;h4&gt;
  
  
  3.1 Build Standard Page Structures
&lt;/h4&gt;

&lt;p&gt;Layout provides standardized area slots: &lt;code&gt;left-aside&lt;/code&gt;, &lt;code&gt;header&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;footer&lt;/code&gt;, &lt;code&gt;right-aside&lt;/code&gt;. Developers can quickly assemble fully structured pages for admin backends, editors and chat platforms with stable, consistent layout logic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft1prljmy2wdfdqwwwfjy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft1prljmy2wdfdqwwwfjy.png" alt=" " width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  3.2 Unified Sidebar Interactions
&lt;/h4&gt;

&lt;p&gt;Layout supports two sidebar modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;dock&lt;/code&gt;: permanent sidebar integrated into the page layout for persistent navigation &amp;amp; info panels&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;drawer&lt;/code&gt;: overlay floating sidebar for temporary functional panels&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sidebars support collapse states and resizable width via drag-and-drop. All common sidebar interaction patterns are encapsulated to unify page layout and state management.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7gig41d0w23xqq9ga4sl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7gig41d0w23xqq9ga4sl.png" alt=" " width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  3.3 Floating Workspace Extension
&lt;/h4&gt;

&lt;p&gt;Layout can switch to &lt;code&gt;floating&lt;/code&gt; mode to create draggable, resizable panels outside the normal document flow. Floating panels retain complete layout slot support (header, main, left/right sidebars) for independent task workspaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb0oct84ydvk7fbj3qdsq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb0oct84ydvk7fbj3qdsq.gif" alt=" " width="760" height="465"&gt;&lt;/a&gt;&lt;br&gt;
Layout unifies standard page structures, sidebar interactions and floating workspaces under a single component, turning disjoint page blocks into organized, coordinated workspaces for complex business scenarios.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. New Tool: CLI Scaffolding — One Command To Generate TinyRobot Projects
&lt;/h3&gt;

&lt;p&gt;TinyRobot CLI provides two streamlined workflows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;basic&lt;/code&gt;: spin up a complete standalone project from scratch&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add chat&lt;/code&gt;: incrementally inject chat components into existing Vue projects&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  4.1 Create Full Project With &lt;code&gt;create&lt;/code&gt; Command
&lt;/h4&gt;

&lt;p&gt;Run the CLI to generate a complete template project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npm&lt;/span&gt;
npx @opentiny/tiny-robot-cli create
&lt;span class="c"&gt;# pnpm&lt;/span&gt;
pnpm dlx @opentiny/tiny-robot-cli create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow terminal prompts to install dependencies and launch the development server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff7hwb585g9s9khox81sh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff7hwb585g9s9khox81sh.png" alt=" " width="391" height="213"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;LLM Key Configuration&lt;/strong&gt;&lt;br&gt;
The basic template comes pre-configured with DeepSeek and Alibaba DashScope integrations. Copy &lt;code&gt;.env.example&lt;/code&gt; to &lt;code&gt;.env&lt;/code&gt; and fill in your API keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Alibaba DashScope API Key (required for partial MCP plugins)
VITE_ALIYUN_DASHSCOPE_KEY=
# DeepSeek API Key
VITE_DEEPSEEK_API_KEY=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 built-in MCP plugins are included: 12306 Ticket Query (Alibaba DashScope), Amap Maps, generic MCP demo. DashScope plugins require the corresponding environment variable.&lt;br&gt;
Visit &lt;code&gt;http://localhost:5173&lt;/code&gt; in your browser to preview the full AI chat application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb7za00vsprfxppm09ctv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb7za00vsprfxppm09ctv.png" alt=" " width="799" height="475"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  4.2 Inject Chat Components Into Existing Projects With &lt;code&gt;add chat&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Execute the command inside your Vue project root directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npm&lt;/span&gt;
npx @opentiny/tiny-robot-cli add chat
&lt;span class="c"&gt;# pnpm&lt;/span&gt;
pnpm dlx @opentiny/tiny-robot-cli add chat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow prompts to complete auto-injection. The generated &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzyxz7d9kt4uv6zcrho20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzyxz7d9kt4uv6zcrho20.png" alt=" " width="661" height="216"&gt;&lt;/a&gt;&lt;br&gt;
&lt;code&gt;TinyRobotChat.vue&lt;/code&gt; component can be imported anywhere in your project, e.g. &lt;code&gt;App.vue&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;HelloWorld&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/HelloWorld.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TinyRobotChat&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./TinyRobotChat.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;HelloWorld&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;TinyRobotChat&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your LLM API key to the &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_DEEPSEEK_API_KEY=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reinstall dependencies and launch dev server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost:5173&lt;/code&gt; to view the embedded AI chat module within your existing project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fco5x0gp0wyg3mmme2w6w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fco5x0gp0wyg3mmme2w6w.gif" alt=" " width="799" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Miscellaneous Optimizations &amp;amp; Bug Fixes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  New Capability Additions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bubble: unified &lt;code&gt;bubble-event&lt;/code&gt; event channel + &lt;code&gt;state-change&lt;/code&gt; state sync; support injecting box/content attributes at Provider level&lt;/li&gt;
&lt;li&gt;Sender: grapheme-based character counting for accurate Emoji &amp;amp; composite character length calculation&lt;/li&gt;
&lt;li&gt;Sender: &lt;code&gt;hasExternalContent&lt;/code&gt; prop to factor attachments into send state logic&lt;/li&gt;
&lt;li&gt;useMessage: refactored core message engine into adapter architecture, reusable for both Vue and vanilla JS&lt;/li&gt;
&lt;li&gt;toolPlugin: aggregate runtime tool providers + tool source tracking for dynamic tool injection based on message context&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Optimizations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reasoning: reasoning bubble expanded by default to reduce user clicks&lt;/li&gt;
&lt;li&gt;McpServerPicker: unified style variables for consistent visual design&lt;/li&gt;
&lt;li&gt;Attachments / Dropdown / Suggestion: complete dark mode variable coverage, optimized hover &amp;amp; interactive styles&lt;/li&gt;
&lt;li&gt;Feedback / Welcome: improved dark theme rendering&lt;/li&gt;
&lt;li&gt;Docs &amp;amp; Demo: refined shell layout, navigation, code blocks and dark mode styles&lt;/li&gt;
&lt;li&gt;Build: lock Tiptap dependency versions; update Playground IDB import maps&lt;/li&gt;
&lt;li&gt;Build: add CSS &lt;code&gt;sideEffects&lt;/code&gt; field to ensure styles are retained during bundling&lt;/li&gt;
&lt;li&gt;Testing: supplement E2E selectors for Sender; add test coverage for Mention, Suggestion &amp;amp; Template scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Bug Fixes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Layout: stabilize type declarations, simplify slot existence judgment logic&lt;/li&gt;
&lt;li&gt;Bubble: fix rendering errors when non-standard APIs return empty &lt;code&gt;reasoning_content&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Attachments: resolve attachment list normalization defects, add corresponding test cases&lt;/li&gt;
&lt;li&gt;Sender: fix tooltip spacing &amp;amp; rendering anomalies for action buttons; stabilize template deletion test cases&lt;/li&gt;
&lt;li&gt;Playground / Docs: fix share link path config; remove hardcoded VitePress brand colors&lt;/li&gt;
&lt;li&gt;CI &amp;amp; Workflow: optimize preview comment workflows; exclude CLI template packages from workspace bundling&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The core value of v0.5.0 lies in shortening the development cycle from component integration to production-ready AI products:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Skills: standardized organization of AI task logic &amp;amp; reference resources&lt;/li&gt;
&lt;li&gt;CLI: one-click project scaffolding for new &amp;amp; existing Vue projects&lt;/li&gt;
&lt;li&gt;Anchor: readable navigation for long dialogue &amp;amp; content&lt;/li&gt;
&lt;li&gt;Layout: unified complex page construction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All four upgrades streamline development workflows and deliver fully functional AI chat applications faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  About OpenTiny NEXT
&lt;/h2&gt;

&lt;p&gt;OpenTiny NEXT is an enterprise intelligent front-end solution built on Generative UI and WebMCP core technologies. It delivers intelligent upgrades for legacy products including the TinyVue component library and TinyEngine low-code engine, while launching Agent-native products such as front-end NEXT-SDKs, AI Extension, TinyRobot AI Assistant and GenUI. It enables AI to interpret user intentions and complete tasks autonomously, accelerating enterprise intelligent transformation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the OpenTiny Open Source Community
&lt;/h3&gt;

&lt;p&gt;WeChat Assistant: opentiny-official&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TinyRobot Official Website: &lt;a href="https://opentiny.design/tiny-robot" rel="noopener noreferrer"&gt;https://opentiny.design/tiny-robot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TinyRobot GitHub Repository: &lt;a href="https://github.com/opentiny/tiny-robot" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-robot&lt;/a&gt; (Star ⭐ appreciated)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you wish to contribute, look for issues tagged &lt;code&gt;good first issue&lt;/code&gt; in the repository. Feel free to leave comments with any questions or feedback!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>TinyEngine v2.11 Released: AI Deeply Integrated Into Canvas, Vue Projects One-Click Convertible to DSL</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Thu, 16 Jul 2026 06:26:17 +0000</pubDate>
      <link>https://dev.to/opentiny/tinyengine-v211-released-ai-deeply-integrated-into-canvas-vue-projects-one-click-convertible-to-2581</link>
      <guid>https://dev.to/opentiny/tinyengine-v211-released-ai-deeply-integrated-into-canvas-vue-projects-one-click-convertible-to-2581</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;TinyEngine is a forward-looking low-code engine foundation that delivers highly customizable technical infrastructure for developers. It supports core capabilities such as visual page building, and enables in-depth secondary development via CLI engineering workflows. Teams can leverage it to rapidly build proprietary low-code platforms.&lt;/p&gt;

&lt;p&gt;TinyEngine flexibly adapts to various scenarios including resource orchestration, server-side rendering, model-driven applications, mobile terminals, large-screen dashboards, and complex page composition, serving as a solid foundation for your low-code system.&lt;/p&gt;

&lt;p&gt;We are pleased to announce the official release of &lt;strong&gt;TinyEngine v2.11&lt;/strong&gt;. This version focuses on three major upgrade directions: smarter development experience, smoother asset import, and a more complete component material ecosystem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Source Repository: &lt;a href="https://github.com/opentiny/tiny-engine" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-engine&lt;/a&gt; (Star ⭐ appreciated!)&lt;/li&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design/tiny-engine" rel="noopener noreferrer"&gt;https://opentiny.design/tiny-engine&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We sincerely thank contributor @zjy2414 for participating in the open-source co-construction of TinyEngine, and invite all developers to join our community to help TinyEngine evolve further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Release Feature Overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[New Feature] Support importing Vue projects / single-file components into low-code platform&lt;/li&gt;
&lt;li&gt;[New Feature] AI assistant entry added to every canvas node for fast modification&lt;/li&gt;
&lt;li&gt;[New Feature] Support mockserver files as local database, plus new &lt;code&gt;dsl-generator&lt;/code&gt; skill&lt;/li&gt;
&lt;li&gt;[New Feature] Auto-format generated code in preview mode&lt;/li&gt;
&lt;li&gt;[Enhancement] Robot plugin upgraded to TinyRobot v0.4.0&lt;/li&gt;
&lt;li&gt;[Enhancement] Expanded built-in component library&lt;/li&gt;
&lt;li&gt;Miscellaneous minor optimizations &amp;amp; bug fixes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In-Depth Feature Breakdown
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. New Feature: Import Vue Projects / SFCs to Low-Code Platform
&lt;/h3&gt;

&lt;p&gt;A major pain point for teams adopting low-code platforms is reusing existing Vue assets. If legacy pages, components and engineering resources cannot be migrated, the low-code system becomes an isolated silo with high internal promotion costs. The new Vue-to-DSL capability solves exactly this problem.&lt;/p&gt;

&lt;p&gt;TinyEngine can parse Vue single-file components, project directories or compressed ZIP packages into TinyEngine DSL schemas, then import them as editable pages, blocks, static assets and data sources for further editing and preview inside the designer.&lt;/p&gt;

&lt;p&gt;Supported import workflows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Import single Vue SFC files&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgshowtdzl17mnnl711rt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgshowtdzl17mnnl711rt.gif" alt=" " width="799" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Import full Vue project directories&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpl7krog1yn9mcwwspv7i.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpl7krog1yn9mcwwspv7i.gif" alt=" " width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Import compressed ZIP source packages&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3cjm96tfpuwhoztgs9rc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3cjm96tfpuwhoztgs9rc.gif" alt=" " width="799" height="396"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Canvas rendering after import, with dedicated panels for i18n, data sources &amp;amp; page states&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fom9g78ylfrl8p0rraun2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fom9g78ylfrl8p0rraun2.gif" alt=" " width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Live project preview post-import&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiwewoxt0l49zfr7an096.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiwewoxt0l49zfr7an096.gif" alt=" " width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. New Feature: Node-Level AI Assistant on Canvas
&lt;/h3&gt;

&lt;p&gt;v2.11 embeds AI capabilities deeper into the visual designer canvas. Every canvas node now has a dedicated AI assistant entry, delivering context-aware development support during page construction. Unlike generic global chat AI, this node-tethered assistant integrates tightly with daily editing workflows to boost page composition efficiency.&lt;/p&gt;

&lt;p&gt;Key capabilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;AI assistant button attached to every canvas component node&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0eisocs2j623wrmdw47h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0eisocs2j623wrmdw47h.jpg" alt=" " width="799" height="259"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shares identical configuration with the global Robot plugin&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwj1gbk6fjqqize5hb2hr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwj1gbk6fjqqize5hb2hr.jpg" alt=" " width="799" height="338"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interactive chat workflow: send requests, then choose to apply, discard or restart generated changes&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffgy8zqymh3khqz7mpfbc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffgy8zqymh3khqz7mpfbc.gif" alt=" " width="719" height="354"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3. New Feature: Mockserver File Database + dsl-generator Skill
&lt;/h3&gt;

&lt;h4&gt;
  
  
  File Mode for Mockserver
&lt;/h4&gt;

&lt;p&gt;Mockserver adds a new &lt;code&gt;file&lt;/code&gt; startup mode (default local database mode). All mock API data is read and persisted to JSON files under the &lt;code&gt;data/**/&lt;/code&gt; directory.&lt;br&gt;
Usage:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Run &lt;code&gt;pnpm dev:file&lt;/code&gt; in project root to launch file-mode mockserver&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F121ry8h9tch3ftyh0w0u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F121ry8h9tch3ftyh0w0u.png" alt=" " width="799" height="261"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create pages &amp;amp; applications, auto-generated JSON data files will appear in the &lt;code&gt;data&lt;/code&gt; folder&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe94zmkw6weittslj0dcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe94zmkw6weittslj0dcp.png" alt=" " width="772" height="820"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  dsl-generator Project Skill
&lt;/h4&gt;

&lt;p&gt;A project-level skill that enables local AI Agents (Claude Code, Cursor, OpenCode, Codex etc.) to generate page/block/application DSL JSON files inside the &lt;code&gt;data&lt;/code&gt; directory, fully compatible with file-mode mockserver.&lt;br&gt;
Usage:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Call the skill via local Agent tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.agents/skills&lt;/code&gt; (compatible with Cursor / OpenCode / Codex)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.claude/skills&lt;/code&gt; (soft link pointing to the shared skill directory for Claude Code)
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F66zo34b1ca2xm0ykybgn.png" alt=" " width="800" height="521"&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5nx1sezhy988bq3nu8ss.png" alt=" " width="799" height="359"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate complete pages and application structures directly via AI&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbkpr1kfrgo6tx8bi9hwb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbkpr1kfrgo6tx8bi9hwb.png" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4. New Feature: Auto Format Generated Code in Preview Mode
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Extended shared AST utilities to support Vue &amp;amp; Less formatting&lt;/li&gt;
&lt;li&gt;Auto-select Prettier parsers based on file extensions&lt;/li&gt;
&lt;li&gt;All generated scripts, templates and config files are auto-formatted on page/app preview for improved readability
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5jxghi8vv86s0im333w0.png" alt=" " width="800" height="833"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Capability Enhancements
&lt;/h3&gt;

&lt;h4&gt;
  
  
  TinyRobot Plugin Upgrade
&lt;/h4&gt;

&lt;p&gt;The built-in Robot plugin has been migrated to TinyRobot v0.4.0. Stable AI functionality requires robust underlying plugin infrastructure rather than superficial UI wrappers; this upgrade solidifies TinyEngine’s foundation for AI assistant and intelligent interaction features.&lt;/p&gt;

&lt;h4&gt;
  
  
  Expanded Component Materials
&lt;/h4&gt;

&lt;p&gt;v2.11 adds a full suite of new built-in components and matching icons:&lt;br&gt;
&lt;code&gt;action-menu&lt;/code&gt;, &lt;code&gt;alert&lt;/code&gt;, &lt;code&gt;link&lt;/code&gt;, &lt;code&gt;divider&lt;/code&gt;, &lt;code&gt;anchor&lt;/code&gt;, &lt;code&gt;drawer&lt;/code&gt;, &lt;code&gt;container&lt;/code&gt;, &lt;code&gt;file-upload&lt;/code&gt;&lt;br&gt;
Plus full support for &lt;code&gt;dropdown&lt;/code&gt; and other frequently used UI components.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Minor Optimizations &amp;amp; Bug Fixes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fixed failure to save event names with &lt;code&gt;onUpdate&lt;/code&gt; prefix&lt;/li&gt;
&lt;li&gt;Serialize &lt;code&gt;page_content&lt;/code&gt; to resolve page creation errors in mockserver&lt;/li&gt;
&lt;li&gt;Fixed blank rendering for certain chart previews&lt;/li&gt;
&lt;li&gt;Added feature toggle for structured CSS output&lt;/li&gt;
&lt;li&gt;Optimized styling &amp;amp; icon replacement for model, resource and AI dialog panels&lt;/li&gt;
&lt;li&gt;Updated unit test templates for auto-generated code&lt;/li&gt;
&lt;li&gt;Added mock data management tools for models&lt;/li&gt;
&lt;li&gt;Fixed error prompts when creating identical pages across different apps&lt;/li&gt;
&lt;li&gt;Removed workflow-level environment variable blocks that exposed secret keys&lt;/li&gt;
&lt;li&gt;Updated data source config to support saving APIs without request parameters&lt;/li&gt;
&lt;li&gt;Resolved message rendering &amp;amp; file upload interaction bugs in Robot plugin, with supplementary test cases&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Documentation Updates
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Added docs for code generation commands&lt;/li&gt;
&lt;li&gt;Deployment workflow now supports custom backend URL configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing Remarks
&lt;/h2&gt;

&lt;p&gt;TinyEngine v2.11 delivers major upgrades across the board: canvas-native AI assistance, bidirectional Vue-to-DSL project migration, expanded component ecosystem and improved local debugging workflows. It makes low-code platform development smarter, more open, and better aligned with real-world engineering pipelines.&lt;/p&gt;

&lt;p&gt;This release stands as a milestone built by collective open-source community contributions. Open source thrives not only on shared code, but also idea exchange and collaborative creation — every user’s feedback and commit shapes TinyEngine’s maturity in real business scenarios.&lt;/p&gt;

&lt;p&gt;We look forward to continued collaboration. Stay tuned for future updates, join community discussions, and submit feature ideas or code contributions to push the boundaries of low-code development together.&lt;/p&gt;

&lt;h2&gt;
  
  
  About OpenTiny
&lt;/h2&gt;

&lt;p&gt;Join the OpenTiny open-source community! Add our WeChat assistant &lt;code&gt;opentiny-official&lt;/code&gt; to communicate with fellow front-end developers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design" rel="noopener noreferrer"&gt;https://opentiny.design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenTiny Monorepo: &lt;a href="https://github.com/opentiny" rel="noopener noreferrer"&gt;https://github.com/opentiny&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TinyEngine Repository: &lt;a href="https://github.com/opentiny/tiny-engine" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-engine&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to star TinyEngine, TinyVue, GenUI SDK, TinyRobot and NEXT SDK on GitHub.&lt;br&gt;
To contribute, locate issues tagged &lt;code&gt;good first issue&lt;/code&gt; in each repository and join our open-source co-construction efforts!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How Do Coding Agents Actually Work, and Why Do They Produce Inaccurate Outputs in Complex Codebases?</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Wed, 15 Jul 2026 06:51:50 +0000</pubDate>
      <link>https://dev.to/opentiny/how-do-coding-agents-actually-work-and-why-do-they-produce-inaccurate-outputs-in-complex-codebases-3j3e</link>
      <guid>https://dev.to/opentiny/how-do-coding-agents-actually-work-and-why-do-they-produce-inaccurate-outputs-in-complex-codebases-3j3e</guid>
      <description>&lt;h2&gt;
  
  
  Preface: Demystify the Black Box
&lt;/h2&gt;

&lt;p&gt;Most developers hold two deep-rooted misconceptions about AI coding assistants.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They treat AI tools as opaque black boxes: input requirements and expect flawless code as output.&lt;/li&gt;
&lt;li&gt;They believe models with million-token context windows will perform better as long as sufficient background information is provided.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach works efficiently for simple, independent small tasks. However, in enterprise-grade projects featuring hundreds of thousands of lines of code, dozens of components, cross-module business logic, and mixed legacy &amp;amp; new code, the "black box mindset" quickly collapses.&lt;/p&gt;

&lt;p&gt;You will observe the AI hallucinates false logic, ignores architectural conventions, and even generates code that is syntactically valid yet fatally flawed for business scenarios.&lt;/p&gt;

&lt;p&gt;Previous community articles introduced Harness Engineering, summarizing Harness methodologies, pitfalls and practical experience from OpenAI, Anthropic, LangChain and more.&lt;/p&gt;

&lt;p&gt;Nevertheless, all publicly available success cases apply to greenfield projects or brand-new Harness implementations. Applying these technologies to decade-old codebases lacking architectural constraints, inconsistent test suites and incomplete documentation poses far greater challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: Core Principles
&lt;/h2&gt;

&lt;p&gt;This section answers the fundamental questions: How do Coding Agents operate, and why do they degrade in complex repositories?&lt;/p&gt;

&lt;h3&gt;
  
  
  Chapter 1: Operating Mechanisms of Coding Agents
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1.1 The Essence of LLMs: Autoregression + Attention Mechanism
&lt;/h4&gt;

&lt;p&gt;To understand why Coding Agents make mistakes, you first need to grasp how their underlying "brain" functions.&lt;/p&gt;

&lt;p&gt;Large Language Models only perform one core task: predict the next token. They possess no separate reasoning process independent of output — reasoning is generation, and generation is reasoning. The model generates one token at a time, appends it to the existing sequence, and continues predicting subsequent tokens. This process is known as &lt;strong&gt;autoregression&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Attention Mechanism&lt;/strong&gt; governs how the model "reads" preceding content at each step. You can visualize it as a dynamic spotlight: while generating new text, the model scans the entire context window and assigns varying weight ("attention") to every position. In theory, this spotlight can illuminate any section of text.&lt;/p&gt;

&lt;p&gt;However, practical deployment reveals several critical inherent limitations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Characteristic&lt;/th&gt;
&lt;th&gt;Technical Definition&lt;/th&gt;
&lt;th&gt;Impact on Programming Workloads&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sparse, Biased Attention&lt;/td&gt;
&lt;td&gt;The model does not distribute focus evenly; it prioritizes text at the very start and end of context&lt;/td&gt;
&lt;td&gt;Critical logic placed in the middle of context may be overlooked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O(N²) Computational Complexity&lt;/td&gt;
&lt;td&gt;Doubling context length quadruples compute and VRAM consumption&lt;/td&gt;
&lt;td&gt;Files cannot be infinitely appended to the context window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diluted Attention Weights&lt;/td&gt;
&lt;td&gt;Longer context reduces the attention share allocated to each individual token&lt;/td&gt;
&lt;td&gt;Key information gets buried when dozens of files are mixed together&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Worse yet, autoregression creates a &lt;strong&gt;hallucination snowball effect&lt;/strong&gt; specifically for coding workloads.&lt;br&gt;
Software development involves long workflows with rigid constraints. Once the model guesses an incorrect function name early (due to diluted attention obscuring the correct API), it will consistently build coherent yet invalid logic atop this error for every subsequent token until compilation fails.&lt;/p&gt;

&lt;p&gt;Two critical takeaways from autoregression and Attention:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Model "reasoning" is probabilistic token continuation, not formal logical deduction.&lt;/li&gt;
&lt;li&gt;Context quality vastly outweighs context quantity. Feeding 50 unrelated files into the window dilutes critical signal rather than improving model performance.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  1.2 Reinforcement Learning (RL): From Text Generation to Action Execution
&lt;/h4&gt;

&lt;p&gt;Pre-training only teaches models what source code looks like via massive GitHub datasets. It is analogous to someone who has read every cookbook yet never set foot in a kitchen — they know recipe formatting but cannot cook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reinforcement Learning (RL)&lt;/strong&gt; equips Coding Agents with actionable capabilities. Instead of explicitly instructing the model how to complete tasks, RL only defines success criteria — an ideology perfectly aligned with software development: any implementation that passes tests is acceptable.&lt;/p&gt;

&lt;p&gt;Modern coding models undergo RL training with the following workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Execute programming tasks inside simulated environments&lt;/li&gt;
&lt;li&gt;Use test pass rates and code quality scores as reward signals&lt;/li&gt;
&lt;li&gt;Learn when to read additional files, when to perform edits, and how to extract actionable clues from error logs&lt;/li&gt;
&lt;/ol&gt;
&lt;h5&gt;
  
  
  Practical Prompt Guidance from RL Principles
&lt;/h5&gt;

&lt;p&gt;Understanding RL reveals how to craft effective instructions for Agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Poor instruction: Fix the login bug.&lt;/li&gt;
&lt;li&gt;✅ High-quality instruction: Resolve unsaved login session state; all tests must pass after running &lt;code&gt;npm test&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These two prompts appear similar to humans, but the latter provides verifiable success metrics that align directly with the reward signals the model learned during RL training. Clear, testable objectives drastically boost Agent performance.&lt;/p&gt;
&lt;h4&gt;
  
  
  1.3 The Agent Loop: Core Execution Cycle
&lt;/h4&gt;

&lt;p&gt;LLMs can answer standalone questions, while Agents can complete multi-step tasks. The core distinction lies in the repeating loop:&lt;br&gt;
&lt;strong&gt;Call LLM → Determine next action → Execute tool → Write tool output back to context → Re-invoke LLM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This repeating sequence is the Agent Loop.&lt;/p&gt;

&lt;p&gt;Take a concrete example task: Fix the bug where user sessions fail to persist after login.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Iteration&lt;/th&gt;
&lt;th&gt;Agent Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Round 1&lt;/td&gt;
&lt;td&gt;Call &lt;code&gt;list_directory&lt;/code&gt; to inspect project root folders&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 2&lt;/td&gt;
&lt;td&gt;Identify the &lt;code&gt;src/auth&lt;/code&gt; directory, invoke &lt;code&gt;read_file&lt;/code&gt; to load &lt;code&gt;login.js&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 3&lt;/td&gt;
&lt;td&gt;Detect calls to &lt;code&gt;sessionManager.save()&lt;/code&gt;, read &lt;code&gt;session/manager.js&lt;/code&gt; for implementation details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 4&lt;/td&gt;
&lt;td&gt;Discover missing &lt;code&gt;await&lt;/code&gt; for asynchronous logic inside &lt;code&gt;save()&lt;/code&gt;, execute &lt;code&gt;edit_file&lt;/code&gt; to patch the code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 5&lt;/td&gt;
&lt;td&gt;Launch shell tool to run automated test suites&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 6&lt;/td&gt;
&lt;td&gt;Confirm all tests pass and generate a summary of the resolved issue&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One vital detail: output from every single tool call is appended to the shared context window. This continuously inflates context size with file contents, shell outputs and error logs — the root cause of failures for lengthy tasks due to context pollution.&lt;/p&gt;
&lt;h3&gt;
  
  
  Chapter 2: Longer Context Does Not Equal Better Performance
&lt;/h3&gt;

&lt;p&gt;After grasping LLMs, RL and Agent Loops, a natural question emerges: what defines the functional limits of Coding Agents?&lt;/p&gt;

&lt;p&gt;Many developers assume the bottleneck is insufficient context window capacity. This statement is only half correct. The true challenge is not whether data can fit into context, but whether the model can reliably and accurately utilize the data once loaded.&lt;/p&gt;

&lt;p&gt;We split Coding Agent context challenges into two distinct layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Capacity Limits: Hard technical caps on input size enforced by models and tooling&lt;/li&gt;
&lt;li&gt;Utilization Limits: Even with data loaded, the model may fail to extract critical information&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The second layer almost always determines real-world performance.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.1 Physical Capacity vs Effective Context Window
&lt;/h4&gt;

&lt;p&gt;Every LLM has a hard maximum context window size, dictated by underlying compute and memory costs. Traditional Attention algorithms scale quadratically with input length, slowing inference and increasing VRAM consumption as text grows longer.&lt;/p&gt;

&lt;p&gt;"Extended context support" purely means the model can technically accept larger input payloads — it does &lt;strong&gt;not&lt;/strong&gt; guarantee stable, accurate comprehension at maximum window size.&lt;/p&gt;

&lt;p&gt;Long context windows solve storage constraints alone; they cannot resolve comprehension degradation.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.2 Context Rot
&lt;/h4&gt;

&lt;p&gt;Research published by Chroma titled Context Rot demonstrates that model performance consistently declines as input length increases. Degradation becomes far more severe when relevant information is semantically distant from the core task query.&lt;/p&gt;

&lt;p&gt;Within Agent workflows, every &lt;code&gt;grep&lt;/code&gt; result and loaded file that proves irrelevant acts as attention noise, degrading the model’s accuracy in subsequent iterations.&lt;/p&gt;

&lt;p&gt;In practical development scenarios, the core pain point is not the model lacking access to information, but its inability to reliably isolate critical signals amid noise.&lt;/p&gt;

&lt;p&gt;This is the most widely misunderstood property of long context windows:&lt;br&gt;
Developers often dump requirement docs, architecture diagrams, API specs and historical discussions into context simultaneously under the assumption "more information = better results." This frequently backfires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extended text dilutes attention weights&lt;/li&gt;
&lt;li&gt;Irrelevant content buries critical clues&lt;/li&gt;
&lt;li&gt;When questions and relevant code are separated by large blocks of text, the model prioritizes superficially matching irrelevant snippets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core challenge introduced by long context is not data storage, but noise mitigation.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.3 Lost in the Middle: U-Shaped Attention Distribution
&lt;/h4&gt;

&lt;p&gt;The "Lost in the Middle" phenomenon predates Context Rot research. A 2024 Stanford study published in TACL proved LLM attention follows a U-shaped curve: the highest focus is allocated to text at the absolute start and end of context, while content in the middle receives minimal weight.&lt;/p&gt;

&lt;p&gt;In multi-document testing with 20 input files, accuracy dropped over 30% when the document containing the correct answer was placed in positions 5–15 (the middle zone), versus placement at the first or last position.&lt;/p&gt;

&lt;p&gt;For Coding Agents, this creates tangible failures: if the Agent loads 8 source files while the critical business logic resides in the 4th file, the model will overlook the key implementation due to the attention blind spot in the middle of context.&lt;/p&gt;

&lt;p&gt;Key Conclusion: Context management is a rigorous engineering discipline, not just loading all available text. Precise, concise context outperforms bloated, noisy context. As Anthropic outlined in its Context Engineering blog: context is a finite resource with diminishing marginal returns.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.4 Three Fundamental Limitations of Current Coding Agents
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Irreversible Bias Accumulation&lt;br&gt;
Once the model misinterprets logic in an early iteration, all subsequent reasoning and code generation builds upon this flawed premise. In coding tasks, this manifests as locally consistent yet globally incorrect code: individual lines, function calls and naming standards appear valid, yet core assumptions about function responsibilities or API semantics are fundamentally wrong. Many AI-generated bugs are logically sound in isolation but broken end-to-end.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limited Multi-Constraint Handling&lt;br&gt;
Real-world development enforces simultaneous rules: syntax validity, semantic logic, directory structure, legacy compatibility, test coverage, performance budgets, security boundaries and team style guides. Agents struggle to maintain compliance with all constraints over long task chains. Fixing one bug often breaks compatibility or violates coding standards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Natural Serial Exploration Bias&lt;br&gt;
Senior human developers maintain multiple parallel hypotheses and eliminate them iteratively when debugging. Most Agents default to serial exploration: they pursue one line of investigation fully before testing alternatives, frequently wasting resources on dead-end paths.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that we understand why Agents degrade in complex codebases, we examine how tooling compensates for these inherent flaws.&lt;/p&gt;
&lt;h2&gt;
  
  
  Part 2: Tooling Analysis
&lt;/h2&gt;

&lt;p&gt;This section avoids head-to-head comparisons between Coding Agent products. Instead, it breaks down the core mechanisms different tools use to offset unstable comprehension of large repositories.&lt;/p&gt;
&lt;h3&gt;
  
  
  Chapter 3: Four Paradigms for Code-Aware AI Tooling
&lt;/h3&gt;
&lt;h4&gt;
  
  
  3.1 Evaluate Context Systems, Not Just Underlying Models
&lt;/h4&gt;

&lt;p&gt;Comparing model parameter counts cannot explain real-world performance gaps. In production projects, the decisive factor is not the model’s raw code generation ability, but how the tool interfaces with the repository, ingests project constraints, forms closed action loops, integrates external extensions, and preserves reusable team knowledge.&lt;/p&gt;

&lt;p&gt;We analyze tools across five core evaluation dimensions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Context Ingestion: Does the tool rely primarily on semantic retrieval/file scanning, or explicit knowledge files (specs, rules, SKILL.md, AGENTS.md)?&lt;/li&gt;
&lt;li&gt;Persistent Constraints: Are project standards stored as one-off temporary prompts per session, or version-controlled repository assets reusable long-term?&lt;/li&gt;
&lt;li&gt;Action Loops: Does the tool only output static suggestions, or autonomously read/edit files, run shell commands and iterate based on feedback?&lt;/li&gt;
&lt;li&gt;External Extensibility: Does it support MCP, hooks, subagents, plugins and skill packages to inject custom workflows?&lt;/li&gt;
&lt;li&gt;Team Governance: Are optimization practices individual developer tricks, or standardized project/team engineering assets?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All modern tools including Cursor, Claude Code, Codex CLI and Kiro implement full Agent Loop functionality (file read/write, command execution, iterative fixes) alongside MCP, subagent and skill extensions. Standardized knowledge files such as SKILL.md and AGENTS.md are cross-compatible across platforms.&lt;/p&gt;

&lt;p&gt;Our comparison focuses on each tool’s unique prioritized optimization direction, rather than feature checklists.&lt;/p&gt;
&lt;h4&gt;
  
  
  3.2 Cursor: Native IDE Agent with Optimized Retrieval &amp;amp; Context Recall
&lt;/h4&gt;

&lt;p&gt;Cursor is one of the most mature AI-first IDEs built atop VS Code, featuring full multi-step task planning, multi-file editing, terminal automation and iterative refinement until tests pass.&lt;/p&gt;

&lt;p&gt;Version 2.4 (Jan 2026) introduced subagents (isolated parallel child agents with independent context windows) and SKILL.md skill packages. Version 2.5 (Feb 2026) expanded the plugin ecosystem, packaging skills, subagents, MCP servers and hooks into installable marketplace modules. Additional offerings include Cloud Agents (isolated cloud VMs triggered via webhooks/Slack/GitHub) and scheduled Automations workflows.&lt;/p&gt;

&lt;p&gt;Cursor’s defining competitive advantage lies in repository indexing and context retrieval deeply integrated within the IDE workflow.&lt;/p&gt;

&lt;p&gt;Most AI coding errors stem from misidentifying relevant source files rather than flawed generation logic: the Agent may load semantically similar modules with unrelated business logic, or overlook critical rule/config files governing system behavior. Cursor mitigates this via heavy investment in repository indexing infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full semantic vector indexing of the entire codebase runs in the background on first project open, building a structural repository map before any Agent session starts.&lt;/li&gt;
&lt;li&gt;Four-tier rule system: project-level &lt;code&gt;.cursor/rules&lt;/code&gt;, user-level, team-level and session-level AGENTS.md to consistently inject constraints into every interaction.&lt;/li&gt;
&lt;li&gt;Dynamic skill loading prevents dumping all project knowledge into the context window simultaneously.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  Vector RAG Workflow
&lt;/h5&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scan full repository files
↓
Split code by semantic blocks (functions/classes, not arbitrary line breaks)
↓
Generate embedding vectors for each logical code block
↓ Store embeddings in Turbopuffer vector database
↓ On user query: vectorize requirements, perform nearest-neighbor semantic search
↓ Inject matching code blocks + user prompt into LLM context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Even functions with no "auth" keyword in their names will be retrieved if their embedding semantically matches user authentication requirements. Code is split along syntactic boundaries rather than arbitrary line cuts for superior retrieval quality.&lt;br&gt;
Limitations: Embedding vectors are stored on Cursor’s cloud servers (raw source remains local); initial indexing consumes high CPU/RAM for repositories exceeding 100,000 files.&lt;/p&gt;

&lt;p&gt;Differentiator: Pioneered deep repository semantic retrieval natively embedded within the end-to-end IDE workflow.&lt;/p&gt;
&lt;h4&gt;
  
  
  3.3 Claude Code: Orchestratable, Governable Agent Exploration Pipelines
&lt;/h4&gt;

&lt;p&gt;Where Cursor prioritizes in-IDE retrieval UX, Claude Code’s core focus is building composable, manageable exploration loops. It recognizes full repository comprehension rarely occurs in a single pass — understanding evolves through cycles of exploration, execution, feedback and revision that require structured orchestration, task division and centralized governance.&lt;/p&gt;
&lt;h5&gt;
  
  
  Live Grepping Workflow
&lt;/h5&gt;

&lt;p&gt;Claude Code does not rely on pre-built RAG indexes, per engineering statements shared on Hacker News. Instead, it equips the Agent with raw filesystem tools to actively discover code on demand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User query: Locate authentication logic
↓ Agent executes grep -r "auth" . → 87 matching results
↓ Agent executes grep -r "guard" . → 23 matching results
↓ Glob pattern search for **/*.interceptor.ts
↓ Read auth.interceptor.ts and trace call chains recursively
↓ Final identification of core authentication implementation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This multi-round tool workflow consumes 3–4x more tokens than indexed retrieval. The tradeoff is offset by a 1M-token ultra-large context window capable of loading entire modules in one payload, bypassing semantic retrieval weaknesses. Teams can also maintain a root &lt;code&gt;CLAUDE.md&lt;/code&gt; manual repository map to skip redundant exploration steps.&lt;/p&gt;

&lt;p&gt;Differentiator: Structured orchestration of multi-step discovery workflows for unindexed, complex codebases.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.4 Codex: Low-Friction Execution &amp;amp; Validation Loops
&lt;/h4&gt;

&lt;p&gt;Codex’s unique optimization streamlines code modification, execution and validation into tight, low-overhead cycles. Its core design assumption: many development tasks do not require full repository comprehension upfront. Fast local feedback accelerates convergence for well-scoped work such as lint fixes, test generation, bulk refactoring and isolated bug patches.&lt;/p&gt;

&lt;p&gt;Codex excels at batch test generation, parallel independent task execution and background asynchronous workflows developers can resume later after meetings. Users describe it as a reliable long-running task executor rather than an interactive paired coding assistant.&lt;/p&gt;

&lt;p&gt;Differentiator: Minimize convergence latency via lightweight local test/execution pipelines.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.5 Kiro: Spec-First Structured Task &amp;amp; Long-Term Knowledge Management
&lt;/h4&gt;

&lt;p&gt;Kiro is an AWS VS Code-based AI IDE with a distinct design philosophy focused on task formalization before writing any code. Many hallucinations originate from ambiguous requirements and missing persistent project context, which Kiro resolves through structured pre-coding documentation.&lt;/p&gt;

&lt;h5&gt;
  
  
  Core Three-Tier Mechanism
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Spec-Driven Development
After users input natural language requirements, Kiro auto-generates version-controlled Markdown specs stored under &lt;code&gt;.kiro/specs&lt;/code&gt;:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;requirements.md&lt;/code&gt;: Formal user stories + acceptance criteria&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;design.md&lt;/code&gt;: Database schemas, API endpoints, TypeScript interfaces, Mermaid data flow diagrams&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tasks.md&lt;/code&gt;: Ordered implementation subtasks with dependencies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example e-commerce review feature workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: Generate Requirements Document
Define user submission windows, star ratings, merchant reply functionality and sorting rules.

Step 2: Generate Design Document
Database Review table schema, REST API routes, frontend component interfaces.

Step 3: Generate Task Breakdown
Ordered actionable subtasks linked to corresponding requirements.

Step 4: Execute Individual Tasks
Launch coding workstreams for each subtask with built unit test coverage requirements.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All spec files are tracked via Git for diff tracking, code review and historical audit trails. Developers report cutting two weeks of trial-and-error work via two hours of spec drafting, with automated high test coverage as a secondary benefit.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Steering Persistent Knowledge Files
Running &lt;code&gt;Kiro: Setup Steering&lt;/code&gt; auto-generates version-controlled project knowledge docs under &lt;code&gt;.kiro/steering&lt;/code&gt;:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;product.md&lt;/code&gt;: Product positioning and target user base&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;structure.md&lt;/code&gt;: Repository directory architecture rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tech.md&lt;/code&gt;: Standard tech stack and tooling constraints
Custom architecture/security rules can be manually added, and the tool automatically references these standards for every Agent session. Fully compatible with the open AGENTS.md standard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Best For: Large collaborative teams, regulated audit-heavy industries, AWS cloud-native projects.&lt;br&gt;
Less Ideal: Tiny one-line hotfixes with excessive spec setup overhead.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Interoperable SKILL.md Skill Packages
Identical skill file format as Cursor and Claude Code for reusable domain workflow modules.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Differentiator: Eliminate pre-task ambiguity by formalizing requirements, architecture and team standards into persistent, reusable repository assets.&lt;/p&gt;
&lt;h4&gt;
  
  
  3.6 Summary: Tool Feature Convergence, Knowledge Engineering Is The Real Divide
&lt;/h4&gt;

&lt;p&gt;All four tools share overlapping core functionality, with differentiation rooted in their prioritized context compensation strategy:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Unique Differentiator&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;td&gt;Indexed semantic retrieval + explicit @ reference context injection, parallel cloud subagent processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;Dynamic on-demand exploration, shared multi-agent context merging with explosion guardrails&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codex&lt;/td&gt;
&lt;td&gt;Short-lived session pipelines, sequential agent chaining centered on shell execution feedback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kiro&lt;/td&gt;
&lt;td&gt;Pre-structured spec requirements + persistent version-controlled knowledge base&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As feature parity and cross-compatible knowledge file standards expand, the decisive competitive advantage shifts to internal project knowledge infrastructure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw Code Repository
↓ Reverse-engineer standardized rule docs (.cursorrules / CLAUDE.md / Kiro Steering)
↓ Inject structured knowledge into AI Agents
↓ Generate compliant new source code
↓ Synchronize updated standards back to repository (closed loop)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tooling and LLMs will continuously update, but structured project knowledge assets compound team value over time — this is the core competitive edge for AI-native engineering workflows.&lt;/p&gt;

&lt;p&gt;Last updated: March 2026. All analysis based on public documentation and hands-on testing; platform functionality subject to frequent official updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appendix: Reference Materials
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Research &amp;amp; Context Theory
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Chroma, Context Rot: How Increasing Input Tokens Impacts LLM Performance (July 2025) — &lt;a href="https://research.trychroma.com/context-rot" rel="noopener noreferrer"&gt;https://research.trychroma.com/context-rot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cursor Official Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Cursor Agent Overview Docs: &lt;a href="https://cursor.com/docs/agent/overview" rel="noopener noreferrer"&gt;https://cursor.com/docs/agent/overview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cursor Agent Best Practices Blog: &lt;a href="https://cursor.com/blog/agent-best-practices" rel="noopener noreferrer"&gt;https://cursor.com/blog/agent-best-practices&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cursor 2.4 Changelog (Subagents &amp;amp; Skills): &lt;a href="https://cursor.com/changelog/2-4" rel="noopener noreferrer"&gt;https://cursor.com/changelog/2-4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cursor 2.5 Changelog (Plugins): &lt;a href="https://cursor.com/changelog/2-5" rel="noopener noreferrer"&gt;https://cursor.com/changelog/2-5&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cloud Agents Blog: &lt;a href="https://cursor.com/blog/cloud-agents" rel="noopener noreferrer"&gt;https://cursor.com/blog/cloud-agents&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Self-Hosted Cloud Agents Blog: &lt;a href="https://cursor.com/blog/self-hosted-cloud-agents" rel="noopener noreferrer"&gt;https://cursor.com/blog/self-hosted-cloud-agents&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Claude Code Official Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Subagent Docs: &lt;a href="https://code.claude.com/docs/en/sub-agents" rel="noopener noreferrer"&gt;https://code.claude.com/docs/en/sub-agents&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Agent Teams Docs: &lt;a href="https://code.claude.com/docs/en/agent-teams" rel="noopener noreferrer"&gt;https://code.claude.com/docs/en/agent-teams&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hooks Docs: &lt;a href="https://code.claude.com/docs/en/hooks" rel="noopener noreferrer"&gt;https://code.claude.com/docs/en/hooks&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Codex CLI Official Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Codex CLI Overview: &lt;a href="https://developers.openai.com/codex/cli" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Codex CLI Feature Guide: &lt;a href="https://developers.openai.com/codex/features" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/features&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Codex MCP Docs: &lt;a href="https://developers.openai.com/codex/mcp" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Agents SDK Integration Guide: &lt;a href="https://developers.openai.com/codex/guides/agents-sdk" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/guides/agents-sdk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Kiro Official Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Kiro Official Site: &lt;a href="https://kiro.dev" rel="noopener noreferrer"&gt;https://kiro.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Steering Docs: &lt;a href="https://kiro.dev/docs/steering/" rel="noopener noreferrer"&gt;https://kiro.dev/docs/steering/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Agent Skill Docs: &lt;a href="https://kiro.dev/docs/skills/" rel="noopener noreferrer"&gt;https://kiro.dev/docs/skills/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Custom Subagent &amp;amp; Skill Blog: &lt;a href="https://kiro.dev/blog/custom-subagents-skills-and-enterprise-controls/" rel="noopener noreferrer"&gt;https://kiro.dev/blog/custom-subagents-skills-and-enterprise-controls/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  About OpenTiny NEXT
&lt;/h2&gt;

&lt;p&gt;OpenTiny NEXT is an enterprise-grade intelligent frontend development solution built on Generative UI and WebMCP core technologies. It delivers intelligent upgrades for legacy products including TinyVue component library and TinyEngine low-code engine, while launching Agent-native products such as frontend NEXT-SDKs, AI Extension, TinyRobot AI Assistant and GenUI. The suite empowers AI to interpret user intentions and complete tasks autonomously, accelerating intelligent transformation for enterprise applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the OpenTiny Open Source Community
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WeChat Assistant: opentiny-official&lt;/li&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design" rel="noopener noreferrer"&gt;https://opentiny.design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GenUI SDK Repo: &lt;a href="https://github.com/opentiny/genui-sdk" rel="noopener noreferrer"&gt;https://github.com/opentiny/genui-sdk&lt;/a&gt; (Star ⭐ appreciated)&lt;/li&gt;
&lt;li&gt;TinyRobot Repo: &lt;a href="https://github.com/opentiny/tiny-robot" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-robot&lt;/a&gt; (Star ⭐ appreciated)&lt;/li&gt;
&lt;li&gt;NEXT WebMCP SDK Repo: &lt;a href="https://github.com/opentiny/webmcp-sdk" rel="noopener noreferrer"&gt;https://github.com/opentiny/webmcp-sdk&lt;/a&gt; (Star ⭐ appreciated)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you wish to contribute, look for issues tagged &lt;code&gt;good first issue&lt;/code&gt; within each repository. Feel free to leave comments with any questions or feedback!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Developing an AI chat page from scratch takes two weeks? Try this Vue3 AI conversation component library, TinyRobot, and get started out of the box!</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Thu, 02 Jul 2026 09:19:16 +0000</pubDate>
      <link>https://dev.to/opentiny/building-an-ai-chat-page-from-scratch-takes-two-weeks-try-tinyrobot-a-vue3-vertical-chat-lm3</link>
      <guid>https://dev.to/opentiny/building-an-ai-chat-page-from-scratch-takes-two-weeks-try-tinyrobot-a-vue3-vertical-chat-lm3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Anyone who has built an AI chat UI knows that even a basic usable dialogue interface requires at least two weeks of development work. This includes message bubble styling, real-time streaming rendering, and full message state management. TinyRobot is here to eliminate repetitive boilerplate work for you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Focus Exclusively on AI Chat Scenarios, Not Generic UI
&lt;/h2&gt;

&lt;p&gt;Many developers may wonder: Is this another UI library competing with TinyVue? The answer is absolutely no — they are complementary tools.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TinyVue covers general page UI: back-end dashboards, forms, modals, and standard enterprise components.&lt;/li&gt;
&lt;li&gt;TinyRobot is built solely for AI chat interaction scenarios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With TinyRobot, you only need to focus on your core business logic: what data the AI returns and what workflows you need to implement. All UI rendering logic, interactive behaviors, and message state maintenance are fully handled by the library.&lt;/p&gt;

&lt;p&gt;Current version: v0.4.1, released under MIT License, with 22 iterative releases.&lt;br&gt;
Code composition: 58.1% TypeScript + 35.4% Vue, delivering robust full type safety.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Architecture Breakdown: Monorepo Three-Package Division
&lt;/h2&gt;

&lt;p&gt;TinyRobot adopts a pnpm workspace monorepo structure, split into three independent packages with clear responsibilities:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package Name&lt;/th&gt;
&lt;th&gt;Core Function&lt;/th&gt;
&lt;th&gt;Installation Requirement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/tiny-robot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Core UI components (bubble, sender, container, etc.)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Mandatory&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/tiny-robot-kit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AI data layer utilities (Provider integration, composables, storage, plugins)&lt;/td&gt;
&lt;td&gt;Optional; install only if connecting LLMs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/tiny-robot-svgs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Built-in SVG icon library&lt;/td&gt;
&lt;td&gt;Optional; install only if using official icons&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The design philosophy behind this three-layer separation is &lt;strong&gt;Separation of Concerns&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Component Layer&lt;/strong&gt;: Only responsible for rendering and user interactions, independent of LLM requests or data persistence logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool Layer&lt;/strong&gt;: Handles heavy logic including model provider access, message state machines, plugins, conversation lifecycle, and storage strategies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Layer&lt;/strong&gt;: Icons are packaged separately without tight coupling to core UI components.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You only need the core package for basic chat UI capabilities; add the kit package on demand for AI integration. Minimal dependencies, maximum flexibility.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. The Soul of the Kit Package: Composable Architecture
&lt;/h2&gt;

&lt;p&gt;Building chat pages is often plagued by messy state management — either cumbersome prop drilling or bloated global state stores. TinyRobot solves this elegantly with two Vue composable hooks, usable anywhere within component trees to access full conversation capabilities.&lt;/p&gt;

&lt;p&gt;Directory structure of composables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;packages/kit/src/vue/
├── message/       &lt;span class="c"&gt;# useMessage composable&lt;/span&gt;
└── conversation/ &lt;span class="c"&gt;# useConversation composable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  useMessage — Message Management Hook
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create, update, delete, and stream-append chat messages with simple APIs&lt;/li&gt;
&lt;li&gt;Message states wrapped in Vue reactive objects, auto-reactive with components (no manual state sync)&lt;/li&gt;
&lt;li&gt;Built-in role classification (user / ai / system), eliminating repetitive &lt;code&gt;if (role === 'ai')&lt;/code&gt; conditional logic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  useConversation — Conversation Session Hook
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Manage full conversation context: chat rounds, history records, and session switching&lt;/li&gt;
&lt;li&gt;Natively integrated with storage strategies for automatic chat persistence&lt;/li&gt;
&lt;li&gt;Full lifecycle control: session creation, loading, switching, and destruction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short: Call &lt;code&gt;useXxx()&lt;/code&gt; inside any Vue component to access complete chat management logic — no prop passing, no heavy global stores, clean and lightweight.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. ResponseProvider Pattern: Plug-and-Play AI Data Sources
&lt;/h2&gt;

&lt;p&gt;Many teams face painful refactoring work when switching LLM vendors: migrating from OpenAI to DeepSeek, private local models, or internal enterprise AI gateways often requires rewriting massive front-end chat logic.&lt;/p&gt;

&lt;p&gt;TinyRobot Kit decouples traditional fixed AI client implementations via the ResponseProvider pattern. The component and message engine remain agnostic to your underlying LLM service; they only require data formatted to match the OpenAI Chat Completions standard.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Swap LLM services freely: OpenAI, DeepSeek, local private models, internal enterprise gateways are all supported&lt;/li&gt;
&lt;li&gt;Flexible access modes: Frontend direct requests, backend proxy forwarding, unified model gateways — no changes required to UI components&lt;/li&gt;
&lt;li&gt;Stable response structure: Standardized formats for plain text, streaming chunks, and tool call payloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All vendor-specific differences are isolated to the data access layer, leaving the UI layer relying on a unified stable schema. This makes integration with existing backends, permission systems, and model routing logic far simpler.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Built-In Persistence Strategies: 3 Storage Options + Custom Extensions
&lt;/h2&gt;

&lt;p&gt;No need to implement local storage logic from scratch. The framework ships with three mature built-in storage adapters, plus support for fully custom implementations.&lt;/p&gt;

&lt;p&gt;Storage module directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;packages/kit/src/storage/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Storage Strategy&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;th&gt;Key Features&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LocalStorage&lt;/td&gt;
&lt;td&gt;Lightweight short-term chat history&lt;/td&gt;
&lt;td&gt;Synchronous read/write, simple implementation, limited capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IndexedDB&lt;/td&gt;
&lt;td&gt;Large volumes of long-term conversation records&lt;/td&gt;
&lt;td&gt;Asynchronous operation, large storage capacity, structured query support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom Adapter&lt;/td&gt;
&lt;td&gt;Enterprise backend database integration&lt;/td&gt;
&lt;td&gt;Fully self-defined logic, ideal for production business systems&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Simply implement the unified &lt;code&gt;StorageAdapter&lt;/code&gt; interface to connect any database (MongoDB, MySQL, Redis, etc.) with consistent APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Deep Dive into Core Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Full Project Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tiny-robot/
├── packages/
│   ├── components/       &lt;span class="c"&gt;# Core UI component library&lt;/span&gt;
│   │   ├── src/
│   │   │   ├── bubble/        &lt;span class="c"&gt;# Chat message bubbles&lt;/span&gt;
│   │   │   ├── sender/        &lt;span class="c"&gt;# Message input box&lt;/span&gt;
│   │   │   ├── container/     &lt;span class="c"&gt;# Chat layout container&lt;/span&gt;
│   │   │   ├── &lt;span class="nb"&gt;history&lt;/span&gt;/       &lt;span class="c"&gt;# Conversation history sidebar&lt;/span&gt;
│   │   │   ├── attachments/    &lt;span class="c"&gt;# File upload attachments&lt;/span&gt;
│   │   │   └── ...            &lt;span class="c"&gt;# Other auxiliary components&lt;/span&gt;
│   ├── kit/               &lt;span class="c"&gt;# AI data tool package&lt;/span&gt;
│   ├── svgs/              &lt;span class="c"&gt;# SVG icon library&lt;/span&gt;
│   ├── playground/        &lt;span class="c"&gt;# Local development playground&lt;/span&gt;
│   └── &lt;span class="nb"&gt;test&lt;/span&gt;/              &lt;span class="c"&gt;# Test suites&lt;/span&gt;
├── docs/                   &lt;span class="c"&gt;# Official documentation site&lt;/span&gt;
├── scripts/                &lt;span class="c"&gt;# Build scripts&lt;/span&gt;
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bubble &amp;amp; BubbleList (Message Bubble + Message List)
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;Bubble&lt;/code&gt; component is the fundamental visual unit for single chat messages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;role&lt;/code&gt; prop: Auto-styled differentiation for ai / user / system identities&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;placement&lt;/code&gt; prop: Left (&lt;code&gt;start&lt;/code&gt;) / Right (&lt;code&gt;end&lt;/code&gt;) alignment fully configurable&lt;/li&gt;
&lt;li&gt;Native streaming rendering: Incrementally render token-by-token AI output without waiting for full responses&lt;/li&gt;
&lt;li&gt;Built-in Markdown parser: Auto-format code blocks, lists, hyperlinks with zero extra code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;BubbleList&lt;/code&gt; renders full multi-turn chat streams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accept a complete &lt;code&gt;messages&lt;/code&gt; array for batch rendering of all chat records&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;roleConfigs&lt;/code&gt;: Global unified configuration for avatar, position, and visibility rules for all roles (no repeated props per message)&lt;/li&gt;
&lt;li&gt;Customizable grouping strategies: Merge consecutive same-role messages or split by user messages; fully custom grouping functions supported&lt;/li&gt;
&lt;li&gt;Intelligent &lt;code&gt;autoScroll&lt;/code&gt;: Only auto-follow streaming content when users are scrolled to the bottom, avoiding disruption while browsing history&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sender (Message Input Box)
&lt;/h3&gt;

&lt;p&gt;The user message entry component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-line text input, configurable send shortcuts (Enter / Ctrl+Enter)&lt;/li&gt;
&lt;li&gt;Native file upload integration linked with the attachments component&lt;/li&gt;
&lt;li&gt;Built-in send status management: loading / success / error states out of the box&lt;/li&gt;
&lt;li&gt;Prefix &amp;amp; suffix slots for custom widgets (emoji pickers, voice buttons, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  History (Conversation History Sidebar)
&lt;/h3&gt;

&lt;p&gt;Navigation component for multi-session chat applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supports flat list and grouped list data structures for history records&lt;/li&gt;
&lt;li&gt;Native UI for selection, renaming, deletion, pinning, and context menu operations&lt;/li&gt;
&lt;li&gt;Customizable slots for item icons, tags, and custom title content&lt;/li&gt;
&lt;li&gt;Seamless integration with &lt;code&gt;useConversation&lt;/code&gt; to build complete "history list + active chat page" workflows quickly&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Full Theme System: One-Click Dark Mode &amp;amp; Brand Customization
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tokenized CSS variable design: All colors, spacing, font sizes, and border radians controlled via CSS variables — no source code edits required for rebranding&lt;/li&gt;
&lt;li&gt;One-click dark mode toggle with complete built-in dark theme styles&lt;/li&gt;
&lt;li&gt;Zero-intrusion brand customization: Override CSS variables only to match corporate design guidelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Native Tree-Shaking Support, Controllable Bundle Size
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import only the components you need&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TrBubble&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/tiny-robot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Every component exports independently; unused components are fully tree-shaken by modern bundlers&lt;/li&gt;
&lt;li&gt;Kit and SVG packages are optional peer dependencies — they won’t increase bundle size if unused&lt;/li&gt;
&lt;li&gt;No bloated "full library" overhead; keep production builds lightweight&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Position in the OpenTiny Ecosystem
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ecosystem Partner&lt;/th&gt;
&lt;th&gt;Relationship&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TinyVue&lt;/td&gt;
&lt;td&gt;Shared OpenTiny Design system; TinyVue for general UI, TinyRobot exclusive to AI chat scenarios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GenUI SDK&lt;/td&gt;
&lt;td&gt;GenUI’s Vue renderer reuses TinyRobot’s base chat UI components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NEXT SDK&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;@opentiny/next-remoter&lt;/code&gt; builds AI chat interfaces directly on top of TinyRobot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TinyEngine&lt;/td&gt;
&lt;td&gt;TinyEngine low-code platform integrates TinyRobot for built-in LLM dialogue modules&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;TinyRobot serves as the foundational UI layer of OpenTiny’s AI ecosystem, supplying standardized chat interaction components for all upper-layer intelligent applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Summary: Is TinyRobot Worth Adopting?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Advantages 👍
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Precise vertical positioning: Specialized for AI chat instead of generic UI, no feature overlap with TinyVue&lt;/li&gt;
&lt;li&gt;Clean Composable architecture: Decouples chat business logic from UI rendering&lt;/li&gt;
&lt;li&gt;Plug-and-play ResponseProvider: Swap LLM vendors without rewriting front-end chat code&lt;/li&gt;
&lt;li&gt;Modular three-package design: Install only what you need, avoid full-library bloat&lt;/li&gt;
&lt;li&gt;Native streaming rendering built-in — a mandatory feature for AI chat that otherwise requires custom implementation&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Areas for Improvement 🤔
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Additional best practice documentation needed: SSE parsing, error recovery, model gateway integration, auth &amp;amp; tool call workflow examples&lt;/li&gt;
&lt;li&gt;Early-stage community ecosystem with limited real-world production case studies&lt;/li&gt;
&lt;li&gt;Component coverage to expand: Native rendering for reasoning chains, complex tool call outputs, and AI-specific interactive widgets&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Ideal Use Cases 🎯
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise AI assistants &amp;amp; intelligent customer service dialogue interfaces&lt;/li&gt;
&lt;li&gt;AI code assistant chat panels&lt;/li&gt;
&lt;li&gt;Low-code platform embedded AI dialogue modules&lt;/li&gt;
&lt;li&gt;Any Vue3 application requiring AI conversation interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Resources
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource Type&lt;/th&gt;
&lt;th&gt;Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Source Code&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/opentiny/tiny-robot" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-robot&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Official Documentation&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.opentiny.design/tiny-robot" rel="noopener noreferrer"&gt;https://docs.opentiny.design/tiny-robot&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quick Start Guide&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.opentiny.design/tiny-robot/quick-start" rel="noopener noreferrer"&gt;https://docs.opentiny.design/tiny-robot/quick-start&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Theme Configuration Docs&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.opentiny.design/tiny-robot/theme" rel="noopener noreferrer"&gt;https://docs.opentiny.design/tiny-robot/theme&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Official Website&lt;/td&gt;
&lt;td&gt;&lt;a href="https://opentiny.design/tiny-robot" rel="noopener noreferrer"&gt;https://opentiny.design/tiny-robot&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NPM Core Package&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/@opentiny/tiny-robot" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@opentiny/tiny-robot&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;If this article is helpful, give it a like and star the repository! Feel free to leave comments with questions or feedback.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>TinyVue 3.30 Officially Released: Multi-End Adaptation &amp; Enhanced AI-Assisted Programming</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Wed, 24 Jun 2026 08:40:01 +0000</pubDate>
      <link>https://dev.to/opentiny/tinyvue-330-officially-released-multi-end-adaptation-enhanced-ai-assisted-programming-3b7l</link>
      <guid>https://dev.to/opentiny/tinyvue-330-officially-released-multi-end-adaptation-enhanced-ai-assisted-programming-3b7l</guid>
      <description>&lt;p&gt;In the era of ubiquitous connectivity, the boundaries of frontend component libraries keep expanding. Developers demand both rigorous efficiency on PC and flexibility &amp;amp; smoothness on mobile devices.&lt;/p&gt;

&lt;p&gt;OpenTiny Community is thrilled to announce the official launch of &lt;strong&gt;TinyVue v3.30.0&lt;/strong&gt;! This release is more than a routine feature iteration — it marks a milestone leap for TinyVue in cross-screen responsive capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 Release Feature Overview
&lt;/h2&gt;

&lt;p&gt;Before diving into details, here are the major highlights of v3.30.0:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📱 Responsive Adaptation: Mobile layout support added for over 20 core components including Button and DialogBox&lt;/li&gt;
&lt;li&gt;🛠️ Component Enhancements: Custom color support for CalendarView, upgraded internationalization for RichText&lt;/li&gt;
&lt;li&gt;🤖 AI-Assisted Programming: New &lt;code&gt;AGENTS.md&lt;/code&gt; file to improve accuracy of AI coding assistants&lt;/li&gt;
&lt;li&gt;🧩 Stability Improvements: Bug fixes and dedicated compatibility patches for Safari &amp;amp; Firefox&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🌈 New Community Contributors
&lt;/h2&gt;

&lt;p&gt;The growth of TinyVue relies on every contributor. We’d like to extend special gratitude to two new contributors who submitted their first code in this release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@ga163&lt;/li&gt;
&lt;li&gt;@zhengshui&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also thank our 9 long-term regular contributors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;discreted66&lt;/li&gt;
&lt;li&gt;gimmyhehe&lt;/li&gt;
&lt;li&gt;James-9696&lt;/li&gt;
&lt;li&gt;kagol&lt;/li&gt;
&lt;li&gt;ourcx&lt;/li&gt;
&lt;li&gt;shenjunjian&lt;/li&gt;
&lt;li&gt;wuyiping0628&lt;/li&gt;
&lt;li&gt;Yujing613&lt;/li&gt;
&lt;li&gt;zzcr&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OpenTiny keeps evolving thanks to all your hard work and dedication 👏&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Core Highlight Breakdown
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Responsive Layout: Seamless Integration Between PC &amp;amp; Mobile
&lt;/h3&gt;

&lt;p&gt;TinyVue v3.30 carries out in-depth cross-end refactoring for &lt;strong&gt;20+ core components&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Component Upgrades: &lt;code&gt;Link&lt;/code&gt;, &lt;code&gt;Cascader&lt;/code&gt;, &lt;code&gt;Search&lt;/code&gt;, &lt;code&gt;Breadcrumb&lt;/code&gt;, &lt;code&gt;Steps&lt;/code&gt;, &lt;code&gt;DialogBox&lt;/code&gt;, &lt;code&gt;Form&lt;/code&gt;, &lt;code&gt;Modal&lt;/code&gt;, &lt;code&gt;Button&lt;/code&gt; and more can now automatically detect viewport sizes and switch to optimized interaction modes.&lt;/li&gt;
&lt;li&gt;Consistent User Experience: Whether users operate on large desktop screens or tap mobile touchscreens, TinyVue delivers unified, polished visual experiences tailored for each device.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0knd2aokbmf4qqk3cdj1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0knd2aokbmf4qqk3cdj1.gif" alt=" " width="560" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Polished Interaction Details
&lt;/h3&gt;

&lt;p&gt;Great component libraries stand out through refined edge cases, and this version upgrades multiple complex components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CalendarView&lt;/strong&gt;: Supports custom theme colors to satisfy personalized schedule display requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgfca4xdrei3ymtdka2np.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgfca4xdrei3ymtdka2np.gif" alt=" " width="760" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RichText&lt;/strong&gt;: Full i18n internationalization support; optimized editor border rendering and hyperlink redirect interception for professional content creation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate&lt;/strong&gt;: Fixed color switching bug for half-star selection to deliver smoother visual feedback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drawer&lt;/strong&gt;: New &lt;code&gt;appendToBody&lt;/code&gt; prop completely resolves occlusion and z-index issues in complex layouts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. AI as Your New Development Teammate
&lt;/h3&gt;

&lt;p&gt;OpenTiny keeps pace with AI development trends, with major AI tooling improvements in v3.30:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AGENTS.md&lt;/strong&gt;: A dedicated structured context file for AI coding assistants (GitHub Copilot and similar tools), helping AI better understand TinyVue project architecture.
Doc Link: &lt;a href="https://github.com/opentiny/tiny-vue/blob/dev/AGENTS.md" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-vue/blob/dev/AGENTS.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Build with AI: Updated documentation exploring unlimited combinations between component libraries and AI tools.
Doc Link: &lt;a href="https://github.com/opentiny/tiny-vue/blob/dev/README.zh-CN.md" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-vue/blob/dev/README.zh-CN.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🐛 Stability: Bug Fixes &amp;amp; Optimizations
&lt;/h2&gt;

&lt;p&gt;While rolling out new features, we prioritize long-term stability. This release contains numerous fixes covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-browser Compatibility: Resolved massive blank space and multi-line rendering defects for read-only Input on Safari; fixed horizontal scrollbar anomalies for tables on Firefox&lt;/li&gt;
&lt;li&gt;Engineering Optimizations: Improved style isolation under SaaS mode; refined E2E test cases to strengthen stability in complex production environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full Changelog: &lt;a href="https://github.com/opentiny/tiny-vue/releases/tag/v3.30.0" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-vue/releases/tag/v3.30.0&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔗 Upgrade Guide
&lt;/h2&gt;

&lt;p&gt;Install &lt;code&gt;@opentiny/vue@3.30.0&lt;/code&gt; to experience the latest version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npm&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; @opentiny/vue@3.30.0

&lt;span class="c"&gt;# yarn&lt;/span&gt;
yarn add @opentiny/vue@3.30.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Closing Remarks
&lt;/h2&gt;

&lt;p&gt;TinyVue 3.30 represents a critical milestone toward full-scenario, multi-terminal coverage. Whether building complex enterprise backends or lightweight mobile applications, TinyVue aims to be your most reliable UI partner.&lt;/p&gt;

&lt;h2&gt;
  
  
  About OpenTiny NEXT
&lt;/h2&gt;

&lt;p&gt;OpenTiny NEXT is an enterprise intelligent frontend solution built on Generative UI and WebMCP. It intelligently upgrades legacy products including TinyVue component library and TinyEngine low-code engine, and launches new Agent-oriented products such as NEXT-SDKs for frontend, AI Extension, TinyRobot AI Assistant and GenUI. It empowers AI to comprehend user intentions and execute tasks autonomously, accelerating enterprise intelligent transformation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the OpenTiny Open Source Community
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WeChat Assistant: opentiny-official&lt;/li&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design" rel="noopener noreferrer"&gt;https://opentiny.design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TinyVue Repository: &lt;a href="https://github.com/opentiny/tiny-vue" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-vue&lt;/a&gt; (Star ⭐ appreciated)&lt;/li&gt;
&lt;li&gt;About Us: &lt;a href="https://opentiny.design/opentiny-design/about" rel="noopener noreferrer"&gt;https://opentiny.design/opentiny-design/about&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to contribute, look for &lt;code&gt;good first issue&lt;/code&gt; labels in the repo. Feel free to leave comments with any questions or feedback!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Diving Into GenUI SDK Source Code: How AI Enables Both Chat &amp; Dynamic Page Rendering</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Wed, 24 Jun 2026 06:20:18 +0000</pubDate>
      <link>https://dev.to/opentiny/diving-into-genui-sdk-source-code-how-ai-enables-both-chat-dynamic-page-rendering-2g65</link>
      <guid>https://dev.to/opentiny/diving-into-genui-sdk-source-code-how-ai-enables-both-chat-dynamic-page-rendering-2g65</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;When AI responses evolve beyond plain Markdown text and directly render interactive forms, charts and cards — this marks the next frontier of AI interaction. Enter GenUI SDK.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. What Is This Project All About?
&lt;/h2&gt;

&lt;p&gt;GenUI SDK is a full-stack development toolkit built by the OpenTiny team around &lt;strong&gt;Generative UI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The core concept is straightforward, as shown in the comparison table below:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Traditional Conversational AI&lt;/th&gt;
&lt;th&gt;Generative UI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AI Output&lt;/td&gt;
&lt;td&gt;Plain text / Markdown&lt;/td&gt;
&lt;td&gt;Interactive components (forms, charts, cards)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User Operations&lt;/td&gt;
&lt;td&gt;Only send follow-up messages&lt;/td&gt;
&lt;td&gt;Directly interact with UI generated by AI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Information Density&lt;/td&gt;
&lt;td&gt;Low (text-based order descriptions)&lt;/td&gt;
&lt;td&gt;High (visual order cards with actionable buttons)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Example Scenario
&lt;/h3&gt;

&lt;p&gt;If a user asks to check their order status:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traditional AI replies with paragraphs of text describing order details.&lt;/li&gt;
&lt;li&gt;Generative UI renders a complete order card with status tags and clickable "Cancel Order" buttons.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GenUI SDK’s core mission: Upgrade AI output from natural language to component description language.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Current version: &lt;code&gt;@opentiny/genui-sdk-vue@1.2.1&lt;/code&gt;, released under the MIT License.&lt;br&gt;
Code composition: 66.2% TypeScript + 31.2% Vue.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Core Mechanism: Schema-Driven Rendering
&lt;/h2&gt;

&lt;p&gt;The "magic" of GenUI SDK relies on a fixed processing pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Output → UI Schema → Renderer Parsing → Vue/Angular Components → User Interaction → New Message → AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A UI Schema is descriptive component definitions, not hardcoded HTML or Vue templates, which specify:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Component type (&lt;code&gt;Form&lt;/code&gt;, &lt;code&gt;Card&lt;/code&gt;, &lt;code&gt;Chart&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Component properties (form fields, card content, chart datasets)&lt;/li&gt;
&lt;li&gt;Interactive behaviors (button clicks, form submission callbacks)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Key Insight
&lt;/h3&gt;

&lt;p&gt;AI outputs component descriptive language instead of raw natural language. The front-end renderer translates these descriptions into real UI elements.&lt;br&gt;
AI developers do not need to write Vue syntax — they only need to define requirements such as "a table with three columns and the following data".&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Architecture Breakdown: Integrated Frontend &amp;amp; Backend Multi-Package Design
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;genui-sdk/&lt;/span&gt;
&lt;span class="s"&gt;├── packages/&lt;/span&gt;
&lt;span class="s"&gt;│   ├── server/&lt;/span&gt;                &lt;span class="c1"&gt;# Backend service package&lt;/span&gt;
&lt;span class="s"&gt;│   ├── frameworks/&lt;/span&gt;
&lt;span class="s"&gt;│   │   ├── vue/&lt;/span&gt;               &lt;span class="c1"&gt;# Vue renderer&lt;/span&gt;
&lt;span class="s"&gt;│   │   └── angular/&lt;/span&gt;           &lt;span class="c1"&gt;# Angular renderer&lt;/span&gt;
&lt;span class="s"&gt;│   ├── core/&lt;/span&gt;                  &lt;span class="c1"&gt;# Shared core logic&lt;/span&gt;
&lt;span class="s"&gt;│   ├── materials/&lt;/span&gt;             &lt;span class="c1"&gt;# Component material definitions&lt;/span&gt;
&lt;span class="s"&gt;│   ├── chat-completions/&lt;/span&gt;      &lt;span class="c1"&gt;# Chat completion utilities&lt;/span&gt;
&lt;span class="s"&gt;│   ├── benchmarks/&lt;/span&gt;            &lt;span class="c1"&gt;# Performance benchmark scripts&lt;/span&gt;
&lt;span class="s"&gt;│   └── ...&lt;/span&gt;
&lt;span class="s"&gt;├── projects/&lt;/span&gt;                   &lt;span class="c1"&gt;# Demo projects&lt;/span&gt;
&lt;span class="s"&gt;├── sites/&lt;/span&gt;                      &lt;span class="c1"&gt;# Playground website&lt;/span&gt;
&lt;span class="s"&gt;├── docs/&lt;/span&gt;                       &lt;span class="c1"&gt;# Official documentation&lt;/span&gt;
&lt;span class="s"&gt;└── pnpm-workspace.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package Name&lt;/th&gt;
&lt;th&gt;Core Responsibility&lt;/th&gt;
&lt;th&gt;Key Capabilities&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/genui-sdk-server&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Backend brain&lt;/td&gt;
&lt;td&gt;LLM integration, message orchestration, tool calling, access control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/genui-sdk-vue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Vue front-end renderer&lt;/td&gt;
&lt;td&gt;Schema parsing, dynamic component rendering, theme customization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/genui-sdk-angular&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Angular front-end renderer&lt;/td&gt;
&lt;td&gt;Schema parsing, dynamic Angular component rendering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Full-Stack Integration
&lt;/h3&gt;

&lt;p&gt;GenUI is not merely a front-end wrapper. The Server package acts as the central brain, converting plain LLM text responses into structured payloads carrying renderable UI Schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Server Package: More Than a Simple LLM Proxy
&lt;/h2&gt;

&lt;p&gt;The core value of the Server package lies in response orchestration and enhancement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LLM Integration&lt;/strong&gt;: Compliant with OpenAI API specs, compatible with OpenAI, DeepSeek, Anthropic and other mainstream large models&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Message Orchestration&lt;/strong&gt;: Assemble user prompts, AI replies and tool return values into complete conversation streams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Tool Extensions&lt;/strong&gt;: Connect external/enterprise systems via Model Context Protocol to expand AI tooling capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access Control&lt;/strong&gt;: Assign distinct tool permissions for different users, a critical requirement for enterprise scenarios&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Actions&lt;/strong&gt;: Configure custom commands such as page navigation and dynamic form generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short: The Server layer does not simply forward raw API responses — it translates plain AI text into renderable instructions for the front end.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Vue Renderer: Translator Between Schema &amp;amp; Real Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Vue Renderer Workflow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Receive UI Schema returned by the LLM&lt;/li&gt;
&lt;li&gt;Parse schema into standardized component definitions (type, props, interactions)&lt;/li&gt;
&lt;li&gt;Dynamically mount components via Vue’s built-in &lt;code&gt;&amp;lt;component :is="xxx"&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Wrap user interactive events into standardized messages and send them back to the AI&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Customization Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom Component Registration&lt;/strong&gt;: Register business-specific components so the AI can generate them alongside standard UI elements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Interaction Flows&lt;/strong&gt;: Configure multi-turn dialogue logic and custom command handlers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tokenized Theming System&lt;/strong&gt;: Full support for brand styling and dark mode&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Materials System: The AI’s UI Vocabulary Library
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/materials/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Materials package serves as GenUI’s dictionary of available UI building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each material defines a component’s specifications: name, props, default values and interactive rules&lt;/li&gt;
&lt;li&gt;The AI can only render components registered in the Materials library, eliminating unrenderable UI output&lt;/li&gt;
&lt;li&gt;Developers can extend the library with new materials to expand the AI’s UI generation vocabulary&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Material Extension Process
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Register component Schema definitions in Materials&lt;/li&gt;
&lt;li&gt;Register corresponding component implementations in Vue/Angular renderers&lt;/li&gt;
&lt;li&gt;Configure the Server layer to enable AI generation of this component&lt;/li&gt;
&lt;li&gt;The LLM can now output this component type in its responses&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI generation capabilities always align with front-end rendering support — eliminating mismatches where the AI outputs UI elements the client cannot display.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. MCP Tool Integration: AI Beyond Visual Display
&lt;/h2&gt;

&lt;p&gt;GenUI SDK fully supports Model Context Protocol (MCP) extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI can invoke tools mid-conversation: query databases, call external APIs, read file data&lt;/li&gt;
&lt;li&gt;Raw tool return data can be automatically converted into Generative UI components such as data tables&lt;/li&gt;
&lt;li&gt;MCP transforms GenUI from a pure presentation layer into a complete business operation layer&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Example
&lt;/h3&gt;

&lt;p&gt;When a user asks to pull monthly sales data, the AI will not only describe metrics in text — it renders an interactive chart with built-in dimension switching and filtering functions, enabling true hands-on AI operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Angular Renderer: True Cross-Framework Compatibility
&lt;/h2&gt;

&lt;p&gt;The Angular renderer mirrors all functionality of the Vue renderer, leveraging Angular’s dynamic component APIs to render Schema-defined UI elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cross-Framework Design Philosophy
&lt;/h3&gt;

&lt;p&gt;Schemas are universal, while renderers are interchangeable. Developers can select either Vue or Angular without being locked into a single framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Playground: Self-Demonstrating Demo Environment
&lt;/h2&gt;

&lt;p&gt;GenUI provides an official online Playground:&lt;br&gt;
&lt;a href="https://opentiny.github.io/genui-sdk/playground/" rel="noopener noreferrer"&gt;https://opentiny.github.io/genui-sdk/playground/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The standout feature: the Playground itself is built entirely with GenUI SDK. All interactive UI elements generated during your chat sessions are real production-grade GenUI outputs — a live demo more persuasive than static documentation screenshots.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. GenUI’s Position Within the OpenTiny Ecosystem
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ecosystem Partner&lt;/th&gt;
&lt;th&gt;Relationship&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TinyRobot&lt;/td&gt;
&lt;td&gt;GenUI’s Vue renderer may reuse TinyRobot’s base chat UI components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NEXT SDK&lt;/td&gt;
&lt;td&gt;NEXT SDK’s WebMCP module provides browser-side transport for GenUI tool calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TinyVue&lt;/td&gt;
&lt;td&gt;GenUI’s built-in materials include native TinyVue components — AI can generate standard TinyVue UI out of the box&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TinyEngine&lt;/td&gt;
&lt;td&gt;Shares core schema-driven rendering logic with low-code engines&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;GenUI SDK sits in the top AI application layer of the OpenTiny stack. It leverages underlying UI components (TinyVue / TinyRobot) and protocol layers (NEXT SDK / WebMCP) to build end-user-facing Generative AI applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Summary: The Next Era of AI Interaction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Core Innovations
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generative UI Paradigm&lt;/strong&gt;: Shift from text-only dialogue to fully interactive AI-generated interfaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;End-to-End Frontend &amp;amp; Backend Integration&lt;/strong&gt;: Complete Server + Vue/Angular stack instead of isolated front-end shells&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema-Driven Architecture&lt;/strong&gt;: Framework-agnostic descriptive layer connecting LLM outputs and client rendering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensible Material Library&lt;/strong&gt;: Controlled expansion of the AI’s UI generation vocabulary&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Core Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Compliant with OpenAI API standards, low barrier for LLM access&lt;/li&gt;
&lt;li&gt;Dual official renderers for Vue and Angular, no framework lock-in&lt;/li&gt;
&lt;li&gt;Native MCP integration enabling AI to perform actionable business operations&lt;/li&gt;
&lt;li&gt;Self-contained Playground for live, tangible product demonstrations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Current Limitations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Small GitHub star count; the project is still in early adoption and requires more real-world case validation&lt;/li&gt;
&lt;li&gt;Generative UI relies on well-engineered LLM prompts to produce valid Schema outputs&lt;/li&gt;
&lt;li&gt;The upper limit of AI UI complexity is determined by the richness of registered materials&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ideal Application Scenarios
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AI customer service panels with one-click business operations&lt;/li&gt;
&lt;li&gt;Dynamic AI-powered data visualization dashboards&lt;/li&gt;
&lt;li&gt;Context-aware conversational form filling&lt;/li&gt;
&lt;li&gt;Enterprise internal AI assistant interaction upgrades&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GenUI SDK pioneers the next generation of AI front-end interaction, moving beyond plain text dialogue to fully interactive generative UI. While the project is in its early stages, its architecture delivers a clear long-term vision and solid engineering foundations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Resources
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource Type&lt;/th&gt;
&lt;th&gt;Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Source Code&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/opentiny/genui-sdk" rel="noopener noreferrer"&gt;https://github.com/opentiny/genui-sdk&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Official Documentation&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.opentiny.design/genui-sdk/guide/quick-start.html" rel="noopener noreferrer"&gt;https://docs.opentiny.design/genui-sdk/guide/quick-start.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Online Playground&lt;/td&gt;
&lt;td&gt;&lt;a href="https://opentiny.github.io/genui-sdk/playground/" rel="noopener noreferrer"&gt;https://opentiny.github.io/genui-sdk/playground/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server Usage Docs&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.opentiny.design/genui-sdk/guide/server-usage.html" rel="noopener noreferrer"&gt;https://docs.opentiny.design/genui-sdk/guide/server-usage.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Official Website&lt;/td&gt;
&lt;td&gt;&lt;a href="https://opentiny.design/genui-sdk" rel="noopener noreferrer"&gt;https://opentiny.design/genui-sdk&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NPM Vue Package&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/@opentiny/genui-sdk-vue" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@opentiny/genui-sdk-vue&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;If this project interests you, give it a like and star the repo to share it with more developers! Generative UI represents the next major wave of AI interaction — get ahead of the curve by learning it early.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  About OpenTiny NEXT
&lt;/h2&gt;

&lt;p&gt;OpenTiny NEXT is an enterprise-grade intelligent front-end development solution built on Generative UI and WebMCP core technologies. It delivers intelligent upgrades for legacy products including the TinyVue component library and TinyEngine low-code engine, while launching new Agent-native products such as front-end NEXT-SDKs, AI Extension, TinyRobot AI Assistant and GenUI. The stack enables AI to interpret user intentions and complete tasks autonomously, accelerating intelligent transformation for enterprise applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the OpenTiny Open Source Community
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WeChat Assistant: opentiny-official&lt;/li&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design" rel="noopener noreferrer"&gt;https://opentiny.design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GenUI SDK Repository: &lt;a href="https://github.com/opentiny/genui-sdk" rel="noopener noreferrer"&gt;https://github.com/opentiny/genui-sdk&lt;/a&gt; (Star ⭐ appreciated)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you wish to contribute, look for issues tagged &lt;code&gt;good first issue&lt;/code&gt; within the repository. Feel free to leave comments with any questions or feedback!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>TinyRobot Bubble: A Vue 3 Message Bubble Component Built Exclusively for AI Conversations</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Mon, 22 Jun 2026 12:17:08 +0000</pubDate>
      <link>https://dev.to/opentiny/tinyrobot-bubble-a-vue-3-message-bubble-component-built-exclusively-for-ai-conversations-108n</link>
      <guid>https://dev.to/opentiny/tinyrobot-bubble-a-vue-3-message-bubble-component-built-exclusively-for-ai-conversations-108n</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Message bubbles may seem like a trivial UI element in AI applications, yet they grow highly complex once put into production. Typical requirements include token-by-token streaming output, Markdown rendering, image display, multi-modal content, reasoning process unfolding, tool call visualization, message grouping, collapsible states, role-specific styles, auto-scrolling, and more. Implementing all of these features from scratch bloats business code with tedious presentation logic.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Bubble&lt;/code&gt; component of TinyRobot is purpose-built to solve this pain point. Rather than a simple text bubble, it delivers a complete message rendering system for AI chat interfaces, consisting of three core primitives: &lt;code&gt;Bubble&lt;/code&gt;, &lt;code&gt;BubbleList&lt;/code&gt; and &lt;code&gt;BubbleProvider&lt;/code&gt;. Developers can seamlessly scale from rendering single messages to full conversation streams.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcbjs0zg6ae7d2g67hd89.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcbjs0zg6ae7d2g67hd89.png" alt=" " width="800" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Render One AI Message with Minimal Code
&lt;/h2&gt;

&lt;p&gt;Basic usage is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;tr-bubble&lt;/span&gt;
    &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"assistant"&lt;/span&gt;
    &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Hello, I'm TinyRobot, here to help you quickly build AI chat interfaces."&lt;/span&gt;
    &lt;span class="na"&gt;placement=&lt;/span&gt;&lt;span class="s"&gt;"start"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TrBubble&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@opentiny/tiny-robot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;placement&lt;/code&gt; prop controls left/right alignment, while the &lt;code&gt;avatar&lt;/code&gt; slot accepts custom avatar components. Visual styles such as background color, font size, border radius and width can be customized via CSS variables. This allows teams to rapidly build functional UIs and refine styling to match product designs later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactive Content Optimized for Streaming Output
&lt;/h2&gt;

&lt;p&gt;AI responses are returned incrementally token by token instead of in one full payload. The &lt;code&gt;content&lt;/code&gt; property of &lt;code&gt;Bubble&lt;/code&gt; is fully reactive — simply update its value continuously to achieve native streaming effects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TrBubble&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@opentiny/tiny-robot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IconAi&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@opentiny/tiny-robot-svgs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aiAvatar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;IconAi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;32px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;streamContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;startStream&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fullText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is an AI response being generated token by token.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;streamContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;fullText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;streamContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This architecture works perfectly with SSE, Fetch Stream, or the message management utilities from TinyRobot Kit. The presentation layer only reacts to changes in message data without embedding streaming logic inside the component itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F74i34rc8ieq0nuoygt6c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F74i34rc8ieq0nuoygt6c.gif" alt=" " width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Support for More Than Text: Images, Markdown, Reasoning &amp;amp; Tool Calls
&lt;/h2&gt;

&lt;p&gt;The Bubble content model aligns with standard LLM message structures. The &lt;code&gt;content&lt;/code&gt; prop accepts either plain strings or structured arrays for multi-modal content, such as images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;tr-bubble&lt;/span&gt;
  &lt;span class="na"&gt;content-render-mode=&lt;/span&gt;&lt;span class="s"&gt;"split"&lt;/span&gt;
  &lt;span class="na"&gt;:content=&lt;/span&gt;&lt;span class="s"&gt;"[
    { type: 'text', text: 'Here is the generated result:' },
    { type: 'image_url', image_url: { url: imageUrl } }
  ]"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When items carry the &lt;code&gt;image_url&lt;/code&gt; type, the built-in image renderer activates automatically. Use &lt;code&gt;contentRenderMode&lt;/code&gt; to render all media within a single bubble box or split them into separate blocks.&lt;/p&gt;

&lt;p&gt;Pre-built renderers are included for all common AI output types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text: Plain text rendering&lt;/li&gt;
&lt;li&gt;Image: Image asset rendering&lt;/li&gt;
&lt;li&gt;Markdown: Full Markdown syntax support&lt;/li&gt;
&lt;li&gt;Loading: Placeholder loading state&lt;/li&gt;
&lt;li&gt;Reasoning: Collapsible model thinking process&lt;/li&gt;
&lt;li&gt;Tools / Tool: Single or batch function call visualization&lt;/li&gt;
&lt;li&gt;ToolRole: Dedicated styling for tool response messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Render reasoning content by passing the dedicated &lt;code&gt;reasoning_content&lt;/code&gt; prop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;tr-bubble&lt;/span&gt;
  &lt;span class="na"&gt;:content=&lt;/span&gt;&lt;span class="s"&gt;"answer"&lt;/span&gt;
  &lt;span class="na"&gt;:reasoning_content=&lt;/span&gt;&lt;span class="s"&gt;"reasoningContent"&lt;/span&gt;
  &lt;span class="na"&gt;:state=&lt;/span&gt;&lt;span class="s"&gt;"{ thinking: false, open: true }"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tool calls follow the standard OpenAI schema format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assistant&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I will look up the weather for you.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;call_0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get_weather&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{"city":"Shenzhen"}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;toolCall&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;call_0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;running&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This design makes Bubble ideal for building Agents, Copilots, enterprise knowledge base assistants, and other products that need transparent visibility into model execution steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F23dqeoxa55y79yby08qz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F23dqeoxa55y79yby08qz.gif" alt=" " width="760" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  BubbleList: Scale from Single Bubbles to Full Conversation Flows
&lt;/h2&gt;

&lt;p&gt;Real-world chat interfaces render sequences of messages. The &lt;code&gt;BubbleList&lt;/code&gt; component accepts a &lt;code&gt;messages&lt;/code&gt; array and unifies avatar, alignment and visibility rules across roles via &lt;code&gt;roleConfigs&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;tr-bubble-list&lt;/span&gt;
    &lt;span class="na"&gt;auto-scroll&lt;/span&gt;
    &lt;span class="na"&gt;:messages=&lt;/span&gt;&lt;span class="s"&gt;"messages"&lt;/span&gt;
    &lt;span class="na"&gt;:role-configs=&lt;/span&gt;&lt;span class="s"&gt;"roleConfigs"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BubbleListProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BubbleRoleConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@opentiny/tiny-robot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TrBubbleList&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@opentiny/tiny-robot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BubbleListProps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;messages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Summarize this document for me&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assistant&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sure, please upload your document.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;roleConfigs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BubbleRoleConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;placement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;assistant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;placement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default grouping strategy uses user messages as dividers: every user message starts a new group, and all subsequent non-user messages are merged into the same reply block. Two alternative grouping modes are available: consecutive role grouping, or fully custom grouping functions.&lt;/p&gt;

&lt;p&gt;This grouping logic fits standard AI chat workflows naturally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Message
└─ Assistant Reply Group
   ├─ Assistant: Initiate data lookup via tool calls
   ├─ Tool: Return ticket details
   ├─ Tool: Return SLA policy rules
   └─ Assistant: Risk analysis based on tool outputs

User Message
└─ Assistant Reply Group
   ├─ Assistant: Fetch assignee and approval status
   ├─ Tool: Return handler information
   └─ Assistant: Recommended resolution steps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;autoScroll&lt;/code&gt; feature is optimized for chat UX:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scrolls smoothly to the bottom when users send new messages&lt;/li&gt;
&lt;li&gt;Only follows streaming updates if the user is already viewing the bottom, avoiding disruption while browsing history.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Renderer Architecture: Extend Content Types Without Rewriting Components
&lt;/h2&gt;

&lt;p&gt;One of Bubble’s core advantages is its pluggable renderer system. Render logic is split into two independent layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Box Renderer: Controls the outer bubble container layout and styling&lt;/li&gt;
&lt;li&gt;Content Renderer: Handles internal rendering of text, media, tool outputs, and custom widgets&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Register global renderers across your entire component tree with &lt;code&gt;BubbleProvider&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;tr-bubble-provider&lt;/span&gt; &lt;span class="na"&gt;:content-renderer-matches=&lt;/span&gt;&lt;span class="s"&gt;"contentRendererMatches"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;tr-bubble-list&lt;/span&gt; &lt;span class="na"&gt;:messages=&lt;/span&gt;&lt;span class="s"&gt;"messages"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/tr-bubble-provider&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BubbleRendererMatchPriority&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BubbleContentRendererMatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@opentiny/tiny-robot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;markRaw&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SchemaCardRenderer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./SchemaCardRenderer.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contentRendererMatches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BubbleContentRendererMatch&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;schema_card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;markRaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SchemaCardRenderer&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BubbleRendererMatchPriority&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CONTENT&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern lets teams inject custom structured widgets — order cards, approval panels, knowledge base citations, charts — without forking component source or writing massive conditional rendering logic inside message lists.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Isolation Optimized for Enterprise AI Systems
&lt;/h2&gt;

&lt;p&gt;All transient UI states (expanded reasoning panels, unfolded tool call details, like/dislike feedback) are stored separately in the &lt;code&gt;state&lt;/code&gt; field of each message. State change events are emitted via &lt;code&gt;state-change&lt;/code&gt; to parent components.&lt;/p&gt;

&lt;p&gt;This separation keeps raw LLM message payloads clean and serializable for API transmission or database persistence, without polluting core business data with temporary UI flags.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;TinyRobot Bubble is far more than a set of aesthetic chat bubbles. It encapsulates all repetitive, complex presentation logic common to AI chat interfaces into a composable system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single message rendering: &lt;code&gt;Bubble&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Full conversation stream rendering: &lt;code&gt;BubbleList&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Global custom content extension: &lt;code&gt;BubbleProvider&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Native built-in support for text, images, Markdown, reasoning chains and tool calls&lt;/li&gt;
&lt;li&gt;Full coverage of role styling, message grouping, auto-scrolling, slots and complete TypeScript typing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you build AI Chat, Agent consoles, enterprise knowledge assistants or Copilot products with Vue 3, TinyRobot Bubble frees you from low-level UI implementation work to focus on core AI user value.&lt;/p&gt;

&lt;h2&gt;
  
  
  About OpenTiny NEXT
&lt;/h2&gt;

&lt;p&gt;OpenTiny NEXT is an enterprise intelligent front-end solution built on two core technologies: Generative UI and WebMCP. It intelligently upgrades legacy products including the TinyVue component library and TinyEngine low-code engine, while launching new Agent-oriented products: NEXT-SDKs for frontend, AI Extension, TinyRobot AI Assistant and GenUI. The suite empowers AI to interpret user intentions and execute tasks autonomously, accelerating intelligent transformation for enterprise applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the OpenTiny Open Source Community
&lt;/h3&gt;

&lt;p&gt;WeChat Assistant: opentiny-official&lt;br&gt;
Official Website: &lt;a href="https://opentiny.design" rel="noopener noreferrer"&gt;https://opentiny.design&lt;/a&gt;&lt;br&gt;
TinyRobot Repository: &lt;a href="https://github.com/opentiny/tiny-robot" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-robot&lt;/a&gt; (Star ⭐ appreciated)&lt;/p&gt;

&lt;p&gt;To contribute, look for issues tagged &lt;code&gt;good first issue&lt;/code&gt; in the repository. Feel free to leave comments with any questions or feedback!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Add AI Chat Entry with One Single Command! TinyRobot Makes It Super Easy</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Wed, 17 Jun 2026 09:08:16 +0000</pubDate>
      <link>https://dev.to/opentiny/add-ai-chat-entry-with-one-single-command-tinyrobot-makes-it-super-easy-31mj</link>
      <guid>https://dev.to/opentiny/add-ai-chat-entry-with-one-single-command-tinyrobot-makes-it-super-easy-31mj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the AI era, AI capabilities are advancing rapidly. Many teams want to add an AI chat entry to their projects. It sounds simple, yet implementation brings lots of work: chat UI, streaming response rendering, conversation state management, Markdown rendering, responsive layout, and more. These features are trivial separately, but combined together, they take massive development effort.&lt;/p&gt;

&lt;p&gt;Is there a simpler, low-effort way to quickly build an AI chat application or embed an AI dialogue entry into existing projects?&lt;/p&gt;

&lt;p&gt;Absolutely! That’s exactly what TinyRobot is built for.&lt;br&gt;
Besides providing basic AI components like chat bubbles and input boxes as a component library, TinyRobot now ships with the &lt;strong&gt;TinyRobot CLI&lt;/strong&gt;. Two simple commands cover two core scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a full project: Run the &lt;code&gt;create&lt;/code&gt; command to generate a fully functional runnable TinyRobot demo project.&lt;/li&gt;
&lt;li&gt;Integrate into existing projects: Run the &lt;code&gt;add&lt;/code&gt; command to inject AI chat components into your existing Vue project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To put it simply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you don’t have a project yet or want to preview the complete experience, use &lt;code&gt;create&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you own an existing project and only need an extra chat entry, use &lt;code&gt;add&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What Is TinyRobot?
&lt;/h2&gt;

&lt;p&gt;TinyRobot is a Vue 3 interactive component library and dialogue framework built for enterprise AI applications.&lt;br&gt;
Built on the OpenTiny design system, it solves common front-end challenges for AI applications, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organizing chat messages and dialogue UI&lt;/li&gt;
&lt;li&gt;Rendering real-time streaming messages&lt;/li&gt;
&lt;li&gt;Managing conversation states&lt;/li&gt;
&lt;li&gt;Rapidly building AI assistants, intelligent customer service, and multi-turn dialogue pages&lt;/li&gt;
&lt;li&gt;Responsive UI layout&lt;/li&gt;
&lt;li&gt;Unified component styling and easy extension&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can write a simple chat box from scratch for small demos. But real production projects introduce extra complexity: message statuses, loading states, error prompts, multi-turn context, multi-model vendor configuration, and business component integration. All of these require heavy front-end encapsulation.&lt;/p&gt;

&lt;p&gt;TinyRobot pre-packages repetitive interaction logic and engineering infrastructure for AI dialogue applications, allowing teams to move straight to business validation faster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxwna87zp9lq7veecpt0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxwna87zp9lq7veecpt0.png" alt=" " width="799" height="334"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why We Built the CLI Tool
&lt;/h2&gt;

&lt;p&gt;From questionnaires, Q&amp;amp;A sessions and live stream feedback, we repeatedly received these requests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to build an AI Q&amp;amp;A interface quickly without writing every component manually.&lt;/li&gt;
&lt;li&gt;Is there a complete dialogue UI component I can import directly?&lt;/li&gt;
&lt;li&gt;I already have an existing business project — can TinyRobot be integrated quickly?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These demands reflect the universal pursuit of higher development efficiency in the AI age. The CLI enables fast project initialization and code injection to cut development time. It also works seamlessly with AI Agents: you can pass this article to an AI and let it execute CLI commands automatically to finish integration, saving manual work. Meanwhile, the CLI lays groundwork for future AI-native features.&lt;/p&gt;

&lt;p&gt;We identified two distinct usage scenarios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start from scratch for validation: Teams without an existing integration solution want to preview the full TinyRobot experience with minimal commands.&lt;/li&gt;
&lt;li&gt;Incremental integration into live projects: Systems such as admin dashboards, workbenches and portals are already online or under development. The priority is to add an AI dialogue entry with minimal code changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thus, TinyRobot CLI provides two core commands to cover both scenarios:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommended Command&lt;/th&gt;
&lt;th&gt;Use Cases&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No existing project, or want to preview full features&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;create&lt;/code&gt; to generate a complete project&lt;/td&gt;
&lt;td&gt;Demos, prototypes, PoCs, solution validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Existing Vue project ready&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;add&lt;/code&gt; to inject chat components&lt;/td&gt;
&lt;td&gt;AI entry for admin systems, workbenches, portals&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;create&lt;/code&gt; if you need a fully functional standalone demo.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;add&lt;/code&gt; if you only want to add chat capabilities to an existing project.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Path 1: Create a Full Project with &lt;code&gt;create&lt;/code&gt; Command
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;create&lt;/code&gt; command is ideal for rapid preview. It generates a complete project for first-time users to experience the full feature set of TinyRobot.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Execute creation command
&lt;/h3&gt;

&lt;p&gt;Run via npm or pnpm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npm&lt;/span&gt;
npx @opentiny/tiny-robot-cli create

&lt;span class="c"&gt;# pnpm&lt;/span&gt;
pnpm dlx @opentiny/tiny-robot-cli create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdycwtlshb3hc71dkncv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdycwtlshb3hc71dkncv5.png" alt=" " width="391" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After generation, enter the project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &amp;lt;project-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configure environment variables
&lt;/h3&gt;

&lt;p&gt;The generated project comes with sample configs for two LLM providers: DeepSeek and Alibaba DashScope.&lt;br&gt;
Copy the sample env file and fill in your API keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &amp;lt;your-project-path&amp;gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;span class="c"&gt;# Edit .env afterwards&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sample env config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Alibaba DashScope API Key (required for some MCP plugins)
VITE_ALIYUN_DASHSCOPE_KEY=

# DeepSeek API Key
VITE_DEEPSEEK_API_KEY=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template includes 3 built-in MCP plugin examples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;12306 ticket query powered by Alibaba DashScope&lt;/li&gt;
&lt;li&gt;Amap Maps&lt;/li&gt;
&lt;li&gt;Generic Model Context Protocol demo&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The DashScope MCP plugins require &lt;code&gt;VITE_ALIYUN_DASHSCOPE_KEY&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Variables prefixed with &lt;code&gt;VITE_&lt;/code&gt; are injected into the build output and exposed to the browser. They are only suitable for local testing and quick validation. For production, route model API calls through backend services or gateways to avoid exposing sensitive keys on the client side.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3: Install dependencies and launch the project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pnpm dev
&lt;span class="c"&gt;# Or npm install &amp;amp;&amp;amp; npm run dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the local address in browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:5173/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now test the full TinyRobot demo application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpe7maoumespg65fcbb7r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpe7maoumespg65fcbb7r.png" alt=" " width="799" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Suitable Scenarios for &lt;code&gt;create&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;First-time users who want to preview complete features&lt;/li&gt;
&lt;li&gt;Fast demo, prototype or PoC development&lt;/li&gt;
&lt;li&gt;Internal team validation of AI dialogue solutions before production integration&lt;/li&gt;
&lt;li&gt;Building a runnable base project for further customization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Advantage: Clear workflow without worrying about compatibility with legacy systems. Teams can verify interactions, LLM vendors, MCP plugins and business logic before formal integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path 2: Inject Chat Components into Existing Projects with &lt;code&gt;add&lt;/code&gt; Command
&lt;/h2&gt;

&lt;p&gt;If you already maintain an admin system, enterprise workbench or internal portal, rebuilding a separate application just for AI chat is unnecessary — the &lt;code&gt;add&lt;/code&gt; command fits perfectly here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Run the command in your project root
&lt;/h3&gt;

&lt;p&gt;Execute the TinyRobot CLI &lt;code&gt;add&lt;/code&gt; command inside your Vue project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @opentiny/tiny-robot-cli add chat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your project uses a monorepo workspace, the CLI will auto-detect and prompt you to select the target package. For standard single-package projects, injection runs directly in the current directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: File modifications handled automatically by CLI
&lt;/h3&gt;

&lt;p&gt;Based on your selected options, the CLI auto-completes repetitive integration work:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modified File&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/TinyRobotChat.vue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate a ready-to-use TinyRobot chat component&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;main.ts&lt;/code&gt; / &lt;code&gt;main.js&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Auto-import TinyRobot global styles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inject required environment variables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install or upgrade &lt;code&gt;@opentiny/tiny-robot&lt;/code&gt; dependency&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;add&lt;/code&gt; command automates tedious repetitive work: component generation, dependency installation, style importing and environment variable setup.&lt;/p&gt;

&lt;p&gt;This minimizes changes to existing business code. You can mount the chat component on a dedicated page to verify API calls and interactions before deeper integration with business data, permissions and layouts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foi4e3s379ucduh474dvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foi4e3s379ucduh474dvx.png" alt=" " width="661" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Use the component in business pages
&lt;/h3&gt;

&lt;p&gt;After generation, place &lt;code&gt;TinyRobotChat.vue&lt;/code&gt; wherever you want the chat entry to appear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7huzsytbqjeff1kg0ot7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7huzsytbqjeff1kg0ot7.png" alt=" " width="729" height="708"&gt;&lt;/a&gt;&lt;br&gt;
Example usage in &lt;code&gt;src/App.vue&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;HelloWorld&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/HelloWorld.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TinyRobotChat&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./TinyRobotChat.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;HelloWorld&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;TinyRobotChat&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI automatically injects global style imports into &lt;code&gt;main.ts&lt;/code&gt; / &lt;code&gt;main.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/tiny-robot/dist/style.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can move the generated component to drawers, modals, sidebars or specific business pages later, following your project’s component organization standards.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Fill in environment variables
&lt;/h3&gt;

&lt;p&gt;You can preview component styling without API keys, but actual LLM requests require valid keys in &lt;code&gt;.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_DEEPSEEK_API_KEY=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a &lt;code&gt;.env&lt;/code&gt; file already exists, the CLI merges new variables; if not, it creates one automatically.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Important reminder: Client-side environment variables are unsafe for production API keys. Always use backend proxy, authentication and rate limiting for formal deployments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 5: Reinstall dependencies and start dev server
&lt;/h3&gt;

&lt;p&gt;If &lt;code&gt;package.json&lt;/code&gt; has been updated, reinstall dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pnpm dev
&lt;span class="c"&gt;# Or npm install &amp;amp;&amp;amp; npm run dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit &lt;code&gt;http://localhost:5173/&lt;/code&gt; to view the embedded AI chat capability within your existing project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6x5tvbwe6r36m7y70quw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6x5tvbwe6r36m7y70quw.gif" alt=" " width="799" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Suitable Scenarios for &lt;code&gt;add&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Existing admin dashboards, workbenches and portal websites&lt;/li&gt;
&lt;li&gt;Need a lightweight AI chat entry without rebuilding the entire project&lt;/li&gt;
&lt;li&gt;Low-cost pilot validation before deep business integration&lt;/li&gt;
&lt;li&gt;Minimal modification to preserve original project structure&lt;/li&gt;
&lt;li&gt;Verify interaction and API flow before implementing permission, data and knowledge base features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compared to generating a full standalone project, &lt;code&gt;add&lt;/code&gt; acts as a lightweight plug-in entry. It does not build a complete business workflow, but lets you preview AI dialogue components running inside your real production project quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;TinyRobot now provides two simple CLI commands to accelerate AI dialogue integration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;create&lt;/code&gt; to generate a complete standalone project for end-to-end preview of TinyRobot interactions, model configuration and MCP plugin examples.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;add&lt;/code&gt; to incrementally inject chat components into existing Vue projects with minimal disruption to your codebase, enabling fast AI capability validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For teams evaluating AI assistants, intelligent customer service and multi-turn dialogue systems, these two approaches cover two core stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Validate whether TinyRobot meets your requirements&lt;/li&gt;
&lt;li&gt;Integrate dialogue capabilities into formal business projects&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc4s57dh4v63pcihd6jlb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc4s57dh4v63pcihd6jlb.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Roadmap &amp;amp; Community Contribution
&lt;/h2&gt;

&lt;p&gt;TinyRobot will keep expanding AI component sets and interactive capabilities, including layout components, chain-of-thought rendering, full dialogue application components, Skill management &amp;amp; loading, and more.&lt;/p&gt;

&lt;p&gt;If you are building AI assistants, intelligent workbench chat entries, or Vue3-based AI interaction components, feel free to follow and contribute to TinyRobot. Star the repository if you find it useful!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TinyRobot Repository: &lt;a href="https://github.com/opentiny/tiny-robot" rel="noopener noreferrer"&gt;https://github.com/opentiny/tiny-robot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TinyRobot Documentation: &lt;a href="https://docs.opentiny.design/tiny-robot/" rel="noopener noreferrer"&gt;https://docs.opentiny.design/tiny-robot/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenTiny Official Website: &lt;a href="https://opentiny.design/" rel="noopener noreferrer"&gt;https://opentiny.design/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You are welcome to submit feedback via GitHub Issues, including usage confusion, bugs, and feature requests for future iterations. Your input directly shapes our product roadmap.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>GenUI SDK v1.2.0 Released: Smaller Package Size, More Stable Streaming, and a Fully Upgraded Playground!</title>
      <dc:creator>OpenTiny</dc:creator>
      <pubDate>Wed, 17 Jun 2026 08:27:02 +0000</pubDate>
      <link>https://dev.to/opentiny/genui-sdk-v120-released-smaller-package-size-more-stable-streaming-and-a-fully-upgraded-2i9h</link>
      <guid>https://dev.to/opentiny/genui-sdk-v120-released-smaller-package-size-more-stable-streaming-and-a-fully-upgraded-2i9h</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;GenUI SDK is a solution developed by the OpenTiny team based on Generative UI concepts. It is designed to enhance the display and interactive capabilities of large language models (LLMs). The SDK delivers full front-end and back-end integrated capabilities and complies with OpenAI specifications.&lt;/p&gt;

&lt;p&gt;It comes with built-in renderers for both Vue and Angular frameworks, and supports custom components, interactive behaviors and theme styles. You can either build an AI chat application from scratch rapidly, or embed Generative UI capabilities into existing business systems.&lt;/p&gt;

&lt;p&gt;We are thrilled to announce the official release of &lt;strong&gt;GenUI SDK v1.2.0&lt;/strong&gt;. This update focuses on four major optimization directions: SDK lightweighting &amp;amp; on-demand importing, improved streaming rendering stability, comprehensive Playground upgrades, and enhanced GenUI Template experience. The SDK now runs lighter, performs more stably and is easier to configure in production environments.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Source Repository: &lt;a href="https://github.com/opentiny/genui-sdk" rel="noopener noreferrer"&gt;github.com/opentiny/genui-sdk&lt;/a&gt; (Star ⭐ appreciated!)&lt;/li&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design/genui-sdk" rel="noopener noreferrer"&gt;opentiny.design/genui-sdk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Version Feature Overview
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SDK Build Optimization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;On-demand importing: &lt;code&gt;@opentiny/genui-sdk-vue&lt;/code&gt; is split into multiple entry points for separate component exports, enabling on-demand importing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  More Stable Streaming Rendering
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A new &lt;code&gt;isJsonComplete&lt;/code&gt; flag is added to the renderer component to optimize buffering for object-type content.&lt;/li&gt;
&lt;li&gt;Enhanced SSE compatibility to support more streaming response formats.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fully Upgraded Playground
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skill Packages&lt;/strong&gt;: Support importing SKILL folders with progressive disclosure capability.&lt;/li&gt;
&lt;li&gt;Added A2A (Agent-to-Agent) collaborative capabilities for agents.&lt;/li&gt;
&lt;li&gt;Split thinking modes: Models like DeepSeek v4 now support thinking and non-thinking modes.&lt;/li&gt;
&lt;li&gt;Import &amp;amp; export for chat and template history records.&lt;/li&gt;
&lt;li&gt;Streaming update support for template JSON Patch.&lt;/li&gt;
&lt;li&gt;Mobile UI optimization and dark mode adaptation for templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other Updates
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enforced strict JSON output specifications to reduce parsing failures at the prompt level.&lt;/li&gt;
&lt;li&gt;Fixed scope issues for loop child nodes and optimized rendering error capture &amp;amp; recovery.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Detailed New Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. On-demand Import &amp;amp; SDK Package Size Reduction
&lt;/h3&gt;

&lt;p&gt;Previously, &lt;code&gt;@opentiny/genui-sdk-vue&lt;/code&gt; was released as a single full package. Even if your project only used the renderer module, modules such as Chat and ConfigProvider would be bundled into the final product under poor tree-shaking configurations, resulting in redundant package bloat.&lt;/p&gt;

&lt;p&gt;v1.2.0 supports subpath package exports, allowing you to import entries based on actual scenarios:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Subpath&lt;/th&gt;
&lt;th&gt;Applicable Scenario&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/genui-sdk-vue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default entry for combined use of Chat, Renderer and ConfigProvider&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/genui-sdk-vue/chat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;For chat components only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/genui-sdk-vue/renderer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;For renderer only (custom-built chat UI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/genui-sdk-vue/config-provider&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;For theme and internationalization configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@opentiny/genui-sdk-vue/transform-jsx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;For JSX transformation capabilities&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you only use &lt;code&gt;GenuiRenderer&lt;/code&gt; to build a custom chat UI, simply import the dedicated renderer subpackage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GenuiRenderer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@opentiny/genui-sdk-vue/renderer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Besides SDK subpackaging, built-in OpenTiny components are now imported at the subpackage level. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fskm9uqy730btm7cjsc28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fskm9uqy730btm7cjsc28.png" alt=" " width="800" height="187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Only components used by GenUI will be packaged, instead of importing the full &lt;code&gt;@opentiny/vue&lt;/code&gt; library. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcglb3cc2njshrg3195kr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcglb3cc2njshrg3195kr.png" alt=" " width="630" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Components like &lt;code&gt;@opentiny/vue-button&lt;/code&gt;, &lt;code&gt;@opentiny/vue-grid&lt;/code&gt; and &lt;code&gt;@opentiny/vue-chart-*&lt;/code&gt; are imported on demand to eliminate unnecessary dependencies.&lt;/p&gt;

&lt;h4&gt;
  
  
  Package Size Comparison
&lt;/h4&gt;

&lt;p&gt;Test environment: Only &lt;code&gt;GenuiRenderer&lt;/code&gt; (&lt;code&gt;@opentiny/genui-sdk-vue/renderer&lt;/code&gt;) imported, built via Vite + Rollup in production mode.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before Optimization&lt;/th&gt;
&lt;th&gt;After Optimization&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Total Bundle Size&lt;/td&gt;
&lt;td&gt;14.67 MB&lt;/td&gt;
&lt;td&gt;8.02 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;@opentiny/genui-sdk-vue&lt;/code&gt; Occupied Size&lt;/td&gt;
&lt;td&gt;~3.04 MB (20.72%)&lt;/td&gt;
&lt;td&gt;~506 KB (6.64%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDK Package Reduction (Renderer Scenario)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;~83%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Before optimization:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44q0y5ijbl4gqk2y8x07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44q0y5ijbl4gqk2y8x07.png" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmu5o13vgajt01li4bz4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmu5o13vgajt01li4bz4z.png" alt=" " width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After optimization:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr06ae178gorfeghr3qcy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr06ae178gorfeghr3qcy.png" alt=" " width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lzjqi2782axrnqrqyg7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lzjqi2782axrnqrqyg7.png" alt=" " width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Import &amp;amp; Export of Chat History
&lt;/h3&gt;

&lt;p&gt;Both chat history and template history in Playground support import and export in JSON format, facilitating context backup, debugging and cross-environment issue reproduction. Multiple records can be selected for batch export or deletion.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Export file naming rule: &lt;code&gt;genui-history-YYYY-MM-DD-HH-mm-ss.json&lt;/code&gt; (The same naming rule applies to template history with distinguishable prefixes)&lt;/li&gt;
&lt;li&gt;File structure: An array of conversation objects, each containing fields such as &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;messages&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Import Validation &amp;amp; Conflict Resolution
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Clear error prompts for invalid JSON files or files missing the &lt;code&gt;messages&lt;/code&gt; array.&lt;/li&gt;
&lt;li&gt;Automatic new ID assignment via &lt;code&gt;reconcileImportedConversationIds&lt;/code&gt; for conflicting conversation IDs to avoid overwriting local records.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;GenuiTemplateList&lt;/code&gt; reuses the same history toolbar, delivering a consistent import &amp;amp; export experience for chats and templates.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conversation Exporting
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwprry6ux6s5wytk4jay.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwprry6ux6s5wytk4jay.gif" alt=" " width="560" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Session Importing
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonylgehn09eh2u0tl6wa.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonylgehn09eh2u0tl6wa.gif" alt=" " width="720" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Playground Skill Package Support
&lt;/h3&gt;

&lt;p&gt;Skill Package is a major upgrade for Agent capabilities in Playground:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single-file Skill&lt;/strong&gt;: For quick testing, write Skill content directly in a single file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Folder Import&lt;/strong&gt;: Import complete SKILL directories containing &lt;code&gt;SKILL.md&lt;/code&gt; and affiliated modules. You can view and edit all files via the tree panel after import.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progressive Disclosure&lt;/strong&gt;: Only skill names and descriptions are injected into system prompts. When the model needs a specific skill, it calls the &lt;code&gt;get_skill_content&lt;/code&gt; tool to fetch full content or sub-documents on demand, preventing excessive consumption of context window space.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas7wjlpkf4jajde9z7uv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas7wjlpkf4jajde9z7uv.gif" alt=" " width="479" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Demo reference: Vue Best Practices Skill → &lt;a href="https://github.com/antfu/skills/tree/main/skills/vue-best-practices" rel="noopener noreferrer"&gt;https://github.com/antfu/skills/tree/main/skills/vue-best-practices&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Playground A2A Agent Collaboration
&lt;/h3&gt;

&lt;p&gt;v1.2.0 implements &lt;strong&gt;A2A (Agent-to-Agent)&lt;/strong&gt; capabilities on the Playground server. External AI agents can be registered as tools, working alongside MCP Tools and Skill Tools within a single conversation.&lt;/p&gt;

&lt;p&gt;Playground has evolved from a single-model mode to a multi-agent architecture: the main Agent orchestrates tasks, while domain-specific Agents execute them. You can integrate existing vertical agents (customer service, data analysis, code review, etc.) without rebuilding the chat UI layer.&lt;/p&gt;

&lt;p&gt;The current implementation is based on A2A Protocol v0.3.0, supporting the full workflow: &lt;em&gt;Main Agent Orchestration → Domain Agent Execution → Result Writeback via Schema&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The official stable A2A Protocol v1.0.0 has been released. We are working on adaptation (Agent Card parsing, calling conventions, error handling, etc.) and plan to complete the upgrade in the next version for better interoperability with the A2A ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr1au0fypnszrb07djt6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr1au0fypnszrb07djt6.png" alt=" " width="546" height="763"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Thinking &amp;amp; Non-Thinking Modes for Models
&lt;/h3&gt;

&lt;p&gt;The system automatically detects models supporting the &lt;code&gt;enable_thinking&lt;/code&gt; parameter (e.g. DeepSeek-V4-Flash/Pro) and splits them into two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;{modelName}&lt;/code&gt;: No-Thinking Mode (&lt;code&gt;thinking: { type: 'disabled' }&lt;/code&gt;) for faster responses.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{modelName}-thinking&lt;/code&gt;: Thinking Mode (&lt;code&gt;thinking: { type: 'enabled' }&lt;/code&gt;) for in-depth reasoning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can select modes based on scenarios: use No-Thinking for simple UI generation to pursue speed, and Thinking Mode for complex interactive logic to guarantee quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Template Experience Optimization
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Mobile &amp;amp; Dark Mode Adaptation
&lt;/h4&gt;

&lt;p&gt;Comprehensive style optimization for GenUI Template on mobile devices, plus full adaptation for dark mode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8hljz9bxhcl4wnnwadu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8hljz9bxhcl4wnnwadu.png" alt=" " width="571" height="1236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filwzk281x8vzeoybpmt5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filwzk281x8vzeoybpmt5.png" alt=" " width="430" height="884"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Optimized Prompt &amp;amp; JSON Patch
&lt;/h4&gt;

&lt;p&gt;Built a complete JSON Patch Zod Schema based on RFC 6902, making diff results returned by LLMs more accurate and stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Notable Fixes &amp;amp; Improvements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  New &lt;code&gt;isJsonComplete&lt;/code&gt; Field for Renderer
&lt;/h3&gt;

&lt;p&gt;Previously, incomplete object data (e.g. unfinished function bodies or style properties) would trigger rendering truncation errors. The newly added &lt;code&gt;isJsonComplete&lt;/code&gt; flag allows developers to explicitly mark whether the JSON schema is complete. Combined with &lt;code&gt;requiredCompleteFieldSelectors&lt;/code&gt; (buffer fields), you can specify mandatory fields that must be fully loaded before rendering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Strict JSON Output Rules
&lt;/h3&gt;

&lt;p&gt;Prompts now enforce standard JSON format requirements: double quotes only, no trailing commas, no comments and no single quotes. This effectively reduces parsing failures caused by non-standard JSON outputs from LLMs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loop Child Node Scope Fix
&lt;/h3&gt;

&lt;p&gt;Resolved the issue where loop child nodes could not access scope variables such as &lt;code&gt;item&lt;/code&gt; and &lt;code&gt;index&lt;/code&gt;. Variables now work normally in loop rendering scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enhanced SSE Compatibility
&lt;/h3&gt;

&lt;p&gt;Added support for non-standard SSE streams where no space follows the &lt;code&gt;data:&lt;/code&gt; prefix (e.g. &lt;code&gt;data:{"content":"..."}&lt;/code&gt;). More third-party streaming interfaces can now be connected smoothly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;GenUI SDK v1.2.0 delivers a lighter package size, more reliable streaming rendering, more powerful Playground functions and a polished template experience.&lt;/p&gt;

&lt;p&gt;Feel free to upgrade and experience the new version. If you encounter edge cases or have optimization suggestions, submit feedback via GitHub Issues. Star and contributions are always welcome!&lt;/p&gt;

&lt;p&gt;Full changelog: &lt;a href="https://github.com/opentiny/genui-sdk/releases" rel="noopener noreferrer"&gt;github.com/opentiny/genui-sdk/releases&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About OpenTiny NEXT
&lt;/h2&gt;

&lt;p&gt;OpenTiny NEXT is an enterprise-grade intelligent front-end development solution built around Generative UI and WebMCP. It intelligently upgrades traditional products including TinyVue component library and TinyEngine low-code engine, and launches new products for Agent applications such as NEXT-SDKs for front-end, AI Extension, TinyRobot AI assistant and GenUI.&lt;/p&gt;

&lt;p&gt;Our goal is to enable AI to understand user intentions and complete tasks autonomously, accelerating the intelligent transformation of enterprise applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the OpenTiny Community
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WeChat Assistant: opentiny-official&lt;/li&gt;
&lt;li&gt;Official Website: &lt;a href="https://opentiny.design" rel="noopener noreferrer"&gt;opentiny.design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Open Source Repository: &lt;a href="https://github.com/opentiny/genui-sdk" rel="noopener noreferrer"&gt;github.com/opentiny/genui-sdk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to contribute to open source, look for issues tagged with &lt;code&gt;good first issue&lt;/code&gt; in the repository to get started!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
