@seed-ship/mcp-ui-solid 6.19.0 → 6.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/CHANGELOG.md +532 -0
  2. package/README.md +798 -1
  3. package/dist/adapters/connector.cjs +15 -4
  4. package/dist/adapters/connector.cjs.map +1 -1
  5. package/dist/adapters/connector.d.ts +38 -0
  6. package/dist/adapters/connector.d.ts.map +1 -1
  7. package/dist/adapters/connector.js +15 -4
  8. package/dist/adapters/connector.js.map +1 -1
  9. package/dist/adapters/index.d.ts +4 -3
  10. package/dist/adapters/index.d.ts.map +1 -1
  11. package/dist/adapters/macro-run.cjs +25 -13
  12. package/dist/adapters/macro-run.cjs.map +1 -1
  13. package/dist/adapters/macro-run.d.ts +37 -2
  14. package/dist/adapters/macro-run.d.ts.map +1 -1
  15. package/dist/adapters/macro-run.js +25 -13
  16. package/dist/adapters/macro-run.js.map +1 -1
  17. package/dist/adapters.cjs +2 -0
  18. package/dist/adapters.cjs.map +1 -1
  19. package/dist/adapters.js +4 -2
  20. package/dist/components/ActionGroupRenderer.cjs +3 -1
  21. package/dist/components/ActionGroupRenderer.cjs.map +1 -1
  22. package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
  23. package/dist/components/ActionGroupRenderer.js +3 -1
  24. package/dist/components/ActionGroupRenderer.js.map +1 -1
  25. package/dist/components/AgentCard.cjs +11 -8
  26. package/dist/components/AgentCard.cjs.map +1 -1
  27. package/dist/components/AgentCard.d.ts.map +1 -1
  28. package/dist/components/AgentCard.js +11 -8
  29. package/dist/components/AgentCard.js.map +1 -1
  30. package/dist/components/AgentHandoff.cjs +6 -1
  31. package/dist/components/AgentHandoff.cjs.map +1 -1
  32. package/dist/components/AgentHandoff.d.ts.map +1 -1
  33. package/dist/components/AgentHandoff.js +6 -1
  34. package/dist/components/AgentHandoff.js.map +1 -1
  35. package/dist/components/ArtifactRenderer.cjs +25 -6
  36. package/dist/components/ArtifactRenderer.cjs.map +1 -1
  37. package/dist/components/ArtifactRenderer.d.ts.map +1 -1
  38. package/dist/components/ArtifactRenderer.js +25 -6
  39. package/dist/components/ArtifactRenderer.js.map +1 -1
  40. package/dist/components/AutocompleteDropdown.cjs +30 -24
  41. package/dist/components/AutocompleteDropdown.cjs.map +1 -1
  42. package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
  43. package/dist/components/AutocompleteDropdown.js +30 -24
  44. package/dist/components/AutocompleteDropdown.js.map +1 -1
  45. package/dist/components/AutocompleteFormField.cjs +3 -1
  46. package/dist/components/AutocompleteFormField.cjs.map +1 -1
  47. package/dist/components/AutocompleteFormField.d.ts.map +1 -1
  48. package/dist/components/AutocompleteFormField.js +4 -2
  49. package/dist/components/AutocompleteFormField.js.map +1 -1
  50. package/dist/components/BriefingDiff.cjs +45 -39
  51. package/dist/components/BriefingDiff.cjs.map +1 -1
  52. package/dist/components/BriefingDiff.d.ts.map +1 -1
  53. package/dist/components/BriefingDiff.js +45 -39
  54. package/dist/components/BriefingDiff.js.map +1 -1
  55. package/dist/components/CarouselRenderer.cjs +8 -2
  56. package/dist/components/CarouselRenderer.cjs.map +1 -1
  57. package/dist/components/CarouselRenderer.d.ts.map +1 -1
  58. package/dist/components/CarouselRenderer.js +8 -2
  59. package/dist/components/CarouselRenderer.js.map +1 -1
  60. package/dist/components/ChartJSRenderer.cjs +60 -36
  61. package/dist/components/ChartJSRenderer.cjs.map +1 -1
  62. package/dist/components/ChartJSRenderer.d.ts.map +1 -1
  63. package/dist/components/ChartJSRenderer.js +61 -37
  64. package/dist/components/ChartJSRenderer.js.map +1 -1
  65. package/dist/components/ChatPrompt.cjs +15 -9
  66. package/dist/components/ChatPrompt.cjs.map +1 -1
  67. package/dist/components/ChatPrompt.d.ts.map +1 -1
  68. package/dist/components/ChatPrompt.js +15 -9
  69. package/dist/components/ChatPrompt.js.map +1 -1
  70. package/dist/components/CodeBlockRenderer.cjs +34 -16
  71. package/dist/components/CodeBlockRenderer.cjs.map +1 -1
  72. package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
  73. package/dist/components/CodeBlockRenderer.js +34 -16
  74. package/dist/components/CodeBlockRenderer.js.map +1 -1
  75. package/dist/components/DataPreviewSection.cjs +91 -44
  76. package/dist/components/DataPreviewSection.cjs.map +1 -1
  77. package/dist/components/DataPreviewSection.d.ts.map +1 -1
  78. package/dist/components/DataPreviewSection.js +92 -45
  79. package/dist/components/DataPreviewSection.js.map +1 -1
  80. package/dist/components/DegradedFallback.cjs +20 -16
  81. package/dist/components/DegradedFallback.cjs.map +1 -1
  82. package/dist/components/DegradedFallback.d.ts.map +1 -1
  83. package/dist/components/DegradedFallback.js +20 -16
  84. package/dist/components/DegradedFallback.js.map +1 -1
  85. package/dist/components/FeedbackInline.cjs +19 -3
  86. package/dist/components/FeedbackInline.cjs.map +1 -1
  87. package/dist/components/FeedbackInline.js +19 -3
  88. package/dist/components/FeedbackInline.js.map +1 -1
  89. package/dist/components/FooterRenderer.cjs +21 -17
  90. package/dist/components/FooterRenderer.cjs.map +1 -1
  91. package/dist/components/FooterRenderer.d.ts.map +1 -1
  92. package/dist/components/FooterRenderer.js +21 -17
  93. package/dist/components/FooterRenderer.js.map +1 -1
  94. package/dist/components/FormFieldRenderer.cjs +116 -93
  95. package/dist/components/FormFieldRenderer.cjs.map +1 -1
  96. package/dist/components/FormFieldRenderer.d.ts.map +1 -1
  97. package/dist/components/FormFieldRenderer.js +116 -93
  98. package/dist/components/FormFieldRenderer.js.map +1 -1
  99. package/dist/components/FormRenderer.cjs +55 -31
  100. package/dist/components/FormRenderer.cjs.map +1 -1
  101. package/dist/components/FormRenderer.d.ts.map +1 -1
  102. package/dist/components/FormRenderer.js +55 -31
  103. package/dist/components/FormRenderer.js.map +1 -1
  104. package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
  105. package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
  106. package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
  107. package/dist/components/GenerativeUIErrorBoundary.js +20 -15
  108. package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
  109. package/dist/components/GraphRenderer.cjs +56 -33
  110. package/dist/components/GraphRenderer.cjs.map +1 -1
  111. package/dist/components/GraphRenderer.d.ts.map +1 -1
  112. package/dist/components/GraphRenderer.js +56 -33
  113. package/dist/components/GraphRenderer.js.map +1 -1
  114. package/dist/components/ImageGalleryRenderer.cjs +13 -4
  115. package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
  116. package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
  117. package/dist/components/ImageGalleryRenderer.js +13 -4
  118. package/dist/components/ImageGalleryRenderer.js.map +1 -1
  119. package/dist/components/LightboxOverlay.cjs +16 -8
  120. package/dist/components/LightboxOverlay.cjs.map +1 -1
  121. package/dist/components/LightboxOverlay.d.ts.map +1 -1
  122. package/dist/components/LightboxOverlay.js +17 -9
  123. package/dist/components/LightboxOverlay.js.map +1 -1
  124. package/dist/components/MapRenderer.cjs +59 -29
  125. package/dist/components/MapRenderer.cjs.map +1 -1
  126. package/dist/components/MapRenderer.d.ts +10 -2
  127. package/dist/components/MapRenderer.d.ts.map +1 -1
  128. package/dist/components/MapRenderer.js +60 -30
  129. package/dist/components/MapRenderer.js.map +1 -1
  130. package/dist/components/ModalRenderer.cjs +4 -1
  131. package/dist/components/ModalRenderer.cjs.map +1 -1
  132. package/dist/components/ModalRenderer.d.ts.map +1 -1
  133. package/dist/components/ModalRenderer.js +5 -2
  134. package/dist/components/ModalRenderer.js.map +1 -1
  135. package/dist/components/ScratchpadPanel.cjs +578 -535
  136. package/dist/components/ScratchpadPanel.cjs.map +1 -1
  137. package/dist/components/ScratchpadPanel.d.ts.map +1 -1
  138. package/dist/components/ScratchpadPanel.js +578 -535
  139. package/dist/components/ScratchpadPanel.js.map +1 -1
  140. package/dist/components/StreamingUIRenderer.cjs +92 -28
  141. package/dist/components/StreamingUIRenderer.cjs.map +1 -1
  142. package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
  143. package/dist/components/StreamingUIRenderer.js +92 -28
  144. package/dist/components/StreamingUIRenderer.js.map +1 -1
  145. package/dist/components/UIResourceRenderer.cjs +456 -363
  146. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  147. package/dist/components/UIResourceRenderer.d.ts +21 -0
  148. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  149. package/dist/components/UIResourceRenderer.js +458 -365
  150. package/dist/components/UIResourceRenderer.js.map +1 -1
  151. package/dist/components/VerifiedText.cjs +39 -20
  152. package/dist/components/VerifiedText.cjs.map +1 -1
  153. package/dist/components/VerifiedText.d.ts +2 -1
  154. package/dist/components/VerifiedText.d.ts.map +1 -1
  155. package/dist/components/VerifiedText.js +39 -20
  156. package/dist/components/VerifiedText.js.map +1 -1
  157. package/dist/components/VideoRenderer.cjs +10 -5
  158. package/dist/components/VideoRenderer.cjs.map +1 -1
  159. package/dist/components/VideoRenderer.d.ts.map +1 -1
  160. package/dist/components/VideoRenderer.js +10 -5
  161. package/dist/components/VideoRenderer.js.map +1 -1
  162. package/dist/components/chart-data-table.cjs +38 -17
  163. package/dist/components/chart-data-table.cjs.map +1 -1
  164. package/dist/components/chart-data-table.d.ts +30 -1
  165. package/dist/components/chart-data-table.d.ts.map +1 -1
  166. package/dist/components/chart-data-table.js +38 -17
  167. package/dist/components/chart-data-table.js.map +1 -1
  168. package/dist/context/MCPActionContext.cjs +3 -1
  169. package/dist/context/MCPActionContext.cjs.map +1 -1
  170. package/dist/context/MCPActionContext.d.ts.map +1 -1
  171. package/dist/context/MCPActionContext.js +3 -1
  172. package/dist/context/MCPActionContext.js.map +1 -1
  173. package/dist/context/MCPUIStringsContext.cjs +285 -2
  174. package/dist/context/MCPUIStringsContext.cjs.map +1 -1
  175. package/dist/context/MCPUIStringsContext.d.ts +600 -3
  176. package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
  177. package/dist/context/MCPUIStringsContext.js +285 -2
  178. package/dist/context/MCPUIStringsContext.js.map +1 -1
  179. package/dist/hooks/index.d.ts +2 -2
  180. package/dist/hooks/index.d.ts.map +1 -1
  181. package/dist/hooks/useStreamingUI.cjs +28 -10
  182. package/dist/hooks/useStreamingUI.cjs.map +1 -1
  183. package/dist/hooks/useStreamingUI.d.ts +37 -0
  184. package/dist/hooks/useStreamingUI.d.ts.map +1 -1
  185. package/dist/hooks/useStreamingUI.js +28 -10
  186. package/dist/hooks/useStreamingUI.js.map +1 -1
  187. package/dist/hooks.cjs +1 -0
  188. package/dist/hooks.cjs.map +1 -1
  189. package/dist/hooks.js +2 -1
  190. package/dist/index.cjs +23 -8
  191. package/dist/index.cjs.map +1 -1
  192. package/dist/index.d.cts +9 -3
  193. package/dist/index.d.ts +9 -3
  194. package/dist/index.d.ts.map +1 -1
  195. package/dist/index.js +18 -3
  196. package/dist/index.js.map +1 -1
  197. package/dist/services/validation.cjs +41 -16
  198. package/dist/services/validation.cjs.map +1 -1
  199. package/dist/services/validation.d.ts +47 -2
  200. package/dist/services/validation.d.ts.map +1 -1
  201. package/dist/services/validation.js +41 -16
  202. package/dist/services/validation.js.map +1 -1
  203. package/dist/utils/degraded-projections.cjs +37 -12
  204. package/dist/utils/degraded-projections.cjs.map +1 -1
  205. package/dist/utils/degraded-projections.d.ts +39 -3
  206. package/dist/utils/degraded-projections.d.ts.map +1 -1
  207. package/dist/utils/degraded-projections.js +37 -12
  208. package/dist/utils/degraded-projections.js.map +1 -1
  209. package/dist/utils/format-string.cjs +10 -0
  210. package/dist/utils/format-string.cjs.map +1 -0
  211. package/dist/utils/format-string.d.ts +26 -0
  212. package/dist/utils/format-string.d.ts.map +1 -0
  213. package/dist/utils/format-string.js +10 -0
  214. package/dist/utils/format-string.js.map +1 -0
  215. package/dist/validation.cjs +3 -0
  216. package/dist/validation.cjs.map +1 -1
  217. package/dist/validation.d.cts +2 -1
  218. package/dist/validation.d.ts +2 -1
  219. package/dist/validation.d.ts.map +1 -1
  220. package/dist/validation.js +4 -1
  221. package/package.json +1 -1
  222. package/src/adapters/connector.ts +58 -4
  223. package/src/adapters/index.ts +12 -2
  224. package/src/adapters/macro-run.ts +71 -11
  225. package/src/components/ActionGroupRenderer.tsx +3 -1
  226. package/src/components/AgentCard.tsx +27 -9
  227. package/src/components/AgentHandoff.tsx +4 -1
  228. package/src/components/ArtifactRenderer.tsx +17 -5
  229. package/src/components/AutocompleteDropdown.tsx +8 -6
  230. package/src/components/AutocompleteFormField.tsx +5 -1
  231. package/src/components/BriefingDiff.tsx +11 -3
  232. package/src/components/CarouselRenderer.tsx +4 -2
  233. package/src/components/ChartJSRenderer.tsx +18 -9
  234. package/src/components/ChatPrompt.tsx +13 -8
  235. package/src/components/CodeBlockRenderer.tsx +12 -10
  236. package/src/components/DataPreviewSection.tsx +92 -26
  237. package/src/components/DegradedFallback.tsx +4 -2
  238. package/src/components/FeedbackInline.tsx +2 -2
  239. package/src/components/FooterRenderer.tsx +3 -1
  240. package/src/components/FormFieldRenderer.tsx +34 -19
  241. package/src/components/FormRenderer.tsx +38 -10
  242. package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
  243. package/src/components/GraphRenderer.tsx +31 -16
  244. package/src/components/ImageGalleryRenderer.tsx +8 -4
  245. package/src/components/LightboxOverlay.tsx +6 -4
  246. package/src/components/MapRenderer.tsx +57 -20
  247. package/src/components/ModalRenderer.tsx +3 -1
  248. package/src/components/ScratchpadPanel.tsx +95 -44
  249. package/src/components/StreamingUIRenderer.tsx +41 -11
  250. package/src/components/UIResourceRenderer.tsx +145 -63
  251. package/src/components/VerifiedText.tsx +19 -9
  252. package/src/components/VideoRenderer.tsx +6 -4
  253. package/src/components/chart-data-table.ts +68 -14
  254. package/src/context/MCPActionContext.tsx +4 -1
  255. package/src/context/MCPUIStringsContext.tsx +1004 -1
  256. package/src/hooks/index.ts +2 -1
  257. package/src/hooks/useStreamingUI.ts +64 -10
  258. package/src/index.ts +23 -0
  259. package/src/services/validation.ts +93 -16
  260. package/src/utils/degraded-projections.ts +75 -12
  261. package/src/utils/format-string.ts +33 -0
  262. package/src/validation.ts +5 -0
