@iyulab/chat-components 0.6.0 → 0.7.1

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 (211) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +15 -39
  3. package/dist/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.139.0/helpers/esm}/decorate.js +2 -2
  4. package/dist/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.139.0/helpers/esm}/decorateMetadata.js +2 -2
  5. package/dist/_virtual/_glob-assets_raw/alert-triangle-fill.svg.4cfc4305.js +4 -0
  6. package/dist/_virtual/_glob-assets_raw/arrows-sort.svg.dda43a85.js +4 -0
  7. package/dist/_virtual/_glob-assets_raw/code.svg.c69bc144.js +4 -0
  8. package/dist/_virtual/_glob-assets_raw/download.svg.bce82177.js +4 -0
  9. package/dist/_virtual/_glob-assets_raw/element-prompt.md.7047ffcc.js +4 -0
  10. package/dist/_virtual/_glob-assets_raw/external-link.svg.a9f7f02d.js +4 -0
  11. package/dist/_virtual/_glob-assets_raw/file-code.svg.0e706f93.js +4 -0
  12. package/dist/_virtual/_glob-assets_raw/file-music.svg.b9970203.js +4 -0
  13. package/dist/_virtual/_glob-assets_raw/file-spreadsheet.svg.8c03bdfa.js +4 -0
  14. package/dist/_virtual/_glob-assets_raw/file-text.svg.85bdd923.js +4 -0
  15. package/dist/_virtual/_glob-assets_raw/file-type-pdf.svg.bc12db6d.js +4 -0
  16. package/dist/_virtual/_glob-assets_raw/file-zip.svg.76dde660.js +4 -0
  17. package/dist/_virtual/_glob-assets_raw/file.svg.28f5d6f1.js +4 -0
  18. package/dist/_virtual/_glob-assets_raw/photo.svg.cc273cc1.js +4 -0
  19. package/dist/_virtual/_glob-assets_raw/player-stop-fill.svg.5378b752.js +4 -0
  20. package/dist/_virtual/_glob-assets_raw/send.svg.02326253.js +4 -0
  21. package/dist/_virtual/_glob-assets_raw/sort-ascending-letters.svg.14a3df67.js +4 -0
  22. package/dist/_virtual/_glob-assets_raw/sort-descending-letters.svg.3e03647c.js +4 -0
  23. package/dist/_virtual/_glob-assets_raw/video.svg.c183f03c.js +4 -0
  24. package/dist/_virtual/_glob-assets_raw/world.svg.cd9903c8.js +4 -0
  25. package/dist/components/UDataElement.d.ts +48 -0
  26. package/dist/components/UDataElement.js +80 -0
  27. package/dist/components/blocks/UCodeBlock.d.ts +0 -4
  28. package/dist/components/blocks/UCodeBlock.js +6 -12
  29. package/dist/components/{views/UView.d.ts → blocks/UElementBlock.d.ts} +18 -8
  30. package/dist/components/{views/UView.js → blocks/UElementBlock.js} +31 -21
  31. package/dist/components/{views/UView.styles.js → blocks/UElementBlock.styles.js} +1 -1
  32. package/dist/components/blocks/UFileBlock.d.ts +15 -5
  33. package/dist/components/blocks/UFileBlock.js +81 -68
  34. package/dist/components/blocks/UFileBlock.styles.js +86 -29
  35. package/dist/components/blocks/UMarkedBlock.d.ts +3 -1
  36. package/dist/components/blocks/UMarkedBlock.js +23 -18
  37. package/dist/components/blocks/URefBlock.js +2 -2
  38. package/dist/components/blocks/UTableBlock.d.ts +2 -2
  39. package/dist/components/blocks/UTableBlock.js +9 -8
  40. package/dist/components/blocks/UTableBlock.styles.js +1 -1
  41. package/dist/components/blocks/UTextBlock.d.ts +2 -0
  42. package/dist/components/blocks/UTextBlock.js +4 -5
  43. package/dist/components/message/UMessage.js +2 -2
  44. package/dist/components/prompt/UPrompt.d.ts +0 -5
  45. package/dist/components/prompt/UPrompt.js +18 -27
  46. package/dist/components/prompt/UPrompt.styles.js +9 -10
  47. package/dist/components/references/URefCard.d.ts +6 -5
  48. package/dist/components/references/URefCard.js +14 -11
  49. package/dist/components/references/URefCardGroup.js +2 -2
  50. package/dist/components/references/URefTag.js +5 -4
  51. package/dist/{components/views/UChartView.d.ts → components-extra/UChartBlock.d.ts} +4 -4
  52. package/dist/{components/views/UChartView.js → components-extra/UChartBlock.js} +22 -34
  53. package/dist/components-extra/UChartBlock.schema.d.ts +3 -0
  54. package/dist/components-extra/UChartBlock.schema.js +34 -0
  55. package/dist/{components/views/UChartView.styles.js → components-extra/UChartBlock.styles.js} +1 -1
  56. package/dist/{components/views/UImagesView.d.ts → components-extra/UImagesBlock.d.ts} +4 -4
  57. package/dist/{components/views/UImagesView.js → components-extra/UImagesBlock.js} +15 -15
  58. package/dist/components-extra/UImagesBlock.schema.d.ts +3 -0
  59. package/dist/components-extra/UImagesBlock.schema.js +31 -0
  60. package/dist/{components/views/UImagesView.styles.js → components-extra/UImagesBlock.styles.js} +5 -5
  61. package/dist/{components/views/UMapView.d.ts → components-extra/UMapBlock.d.ts} +4 -4
  62. package/dist/{components/views/UMapView.js → components-extra/UMapBlock.js} +18 -18
  63. package/dist/components-extra/UMapBlock.schema.d.ts +3 -0
  64. package/dist/components-extra/UMapBlock.schema.js +33 -0
  65. package/dist/{components/views/UMapView.styles.js → components-extra/UMapBlock.styles.js} +1 -1
  66. package/dist/{components/views/UVideoView.d.ts → components-extra/UVideoBlock.d.ts} +4 -4
  67. package/dist/{components/views/UVideoView.js → components-extra/UVideoBlock.js} +10 -10
  68. package/dist/components-extra/UVideoBlock.schema.d.ts +3 -0
  69. package/dist/components-extra/UVideoBlock.schema.js +28 -0
  70. package/dist/{components/views/UVideoView.styles.js → components-extra/UVideoBlock.styles.js} +1 -1
  71. package/dist/events/SendEvent.d.ts +0 -5
  72. package/dist/events/StopEvent.d.ts +0 -5
  73. package/dist/extra.d.ts +6 -0
  74. package/dist/extra.js +14 -0
  75. package/dist/index.d.ts +5 -17
  76. package/dist/index.js +6 -16
  77. package/dist/react/UCodeBlock.js +2 -2
  78. package/dist/react/UElementBlock.d.ts +9 -0
  79. package/dist/react/UElementBlock.js +10 -0
  80. package/dist/react/UFileBlock.js +2 -2
  81. package/dist/react/UImagesBlock.d.ts +9 -0
  82. package/dist/react/UImagesBlock.js +10 -0
  83. package/dist/react/UMapBlock.d.ts +9 -0
  84. package/dist/react/UMapBlock.js +10 -0
  85. package/dist/react/UMarkedBlock.js +2 -2
  86. package/dist/react/UMessage.js +2 -2
  87. package/dist/react/UPrompt.js +2 -2
  88. package/dist/react/URefBlock.js +2 -2
  89. package/dist/react/URefCard.js +2 -2
  90. package/dist/react/URefCardGroup.js +2 -2
  91. package/dist/react/URefTag.js +2 -2
  92. package/dist/react/UTableBlock.js +2 -2
  93. package/dist/react/UTextBlock.d.ts +1 -0
  94. package/dist/react/UTextBlock.js +5 -3
  95. package/dist/react/UVideoBlock.d.ts +9 -0
  96. package/dist/react/UVideoBlock.js +10 -0
  97. package/dist/react/index.d.ts +4 -11
  98. package/dist/react/index.js +4 -11
  99. package/dist/types/BlockItem.d.ts +1 -24
  100. package/dist/types/{JsonSchema.d.ts → Schema.d.ts} +13 -0
  101. package/dist/utilities/HtmlBuilder.d.ts +28 -0
  102. package/dist/utilities/HtmlBuilder.js +41 -0
  103. package/dist/utilities/PromptBuilder.d.ts +21 -0
  104. package/dist/utilities/PromptBuilder.js +60 -0
  105. package/dist/utilities/icons.d.ts +1 -0
  106. package/dist/utilities/icons.js +52 -0
  107. package/dist/utilities/sanitizers.d.ts +35 -0
  108. package/dist/utilities/sanitizers.js +75 -0
  109. package/package.json +18 -19
  110. package/skills/iyulab-chat-components/SKILL.md +18 -33
  111. package/skills/iyulab-chat-components/references/components/{chart-view.md → chart-block.md} +16 -12
  112. package/skills/iyulab-chat-components/references/components/code-block.md +1 -5
  113. package/skills/iyulab-chat-components/references/components/element-block.md +57 -0
  114. package/skills/iyulab-chat-components/references/components/file-block.md +22 -25
  115. package/skills/iyulab-chat-components/references/components/{images-view.md → images-block.md} +10 -10
  116. package/skills/iyulab-chat-components/references/components/{map-view.md → map-block.md} +9 -9
  117. package/skills/iyulab-chat-components/references/components/marked-block.md +5 -4
  118. package/skills/iyulab-chat-components/references/components/message.md +1 -2
  119. package/skills/iyulab-chat-components/references/components/prompt.md +12 -21
  120. package/skills/iyulab-chat-components/references/components/{video-view.md → video-block.md} +10 -10
  121. package/skills/iyulab-chat-components/references/extra-system.md +95 -0
  122. package/skills/iyulab-chat-components/references/types.md +17 -31
  123. package/skills/iyulab-chat-components/references/usage.md +13 -81
  124. package/skills/iyulab-chat-components/references/utilities/html-builder.md +35 -0
  125. package/skills/iyulab-chat-components/references/utilities/prompt-builder.md +73 -0
  126. package/dist/_virtual/_glob-assets_raw/intent-prompt.md.1907474e.js +0 -4
  127. package/dist/_virtual/_glob-assets_raw/view-prompt.md.e0dbcffe.js +0 -4
  128. package/dist/chart.d.ts +0 -1
  129. package/dist/chart.js +0 -2
  130. package/dist/components/blocks/UJsonBlock.d.ts +0 -49
  131. package/dist/components/blocks/UJsonBlock.js +0 -130
  132. package/dist/components/blocks/UJsonBlock.styles.js +0 -115
  133. package/dist/components/blocks/UThinkBlock.d.ts +0 -35
  134. package/dist/components/blocks/UThinkBlock.js +0 -87
  135. package/dist/components/blocks/UThinkBlock.styles.js +0 -74
  136. package/dist/components/blocks/UToolBlock.d.ts +0 -24
  137. package/dist/components/blocks/UToolBlock.js +0 -70
  138. package/dist/components/blocks/UToolBlock.styles.js +0 -66
  139. package/dist/components/buttons/UAttachButton.d.ts +0 -26
  140. package/dist/components/buttons/UAttachButton.js +0 -63
  141. package/dist/components/buttons/UAttachButton.styles.js +0 -14
  142. package/dist/components/buttons/UCopyButton.d.ts +0 -24
  143. package/dist/components/buttons/UCopyButton.js +0 -59
  144. package/dist/components/buttons/UCopyButton.styles.js +0 -18
  145. package/dist/components/buttons/UVoteButton.d.ts +0 -19
  146. package/dist/components/buttons/UVoteButton.js +0 -64
  147. package/dist/components/buttons/UVoteButton.styles.d.ts +0 -1
  148. package/dist/components/buttons/UVoteButton.styles.js +0 -19
  149. package/dist/components/intents/UQuestionIntent.d.ts +0 -22
  150. package/dist/components/intents/UQuestionIntent.js +0 -41
  151. package/dist/components/intents/UQuestionIntent.styles.d.ts +0 -1
  152. package/dist/components/intents/UQuestionIntent.styles.js +0 -43
  153. package/dist/components/views/UChartView.styles.d.ts +0 -1
  154. package/dist/components/views/UImagesView.styles.d.ts +0 -1
  155. package/dist/components/views/UMapView.styles.d.ts +0 -1
  156. package/dist/components/views/UVideoView.styles.d.ts +0 -1
  157. package/dist/components/views/UView.styles.d.ts +0 -1
  158. package/dist/events/AttachEvent.d.ts +0 -9
  159. package/dist/events/ChoiceEvent.d.ts +0 -9
  160. package/dist/react/UAttachButton.d.ts +0 -11
  161. package/dist/react/UAttachButton.js +0 -12
  162. package/dist/react/UCopyButton.d.ts +0 -9
  163. package/dist/react/UCopyButton.js +0 -10
  164. package/dist/react/UImagesView.d.ts +0 -9
  165. package/dist/react/UImagesView.js +0 -10
  166. package/dist/react/UJsonBlock.d.ts +0 -9
  167. package/dist/react/UJsonBlock.js +0 -10
  168. package/dist/react/UMapView.d.ts +0 -9
  169. package/dist/react/UMapView.js +0 -10
  170. package/dist/react/UQuestionIntent.d.ts +0 -11
  171. package/dist/react/UQuestionIntent.js +0 -12
  172. package/dist/react/UThinkBlock.d.ts +0 -9
  173. package/dist/react/UThinkBlock.js +0 -10
  174. package/dist/react/UToolBlock.d.ts +0 -9
  175. package/dist/react/UToolBlock.js +0 -10
  176. package/dist/react/UVideoView.d.ts +0 -9
  177. package/dist/react/UVideoView.js +0 -10
  178. package/dist/react/UView.d.ts +0 -9
  179. package/dist/react/UView.js +0 -10
  180. package/dist/react/UVoteButton.d.ts +0 -9
  181. package/dist/react/UVoteButton.js +0 -10
  182. package/dist/types/Intents.d.ts +0 -26
  183. package/dist/types/Intents.js +0 -30
  184. package/dist/types/JsonNode.d.ts +0 -20
  185. package/dist/types/Views.d.ts +0 -34
  186. package/dist/types/Views.js +0 -148
  187. package/dist/utilities/IntentPromptBuilder.d.ts +0 -40
  188. package/dist/utilities/IntentPromptBuilder.js +0 -95
  189. package/dist/utilities/ViewPromptBuilder.d.ts +0 -28
  190. package/dist/utilities/ViewPromptBuilder.js +0 -78
  191. package/dist/utilities/dom-agent/DOMAgent.d.ts +0 -74
  192. package/dist/utilities/dom-agent/DOMController.d.ts +0 -78
  193. package/dist/utilities/dom-agent/DOMPromptBuilder.d.ts +0 -54
  194. package/dist/utilities/dom-agent/DOMScanner.d.ts +0 -83
  195. package/dist/utilities/dom-agent/index.d.ts +0 -9
  196. package/dist/utilities/dom-agent/types.d.ts +0 -209
  197. package/skills/iyulab-chat-components/references/components/attach-button.md +0 -69
  198. package/skills/iyulab-chat-components/references/components/copy-button.md +0 -46
  199. package/skills/iyulab-chat-components/references/components/json-block.md +0 -41
  200. package/skills/iyulab-chat-components/references/components/question-intent.md +0 -75
  201. package/skills/iyulab-chat-components/references/components/think-block.md +0 -48
  202. package/skills/iyulab-chat-components/references/components/tool-block.md +0 -57
  203. package/skills/iyulab-chat-components/references/components/view.md +0 -51
  204. package/skills/iyulab-chat-components/references/components/vote-button.md +0 -60
  205. package/skills/iyulab-chat-components/references/utilities/intent-prompt-builder.md +0 -123
  206. package/skills/iyulab-chat-components/references/utilities/view-prompt-builder.md +0 -112
  207. /package/dist/components/{buttons/UCopyButton.styles.d.ts → blocks/UElementBlock.styles.d.ts} +0 -0
  208. /package/dist/{components/blocks/UJsonBlock.styles.d.ts → components-extra/UChartBlock.styles.d.ts} +0 -0
  209. /package/dist/{components/blocks/UThinkBlock.styles.d.ts → components-extra/UImagesBlock.styles.d.ts} +0 -0
  210. /package/dist/{components/blocks/UToolBlock.styles.d.ts → components-extra/UMapBlock.styles.d.ts} +0 -0
  211. /package/dist/{components/buttons/UAttachButton.styles.d.ts → components-extra/UVideoBlock.styles.d.ts} +0 -0