@@ -6,12 +6,14 @@
6
6
  *
7
7
  * Modes:
8
8
  * - highlight: ✅/⚠️ badges next to numbers (default)
9
- * - strip: replaces hallucinated numbers with [non vérifié]
9
+ * - strip: replaces hallucinated numbers with the `verifiedStripLabel`
10
+ * chrome string ('[unverified]' by default)
10
11
  * - annotate: tooltip on hover with closest source number
11
12
  */
12
13
 
13
14
  import { createMemo, For } from 'solid-js'
14
15
  import type { DataValidation, HallucinatedNumber } from '../types/chat-bus'
16
+ import { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'
15
17
 
16
18
  export interface VerifiedTextProps {
17
19
  text: string
@@ -94,6 +96,7 @@ function buildAnnotatedSegments(text: string, validation: DataValidation): TextS
94
96
  }
95
97
 
96
98
  export function VerifiedText(props: VerifiedTextProps) {
99
+ const strings = useMCPUIStrings()
97
100
  const mode = () => props.mode || 'highlight'
98
101
 
99
102
  const segments = createMemo<TextSegment[]>(() => {
@@ -115,10 +118,10 @@ export function VerifiedText(props: VerifiedTextProps) {
115
118
  return (
116
119
  <span
117
120
  class="inline-flex items-center gap-0.5 px-0.5 rounded bg-green-50 dark:bg-green-900/20 text-green-800 dark:text-green-300"
118
- title="Verified against source data"
121
+ title={strings.verifiedTitle}
119
122
  >
120
123
  {seg.content}
121
- <span class="text-xs opacity-70" aria-label="verified">&#x2705;</span>
124
+ <span class="text-xs opacity-70" aria-label={strings.verifiedAria}>&#x2705;</span>
122
125
  </span>
123
126
  )
124
127
  }
@@ -127,9 +130,12 @@ export function VerifiedText(props: VerifiedTextProps) {
127
130
  const h = seg.item!
128
131
  const tooltipText = () => {
129
132
  if (h.closest != null && h.distance != null) {
130
- return `Not found in source data. Closest: ${h.closest} (${Math.round(h.distance * 100)}% off)`
133
+ return formatMCPUIString(strings.verifiedNotFoundClosest, {
134
+ closest: h.closest,
135
+ pct: Math.round(h.distance * 100),
136
+ })
131
137
  }
132
- return 'Not found in source data'
138
+ return strings.verifiedNotFound
133
139
  }
134
140
 
135
141
  if (mode() === 'strip') {
@@ -138,7 +144,7 @@ export function VerifiedText(props: VerifiedTextProps) {
138
144
  class="inline-flex items-center px-1 rounded bg-amber-50 dark:bg-amber-900/20 text-amber-700 dark:text-amber-300 italic text-xs"
139
145
  title={tooltipText()}
140
146
  >
141
- [non v&eacute;rifi&eacute;]
147
+ {strings.verifiedStripLabel}
142
148
  </span>
143
149
  )
144
150
  }
@@ -151,7 +157,7 @@ export function VerifiedText(props: VerifiedTextProps) {
151
157
  role={props.onHallucinationClick ? 'button' : undefined}
152
158
  >
153
159
  {seg.content}
154
- <span class="text-xs" aria-label="unverified">&#x26A0;&#xFE0F;</span>
160
+ <span class="text-xs" aria-label={strings.unverifiedAria}>&#x26A0;&#xFE0F;</span>
155
161
  </span>
156
162
  )
157
163
  }}
@@ -172,8 +178,12 @@ export function VerifiedText(props: VerifiedTextProps) {
172
178
  />
173
179
  </div>
174
180
  <span>
175
- {Math.round(props.validation.confidence * 100)}% verified
176
- ({props.validation.hallucinated.length} unverified)
181
+ {formatMCPUIString(strings.verifiedConfidence, {
182
+ pct: Math.round(props.validation.confidence * 100),
183
+ })}{' '}
184
+ {formatMCPUIString(strings.verifiedUnverifiedCount, {
185
+ count: props.validation.hallucinated.length,
186
+ })}
177
187
  </span>
178
188
  </div>
179
189
  )}
@@ -8,6 +8,7 @@
8
8
  import { Component, createMemo, Show } from 'solid-js'
9
9
  import type { UIComponent, VideoComponentParams } from '../types'
10
10
  import { ExpandableWrapper, useExpanded } from './ExpandableWrapper'
11
+ import { useMCPUIStrings } from '../context/MCPUIStringsContext'
11
12
 
12
13
  export interface VideoRendererProps {
13
14
  /**
@@ -74,6 +75,7 @@ function parseVideoUrl(url: string): VideoInfo {
74
75
  }
75
76
 
76
77
  export const VideoRenderer: Component<VideoRendererProps> = (props) => {
78
+ const strings = useMCPUIStrings()
77
79
  const params = () => props.params || (props.component?.params as VideoComponentParams)
78
80
  const isExpanded = useExpanded()
79
81
 
@@ -135,9 +137,9 @@ export const VideoRenderer: Component<VideoRendererProps> = (props) => {
135
137
 
136
138
  return (
137
139
  <ExpandableWrapper
138
- title={params()?.title || 'Video'}
140
+ title={params()?.title || strings.videoTitle}
139
141
  copyData={params()?.url || ''}
140
- copyLabel="Copy video URL"
142
+ copyLabel={strings.videoCopy}
141
143
  toolbarVariant={props.toolbarVariant}
142
144
  >
143
145
  <div class={`w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${
@@ -168,14 +170,14 @@ export const VideoRenderer: Component<VideoRendererProps> = (props) => {
168
170
  onError={handleVideoError}
169
171
  >
170
172
  <track kind="captions" />
171
- Your browser does not support the video tag.
173
+ {strings.videoUnsupported}
172
174
  </video>
173
175
  }
174
176
  >
175
177
  {/* YouTube/Vimeo embed */}
176
178
  <iframe
177
179
  src={embedUrl()!}
178
- title={params()?.title || 'Video'}
180
+ title={params()?.title || strings.videoTitle}
179
181
  class="absolute inset-0 w-full h-full"
180
182
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
181
183
  allowfullscreen
@@ -1,3 +1,44 @@
1
+ import { formatMCPUIString } from '../utils/format-string';
2
+
3
+ /**
4
+ * Column headers and series names of the accessible chart data table.
5
+ *
6
+ * `chartToDataTable` is a pure helper with no access to `MCPUIStrings`, so
7
+ * the wording is injected: it takes an optional trailing `labels` partial,
8
+ * which `ChartJSRenderer` feeds from `useMCPUIStrings()`. Left out, the
9
+ * English defaults below apply — the pre-v6.20.0 behaviour.
10
+ *
11
+ * `x` / `y` / `r` stay untranslated on purpose: they are the Chart.js point
12
+ * property NAMES the cells mirror, not prose.
13
+ *
14
+ * @since v6.20.0
15
+ */
16
+ export interface ChartDataTableLabels {
17
+ /** Series column of the per-point table. */
18
+ series: string;
19
+ /** Point-index column of the per-point table. */
20
+ point: string;
21
+ /** Label column (categorical table, and per-point table when labelled). */
22
+ label: string;
23
+ /** Fallback dataset name. Template — `{n}`. */
24
+ seriesName: string;
25
+ /** Chart.js point property names — machine tokens, rarely overridden. */
26
+ x: string;
27
+ y: string;
28
+ r: string;
29
+ }
30
+
31
+ /** English defaults for {@link ChartDataTableLabels}. */
32
+ export const CHART_DATA_TABLE_LABELS: ChartDataTableLabels = {
33
+ series: 'Series',
34
+ point: 'Point',
35
+ label: 'Label',
36
+ seriesName: 'Series {n}',
37
+ x: 'x',
38
+ y: 'y',
39
+ r: 'r',
40
+ };
41
+
1
42
  export interface ChartDataTable {
2
43
  columns: string[];
3
44
  rows: Array<Array<string | number>>;
@@ -41,37 +82,41 @@ function isPoint(value: unknown): value is Record<string, unknown> {
41
82
  * coordinates. Categorical charts use a compact wide table; scatter, bubble,
42
83
  * and object-valued line charts use one row per point so x/y/r remain distinct.
43
84
  */
44
- export function chartToDataTable(params: ChartDataLike): ChartDataTable {
85
+ export function chartToDataTable(
86
+ params: ChartDataLike,
87
+ labels?: Partial<ChartDataTableLabels>
88
+ ): ChartDataTable {
89
+ const l: ChartDataTableLabels = { ...CHART_DATA_TABLE_LABELS, ...labels };
45
90
  const datasets = params.data?.datasets ?? [];
46
- const labels = params.data?.labels ?? [];
91
+ const dataLabels = params.data?.labels ?? [];
47
92
  const pointData =
48
93
  params.type === 'scatter' ||
49
94
  params.type === 'bubble' ||
50
95
  datasets.some((dataset) => dataset.data?.some(isPoint));
51
96
 
52
97
  if (pointData) {
53
- const hasLabels = labels.length > 0;
98
+ const hasLabels = dataLabels.length > 0;
54
99
  const hasRadius =
55
100
  params.type === 'bubble' ||
56
101
  datasets.some((dataset) => dataset.data?.some((value) => isPoint(value) && 'r' in value));
57
102
  const columns = [
58
- 'Series',
59
- 'Point',
60
- ...(hasLabels ? ['Label'] : []),
61
- 'x',
62
- 'y',
63
- ...(hasRadius ? ['r'] : []),
103
+ l.series,
104
+ l.point,
105
+ ...(hasLabels ? [l.label] : []),
106
+ l.x,
107
+ l.y,
108
+ ...(hasRadius ? [l.r] : []),
64
109
  ];
65
110
  const rows: Array<Array<string | number>> = [];
66
111
 
67
112
  datasets.forEach((dataset, datasetIndex) => {
68
- const series = dataset.label || `Series ${datasetIndex + 1}`;
113
+ const series = dataset.label || formatMCPUIString(l.seriesName, { n: datasetIndex + 1 });
69
114
  (dataset.data ?? []).forEach((value, pointIndex) => {
70
115
  const point = isPoint(value) ? value : { y: value };
71
116
  rows.push([
72
117
  series,
73
118
  pointIndex + 1,
74
- ...(hasLabels ? [tableCell(labels[pointIndex])] : []),
119
+ ...(hasLabels ? [tableCell(dataLabels[pointIndex])] : []),
75
120
  tableCell(point.x),
76
121
  tableCell(point.y),
77
122
  ...(hasRadius ? [tableCell(point.r)] : []),
@@ -82,13 +127,22 @@ export function chartToDataTable(params: ChartDataLike): ChartDataTable {
82
127
  return { columns, rows };
83
128
  }
84
129
 
85
- const rowCount = Math.max(labels.length, ...datasets.map((dataset) => dataset.data?.length ?? 0), 0);
86
- const columns = ['Label', ...datasets.map((dataset, index) => dataset.label || `Series ${index + 1}`)];
130
+ const rowCount = Math.max(
131
+ dataLabels.length,
132
+ ...datasets.map((dataset) => dataset.data?.length ?? 0),
133
+ 0
134
+ );
135
+ const columns = [
136
+ l.label,
137
+ ...datasets.map(
138
+ (dataset, index) => dataset.label || formatMCPUIString(l.seriesName, { n: index + 1 })
139
+ ),
140
+ ];
87
141
  const rows: Array<Array<string | number>> = [];
88
142
 
89
143
  for (let rowIndex = 0; rowIndex < rowCount; rowIndex += 1) {
90
144
  rows.push([
91
- tableCell(labels[rowIndex] ?? rowIndex + 1),
145
+ tableCell(dataLabels[rowIndex] ?? rowIndex + 1),
92
146
  ...datasets.map((dataset) => tableCell(dataset.data?.[rowIndex])),
93
147
  ]);
94
148
  }
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { createContext, createSignal, useContext, ParentComponent, Accessor } from 'solid-js'
7
+ import { useMCPUIStrings } from './MCPUIStringsContext'
7
8
 
8
9
  /**
9
10
  * Action request payload
@@ -223,6 +224,8 @@ const defaultExecutor = async (request: ActionRequest): Promise<ActionResult> =>
223
224
  * ```
224
225
  */
225
226
  export const MCPActionProvider: ParentComponent<MCPActionProviderProps> = (props) => {
227
+ // The error of a failed action can be rendered by FormRenderer.
228
+ const strings = useMCPUIStrings()
226
229
  const [isExecuting, setIsExecuting] = createSignal(false)
227
230
  const [lastResult, setLastResult] = createSignal<ActionResult>()
228
231
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -270,7 +273,7 @@ export const MCPActionProvider: ParentComponent<MCPActionProviderProps> = (props
270
273
  } catch (error) {
271
274
  const errorResult: ActionResult = {
272
275
  success: false,
273
- error: error instanceof Error ? error.message : 'Unknown error',
276
+ error: error instanceof Error ? error.message : strings.errorUnknown,
274
277
  timestamp: new Date().toISOString(),
275
278
  toolName: request.toolName,
276
279
  }