@@ -10,24 +10,12 @@ Union type for all message content blocks. Used to exchange structured message d
10
10
 
11
11
  ```ts
12
12
  type BlockItem =
13
- | ThinkingBlockItem
14
13
  | TextBlockItem
15
14
  | MarkdownBlockItem
16
15
  | FileBlockItem
17
- | ToolBlockItem
18
16
  | ReferenceBlockItem;
19
17
  ```
20
18
 
21
- ### ThinkingBlockItem → `u-think-block`
22
-
23
- ```ts
24
- interface ThinkingBlockItem {
25
- type: 'thinking';
26
- loading?: boolean; // Streaming in progress
27
- value?: string; // Reasoning text content
28
- }
29
- ```
30
-
31
19
  ### TextBlockItem → `u-text-block`
32
20
 
33
21
  ```ts
@@ -52,27 +40,14 @@ interface MarkdownBlockItem {
52
40
  ```ts
53
41
  interface FileBlockItem {
54
42
  type: 'file';
55
- status?: 'idle' | 'uploading' | 'error';
56
43
  name?: string; // File name
57
44
  size?: number; // File size in bytes
58
45
  mimeType?: string; // MIME type, e.g. "image/png"
59
- url?: string; // Download URL
46
+ url?: string; // File URL (used for image/video thumbnail + preview)
60
47
  data?: any;
61
48
  }
62
49
  ```
63
50
 
64
- ### ToolBlockItem → `u-tool-block`
65
-
66
- ```ts
67
- interface ToolBlockItem {
68
- type: 'tool';
69
- loading?: boolean;
70
- title?: string;
71
- input?: JsonNode;
72
- output?: JsonNode;
73
- }
74
- ```
75
-
76
51
  ### ReferenceBlockItem → `u-ref-block`
77
52
 
78
53
  ```ts
@@ -105,11 +80,22 @@ interface ReferenceCitation {
105
80
 
106
81
  ---
107
82
 
108
- ## JsonNode
83
+ ## JsonSchema & ElementSchema
84
+
85
+ Used by [`ElementPromptBuilder`](./utilities/prompt-builder.md) to describe extra/element schemas for the LLM system prompt (see [extra-system.md](./extra-system.md)).
109
86
 
110
87
  ```ts
111
- type JsonValue = string | number | boolean | null;
112
- type JsonArray = JsonNode[];
113
- type JsonObject = { [key: string]: JsonNode };
114
- type JsonNode = JsonValue | JsonArray | JsonObject;
88
+ type JsonSchema =
89
+ | { type: 'boolean'; description?: string; default?: any; enum?: any[]; examples?: any[] }
90
+ | { type: 'string'; minLength?: number; maxLength?: number; /* + base fields above */ }
91
+ | { type: 'number' | 'integer'; minimum?: number; maximum?: number; /* + base fields above */ }
92
+ | { type: 'array'; items?: JsonSchema; minItems?: number; maxItems?: number; /* + base fields above */ }
93
+ | { type: 'object'; properties?: Record<string, JsonSchema>; required?: string[]; additionalProperties?: boolean; /* + base fields above */ };
94
+
95
+ interface ElementSchema {
96
+ tag: string; // Custom element tag to register
97
+ description: string; // LLM-facing description
98
+ properties?: Record<string, JsonSchema>; // LLM-facing property schema
99
+ required?: string[]; // Required property names
100
+ }
115
101
  ```
@@ -28,7 +28,6 @@ import '@iyulab/chat-components/dist/components/blocks/UMarkedBlock.js';
28
28
 
29
29
  ```ts
30
30
  import type { BlockItem, ReferenceSource } from '@iyulab/chat-components';
31
- import { PresetIntent, PresetView } from '@iyulab/chat-components';
32
31
  ```
33
32
 
34
33
  ---
@@ -51,8 +50,8 @@ const prompt = document.getElementById('prompt');
51
50
  const messages = document.getElementById('messages');
52
51
 
53
52
  // Handle send event
54
- prompt.addEventListener('send', () => {
55
- const value = prompt.value;
53
+ prompt.addEventListener('send', (e) => {
54
+ const { value } = e.detail;
56
55
  if (!value) return;
57
56
 
58
57
  // Add user message
@@ -70,15 +69,14 @@ prompt.addEventListener('send', () => {
70
69
  // Handle LLM streaming...
71
70
  });
72
71
 
73
- // Handle file attachments
74
- prompt.addEventListener('attach', (e) => {
75
- const { files } = e.detail;
72
+ // Handle file attachments (there is no built-in attach button — wire up your own)
73
+ fileInput.addEventListener('change', (e) => {
74
+ const files = [...e.target.files];
76
75
  prompt.files = files.map(f => ({
77
76
  type: 'file',
78
77
  name: f.name,
79
78
  size: f.size,
80
79
  mimeType: f.type,
81
- status: 'idle',
82
80
  }));
83
81
  });
84
82
  ```
@@ -117,72 +115,23 @@ markedBlock.refs = refs;
117
115
 
118
116
  ---
119
117
 
120
- ## Intent System
118
+ ## Extra System
121
119
 
122
- Make the LLM output structured intent-json blocks by adding instructions to the system prompt:
120
+ Let the LLM render rich content (charts, maps, image galleries, videos) via `block-json` code fences. See [extra-system.md](./extra-system.md) for full details.
123
121
 
124
122
  ```ts
125
- import { IntentPromptBuilder, PresetIntent } from '@iyulab/chat-components';
126
-
127
- // Use preset intents
128
- IntentPromptBuilder.instance.use(PresetIntent.Questions);
129
-
130
- // Add custom intent
131
- IntentPromptBuilder.instance.add({
132
- type: 'rating',
133
- description: 'Ask user to rate something on a scale',
134
- properties: {
135
- label: { type: 'string', description: 'What to rate' },
136
- max: { type: 'number', description: 'Max score (default: 5)' }
137
- },
138
- required: ['label']
139
- });
140
-
141
- // Inject into system prompt
142
- const systemPrompt = IntentPromptBuilder.instance.build();
143
- ```
144
-
145
- Parse intent-json from the LLM response and render components:
146
-
147
- ```ts
148
- const [cleanText, intents] = IntentPromptBuilder.instance.parse(llmResponse);
149
-
150
- for (const intent of intents) {
151
- if (intent.type === 'question') {
152
- const el = document.createElement('u-question-intent');
153
- el.question = intent.properties?.question;
154
- el.choices = intent.properties?.choices ?? [];
155
- messageEl.appendChild(el);
156
- }
157
- }
158
-
159
- markedBlock.value = cleanText;
160
- ```
161
-
162
- ---
163
-
164
- ## View System
165
-
166
- Let the LLM render rich content (charts, maps, videos, etc.) via view-json code blocks:
167
-
168
- ```ts
169
- import { ViewPromptBuilder, PresetView } from '@iyulab/chat-components';
170
-
171
- // Use all preset views
172
- ViewPromptBuilder.instance.use(PresetView.All);
173
- // Or selectively
174
- ViewPromptBuilder.instance.use(PresetView.Images | PresetView.Chart);
123
+ import '@iyulab/chat-components';
124
+ import { prompt as extraInstructions } from '@iyulab/chat-components/extra';
175
125
 
176
- // Inject into system prompt
177
- const systemPrompt = ViewPromptBuilder.instance.build();
126
+ const systemPrompt = `You are a helpful assistant.\n\n${extraInstructions}`;
178
127
  ```
179
128
 
180
- When `u-marked-block` encounters a view-json code block from the LLM, it automatically renders it via `u-view`:
129
+ `u-marked-block` automatically detects `block-json` fences and renders them via `u-element-block` — no parsing step needed:
181
130
 
182
131
  ````
183
- ```view-json
132
+ ```block-json
184
133
  {
185
- "tag": "u-chart-view",
134
+ "tag": "u-chart-block",
186
135
  "properties": {
187
136
  "type": "bar",
188
137
  "data": { "labels": ["A", "B"], "datasets": [{ "data": [10, 20] }] }
@@ -216,29 +165,12 @@ function renderBlocks(blocks: BlockItem[], container: HTMLElement) {
216
165
  container.appendChild(el);
217
166
  break;
218
167
  }
219
- case 'thinking': {
220
- const el = document.createElement('u-think-block');
221
- el.loading = block.loading ?? false;
222
- el.value = block.value;
223
- container.appendChild(el);
224
- break;
225
- }
226
- case 'tool': {
227
- const el = document.createElement('u-tool-block');
228
- el.loading = block.loading ?? false;
229
- el.title = block.title ?? '';
230
- el.input = block.input;
231
- el.output = block.output;
232
- container.appendChild(el);
233
- break;
234
- }
235
168
  case 'file': {
236
169
  const el = document.createElement('u-file-block');
237
170
  el.name = block.name;
238
171
  el.size = block.size;
239
172
  el.type = block.mimeType;
240
173
  el.url = block.url;
241
- el.status = block.status ?? 'idle';
242
174
  container.appendChild(el);
243
175
  break;
244
176
  }
@@ -0,0 +1,35 @@
1
+ # HtmlBuilder
2
+
3
+ ```ts
4
+ import { HtmlBuilder } from '@iyulab/chat-components';
5
+ ```
6
+
7
+ Utility for building custom-element HTML strings, used internally by `u-marked-block` to inject `u-ref-tag`, `u-ref-card-group`, `u-code-block`, and `u-element-block` markup while rendering markdown. Useful if you're pre-building HTML fragments to feed into `u-marked-block` (e.g. custom preprocessing) instead of writing template strings by hand.
8
+
9
+ ```ts
10
+ HtmlBuilder.build('u-ref-tag', { href: 'https://example.com', disabled: true }, 'Click');
11
+ // → '<u-ref-tag href="https://example.com" disabled>Click</u-ref-tag>'
12
+ ```
13
+
14
+ ---
15
+
16
+ ## API
17
+
18
+ ### `HtmlBuilder.build(tag, attrs?, content?): string`
19
+
20
+ | Param | Type | Description |
21
+ |-------|------|-------------|
22
+ | `tag` | `string` | Custom element tag name (e.g. `"u-ref-tag"`) |
23
+ | `attrs` | `Record<string, string \| boolean \| object \| null \| undefined>` | Attribute map (default `{}`) |
24
+ | `content` | `string` | Inner HTML string, assumed already safe — no internal escaping (default `''`) |
25
+
26
+ **Attribute value rules:**
27
+
28
+ | Value | Result |
29
+ |-------|--------|
30
+ | `null` / `undefined` | Attribute omitted |
31
+ | `false` | Attribute omitted |
32
+ | `true` | Key only, no value (e.g. `disabled`) |
33
+ | `object` | `JSON.stringify`'d, then HTML-attribute-escaped |
34
+ | `href` / `src` keys | Escaped via the URL-safe escaper (blocks `javascript:` etc.) |
35
+ | other `string` | HTML-attribute-escaped |
@@ -0,0 +1,73 @@
1
+ # ElementPromptBuilder
2
+
3
+ ```ts
4
+ import { ElementPromptBuilder } from '@iyulab/chat-components';
5
+ import type { ElementSchema } from '@iyulab/chat-components';
6
+ ```
7
+
8
+ Singleton utility that registers element schemas and generates LLM system prompt instructions for the `block-json` extra system. No manual parsing is needed — `u-marked-block` automatically renders `block-json` code fences via `u-element-block` (see [../extra-system.md](../extra-system.md)).
9
+
10
+ For the 4 built-in extras (chart/images/map/video), you usually don't need to touch this API directly — `@iyulab/chat-components/extra` exports a ready-built `prompt` string:
11
+
12
+ ```ts
13
+ import { prompt } from '@iyulab/chat-components/extra';
14
+
15
+ const systemPrompt = `You are a helpful assistant.\n\n${prompt}`;
16
+ ```
17
+
18
+ ---
19
+
20
+ ## Overview
21
+
22
+ ```ts
23
+ const builder = ElementPromptBuilder.instance;
24
+
25
+ // Register a custom element schema
26
+ builder.add({
27
+ tag: 'my-custom-block',
28
+ description: 'Display a custom visualization',
29
+ properties: {
30
+ data: { type: 'array', description: 'Data array' }
31
+ },
32
+ required: ['data']
33
+ });
34
+
35
+ // Inject into LLM system prompt
36
+ const instruction = builder.build();
37
+ ```
38
+
39
+ When the LLM outputs a `block-json` fence, `u-marked-block` renders it automatically via `u-element-block`:
40
+
41
+ ````
42
+ ```block-json
43
+ {
44
+ "tag": "my-custom-block",
45
+ "properties": { "data": [1, 2, 3] }
46
+ }
47
+ ```
48
+ ````
49
+
50
+ ---
51
+
52
+ ## API
53
+
54
+ ### `ElementPromptBuilder.instance`
55
+
56
+ Returns the singleton. Created on first access.
57
+
58
+ ### `.add(schema: ElementSchema): this`
59
+
60
+ Registers a custom element schema. Throws if the same `tag` is already registered.
61
+
62
+ ```ts
63
+ interface ElementSchema {
64
+ tag: string;
65
+ description: string;
66
+ properties?: Record<string, JsonSchema>;
67
+ required?: string[];
68
+ }
69
+ ```
70
+
71
+ ### `.build(): string`
72
+
73
+ Returns LLM system prompt instructions for all registered schemas, injected into the `element-prompt.md` template. Returns an empty string if nothing is registered.
@@ -1,4 +0,0 @@
1
- //#region \0glob-assets_raw/intent-prompt.md.1907474e
2
- var intent_prompt_md_default = "## Interactive Intents\n\nYou can guide the user with interactive intents by appending `intent-json` fenced code blocks at the end of your response. These intents can suggest follow-up questions, offer buttons to click, or provide other interactive elements that help the user continue the conversation.\n\n**Output format (the fence language must be `intent-json`):**\n```intent-json\n{\n \"type\": \"intent-type-here\",\n \"properties\" : {\n \"key\": \"value\"\n }\n}\n```\n\n**Rules — follow these STRICTLY. Violation means the feature will not work:**\n1. The fenced block language identifier must be `intent-json`, not `json` or anything else.\n2. `type` must be one of the exact strings listed below. Do not invent new types.\n3. place ALL intent blocks at the very end of your response, after all prose content.\n4. Output valid JSON only — no comments, no trailing commas, etc.\n\n---\n\n{{INTENT_DOCS}}\n";
3
- //#endregion
4
- export { intent_prompt_md_default as default };
@@ -1,4 +0,0 @@
1
- //#region \0glob-assets_raw/view-prompt.md.e0dbcffe
2
- var view_prompt_md_default = "## Renderable Views\n\nYou can render interactive visual views inside your response.\nWhen a view would make your answer clearer or more useful, output a `view-json` fenced code block.\n\n**Output format (the fence language must be `view-json`):**\n```view-json\n{\n \"tag\": \"view-tag-here\",\n \"properties\": {\n \"key\": \"value\"\n }\n}\n```\n\n**Rules — follow these strictly:**\n1. The fenced block language identifier must be `view-json`, not `json` or anything else.\n2. `tag` must be one of the exact strings listed below. Never invent a tag.\n3. Output valid JSON — no comments, no trailing commas.\n\n---\n\n{{VIEW_DOCS}}\n";
3
- //#endregion
4
- export { view_prompt_md_default as default };
package/dist/chart.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from './components/views/UChartView.js';
package/dist/chart.js DELETED
@@ -1,2 +0,0 @@
1
- import { UChartView } from "./components/views/UChartView.js";
2
- export { UChartView };
@@ -1,49 +0,0 @@
1
- import { PropertyValues, TemplateResult } from 'lit';
2
- import { UElement } from '@iyulab/components/dist/components/UElement.js';
3
- import { JsonNode } from '../../types/JsonNode.js';
4
- /**
5
- * json 데이터를 트리 형태로 시각화하는 컴포넌트입니다.
6
- */
7
- export declare class UJsonBlock extends UElement {
8
- static styles: import('lit').CSSResultGroup[];
9
- /** 초기 확장 상태를 관리하는 속성입니다. */
10
- expanded: boolean;
11
- /** JSON 데이터 (속성으로 전달 가능) */
12
- value: JsonNode;
13
- state: Record<string, boolean>;
14
- connectedCallback(): void;
15
- protected willUpdate(changedProperties: PropertyValues): void;
16
- render(): TemplateResult<1>;
17
- /**
18
- * JsonNode를 렌더링합니다.
19
- * @param value - JsonNode (JsonObject, JsonArray, 또는 JsonValue)
20
- * @param parent - 부모 노드의 경로
21
- */
22
- private renderNode;
23
- /**
24
- * JsonValue를 렌더링합니다.
25
- * @param node - JsonValue (string, number, boolean, null 등)
26
- */
27
- private renderValue;
28
- /**
29
- * JsonObject 또는 JsonArray를 렌더링합니다.
30
- * @param node - JsonObject 또는 JsonArray
31
- * @param depth - 현재 깊이
32
- */
33
- private renderObject;
34
- /**
35
- * 노드의 미리보기를 렌더링합니다.
36
- * @param node - JsonObject 또는 JsonArray
37
- */
38
- private renderPreview;
39
- /** JSON 데이터를 순회하며 각 경로의 확장 상태를 설정합니다. */
40
- private setState;
41
- private isValueType;
42
- /** 노드 확장/축소 클릭 핸들러 */
43
- private handlePropertyKeyClick;
44
- }
45
- declare global {
46
- interface HTMLElementTagNameMap {
47
- 'u-json-block': UJsonBlock;
48
- }
49
- }
@@ -1,130 +0,0 @@
1
- import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.130.0/helpers/decorateMetadata.js";
2
- import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.130.0/helpers/decorate.js";
3
- import { styles } from "./UJsonBlock.styles.js";
4
- import { html } from "lit";
5
- import { customElement, property, state } from "lit/decorators.js";
6
- import { UElement } from "@iyulab/components/dist/components/UElement.js";
7
- import { map } from "lit/directives/map.js";
8
- import { when } from "lit/directives/when.js";
9
- import { jsonAttrConverter } from "@iyulab/components/dist/utilities/converters.js";
10
- //#region src/components/blocks/UJsonBlock.ts
11
- var _ref;
12
- var UJsonBlock = class UJsonBlock extends UElement {
13
- constructor(..._args) {
14
- super(..._args);
15
- this.expanded = true;
16
- this.value = {};
17
- this.state = {};
18
- this.isValueType = (value) => {
19
- return value !== Object(value);
20
- };
21
- }
22
- static {
23
- this.styles = [super.styles, styles];
24
- }
25
- connectedCallback() {
26
- super.connectedCallback();
27
- this.setAttribute("tabindex", "0");
28
- }
29
- willUpdate(changedProperties) {
30
- super.willUpdate(changedProperties);
31
- if (changedProperties.has("value") || changedProperties.has("expanded")) this.state = this.setState(this.value);
32
- }
33
- render() {
34
- return html`
35
- <div part="base">
36
- ${this.renderNode(this.value)}
37
- </div>
38
- `;
39
- }
40
- /**
41
- * JsonNode를 렌더링합니다.
42
- * @param value - JsonNode (JsonObject, JsonArray, 또는 JsonValue)
43
- * @param parent - 부모 노드의 경로
44
- */
45
- renderNode(value, parent = "") {
46
- return this.isValueType(value) ? this.renderValue(value) : this.renderObject(value, parent);
47
- }
48
- /**
49
- * JsonValue를 렌더링합니다.
50
- * @param node - JsonValue (string, number, boolean, null 등)
51
- */
52
- renderValue(node) {
53
- const type = node === null ? "null" : Array.isArray(node) ? "array" : typeof node === "object" ? "object" : typeof node;
54
- return html`
55
- <span part="${type}" class="${type}" role="treeitem">
56
- ${JSON.stringify(node)}
57
- </span>
58
- `;
59
- }
60
- /**
61
- * JsonObject 또는 JsonArray를 렌더링합니다.
62
- * @param node - JsonObject 또는 JsonArray
63
- * @param depth - 현재 깊이
64
- */
65
- renderObject(node, parent) {
66
- return html`
67
- <ul part="object" role="group">
68
- ${map(Object.entries(node), ([key, value]) => {
69
- const path = parent ? `${parent}.${key}` : key;
70
- const isValue = this.isValueType(value);
71
- const isExpanded = this.state[path] ?? this.expanded;
72
- return html`
73
- <li part="property" role="treeitem"
74
- data-path="${path}"
75
- aria-expanded="${isExpanded ? "true" : "false"}">
76
- <span part="key"
77
- class="key"
78
- ?collapsable="${!isValue}"
79
- ?collapsed="${!isValue && !isExpanded}"
80
- @click=${!isValue ? () => this.handlePropertyKeyClick(path) : null}>
81
- ${key}:
82
- ${when(!isValue && !isExpanded, () => this.renderPreview(value))}
83
- </span>
84
-
85
- ${when(isValue || isExpanded, () => this.renderNode(value, path))}
86
- </li>`;
87
- })}
88
- </ul>
89
- `;
90
- }
91
- /**
92
- * 노드의 미리보기를 렌더링합니다.
93
- * @param node - JsonObject 또는 JsonArray
94
- */
95
- renderPreview(node) {
96
- return html`
97
- <span part="preview" class="preview">
98
- ${Array.isArray(node) ? node.length === 0 ? "[ ]" : `[ ${node.length} items ]` : Object.keys(node).length === 0 ? "{ }" : `{ ${Object.keys(node).length} properties }`}
99
- </span>
100
- `;
101
- }
102
- /** JSON 데이터를 순회하며 각 경로의 확장 상태를 설정합니다. */
103
- setState(value, parent = "") {
104
- if (typeof value !== "object" || value === null) return {};
105
- const state = {};
106
- Object.entries(value).forEach(([key, item]) => {
107
- const path = parent ? `${parent}.${key}` : key;
108
- state[path] = this.expanded;
109
- Object.assign(state, this.setState(item, path));
110
- });
111
- return state;
112
- }
113
- /** 노드 확장/축소 클릭 핸들러 */
114
- handlePropertyKeyClick(path) {
115
- const isExpanded = this.state[path] ?? false;
116
- this.state = {
117
- ...this.state,
118
- [path]: !isExpanded
119
- };
120
- }
121
- };
122
- __decorate([property({ type: Boolean }), __decorateMetadata("design:type", Boolean)], UJsonBlock.prototype, "expanded", void 0);
123
- __decorate([property({
124
- type: Object,
125
- converter: jsonAttrConverter()
126
- }), __decorateMetadata("design:type", Object)], UJsonBlock.prototype, "value", void 0);
127
- __decorate([state(), __decorateMetadata("design:type", typeof (_ref = typeof Record !== "undefined" && Record) === "function" ? _ref : Object)], UJsonBlock.prototype, "state", void 0);
128
- UJsonBlock = __decorate([customElement("u-json-block")], UJsonBlock);
129
- //#endregion
130
- export { UJsonBlock };
@@ -1,115 +0,0 @@
1
- import { css } from "lit";
2
- //#region src/components/blocks/UJsonBlock.styles.ts
3
- var styles = css`
4
- :host {
5
- --indent-size: 2em;
6
-
7
- --json-property-color: #0451a5;
8
- --json-string-color: #a31515;
9
- --json-number-color: #098658;
10
- --json-boolean-color: #0000ff;
11
- --json-null-color: #0000ff;
12
- --json-preview-color: #999999;
13
- --json-arrow-color: #666968;
14
- --json-guide-color: #c0c0c0;
15
- }
16
- :host-context([theme="dark"]) {
17
- --json-property-color: #9cdcfe;
18
- --json-string-color: #ce9178;
19
- --json-number-color: #b5cea8;
20
- --json-boolean-color: #569cd6;
21
- --json-null-color: #569CD6;
22
- --json-preview-color: #999999;
23
- --json-arrow-color: #d4d4d4;
24
- --json-guide-color: #3c3c3c;
25
- }
26
-
27
- :host {
28
- display: block;
29
- font-family: inherit;
30
- font-size: inherit;
31
- line-height: 1.5;
32
- }
33
-
34
- .key {
35
- color: var(--json-property-color);
36
- display: inline-flex;
37
- align-items: center;
38
- }
39
- .key[collapsable] {
40
- cursor: pointer;
41
- user-select: none;
42
- }
43
- .key[collapsable]::before {
44
- display: inline-flex;
45
- font-size: 0.5em;
46
- content: '▶';
47
- align-items: center;
48
- justify-content: center;
49
-
50
- transform: rotate(90deg);
51
- transition: transform 0.2s ease-out;
52
- margin-right: 0.5em;
53
-
54
- color: var(--json-arrow-color);
55
- }
56
- .key[collapsable][collapsed]::before {
57
- transform: rotate(0);
58
- }
59
-
60
- .preview {
61
- color: var(--json-preview-color);
62
- margin-left: 0.5em;
63
- }
64
-
65
- .string {
66
- color: var(--json-string-color);
67
- }
68
-
69
- .number {
70
- color: var(--json-number-color);
71
- }
72
-
73
- .boolean {
74
- color: var(--json-boolean-color);
75
- }
76
-
77
- .null {
78
- color: var(--json-null-color);
79
- }
80
-
81
- /* object styles */
82
- ul {
83
- position: relative;
84
- list-style: none;
85
- margin: 0;
86
- padding: 0;
87
- clear: both;
88
- }
89
-
90
- /* property styles */
91
- li {
92
- position: relative;
93
- list-style: none;
94
- outline: none;
95
- }
96
-
97
- /* nested property styles */
98
- li ul > li {
99
- position: relative;
100
- margin-left: var(--indent-size);
101
- padding-left: 0px;
102
- }
103
-
104
- /* guide line styles */
105
- ul ul::before {
106
- content: '';
107
- border-left: 1px solid var(--json-guide-color);
108
- position: absolute;
109
- left: calc(1.5em / 2 - 1px);
110
- top: 0.2em;
111
- bottom: 0.2em;
112
- }
113
- `;
114
- //#endregion
115
- export { styles };