|
36 | 36 | children: [] |
37 | 37 | }; |
38 | 38 |
|
39 | | - let processingMessage = $state({ |
40 | | - id: '4', |
41 | | - convId: 'conv-1', |
42 | | - type: 'message', |
43 | | - timestamp: 0, // No timestamp = processing |
44 | | - role: 'assistant', |
45 | | - content: '', |
46 | | - parent: '1', |
47 | | - thinking: '', |
48 | | - children: [] |
49 | | - }); |
50 | | -
|
51 | | - let streamingMessage = $state({ |
52 | | - id: '5', |
53 | | - convId: 'conv-1', |
54 | | - type: 'message', |
55 | | - timestamp: 0, // No timestamp = streaming |
56 | | - role: 'assistant', |
57 | | - content: '', |
58 | | - parent: '1', |
59 | | - thinking: '', |
60 | | - children: [] |
61 | | - }); |
62 | | -
|
63 | | - // Message with dedicated thinking content |
64 | | - const thinkTagMessage: DatabaseMessage = { |
65 | | - id: '6', |
| 39 | + const assistantWithReasoning: DatabaseMessage = { |
| 40 | + id: '3', |
66 | 41 | convId: 'conv-1', |
67 | 42 | type: 'message', |
68 | 43 | timestamp: Date.now() - 1000 * 60 * 2, |
69 | 44 | role: 'assistant', |
70 | 45 | content: |
71 | | - "Here's my response after thinking through the problem. The reasoning should appear separately from this main response content.", |
| 46 | + "Here's the concise answer, now that I've thought it through carefully for you.", |
72 | 47 | parent: '1', |
73 | 48 | thinking: |
74 | | - "Let me analyze this step by step:\n\n1. The user is asking about thinking formats\n2. I need to demonstrate the <think> tag format\n3. This content should be displayed in the thinking section\n4. The main response should be separate\n\nThis is a good example of reasoning content.", |
| 49 | + "Let's consider the user's question step by step:\\n\\n1. Identify the core problem\\n2. Evaluate relevant information\\n3. Formulate a clear answer\\n\\nFollowing this process ensures the final response stays focused and accurate.", |
75 | 50 | children: [] |
76 | 51 | }; |
77 | 52 |
|
78 | | - // Message with separate DeepSeek-style thinking content |
79 | | - const thinkBracketMessage: DatabaseMessage = { |
80 | | - id: '7', |
81 | | - convId: 'conv-1', |
82 | | - type: 'message', |
83 | | - timestamp: Date.now() - 1000 * 60 * 1, |
84 | | - role: 'assistant', |
85 | | - content: |
86 | | - "Here's my response after using the [THINK] format to organize the answer. The reasoning content should be shown separately from this response.", |
87 | | - parent: '1', |
88 | | - thinking: |
89 | | - "This is the DeepSeek-style thinking format:\n\n- Using square brackets instead of angle brackets\n- Should work identically to the <think> format\n- Reasoning content should display in the thinking section\n- Main response should be separate\n\nBoth formats should be supported seamlessly.", |
90 | | - children: [] |
91 | | - }; |
92 | | -
|
93 | | - // Streaming message for dedicated thinking content |
94 | | - let streamingThinkMessage = $state({ |
95 | | - id: '8', |
| 53 | + let processingMessage = $state({ |
| 54 | + id: '4', |
96 | 55 | convId: 'conv-1', |
97 | 56 | type: 'message', |
98 | | - timestamp: 0, // No timestamp = streaming |
| 57 | + timestamp: 0, // No timestamp = processing |
99 | 58 | role: 'assistant', |
100 | 59 | content: '', |
101 | 60 | parent: '1', |
102 | 61 | thinking: '', |
103 | 62 | children: [] |
104 | 63 | }); |
105 | 64 |
|
106 | | - // Streaming message for DeepSeek-style thinking content |
107 | | - let streamingBracketMessage = $state({ |
108 | | - id: '9', |
| 65 | + let streamingMessage = $state({ |
| 66 | + id: '5', |
109 | 67 | convId: 'conv-1', |
110 | 68 | type: 'message', |
111 | 69 | timestamp: 0, // No timestamp = streaming |
|
133 | 91 | /> |
134 | 92 |
|
135 | 93 | <Story |
136 | | - name="WithThinkingBlock" |
| 94 | + name="AssistantWithReasoning" |
| 95 | + args={{ |
| 96 | + class: 'max-w-[56rem] w-[calc(100vw-2rem)]', |
| 97 | + message: assistantWithReasoning |
| 98 | + }} |
| 99 | +/> |
| 100 | + |
| 101 | +<Story |
| 102 | + name="WithReasoningContent" |
137 | 103 | args={{ |
138 | 104 | message: streamingMessage |
139 | 105 | }} |
140 | | - asChild |
| 106 | +asChild |
141 | 107 | play={async () => { |
142 | 108 | // Phase 1: Stream reasoning content in chunks |
143 | 109 | let reasoningText = |
|
183 | 149 | </div> |
184 | 150 | </Story> |
185 | 151 |
|
| 152 | + |
186 | 153 | <Story |
187 | 154 | name="Processing" |
188 | 155 | args={{ |
|
191 | 158 | play={async () => { |
192 | 159 | // Import the chat store to simulate loading state |
193 | 160 | const { chatStore } = await import('$lib/stores/chat.svelte'); |
194 | | - |
| 161 | + |
195 | 162 | // Set loading state to true to trigger the processing UI |
196 | 163 | chatStore.isLoading = true; |
197 | | - |
| 164 | + |
198 | 165 | // Simulate the processing state hook behavior |
199 | 166 | // This will show the "Generating..." text and parameter details |
200 | | - await new Promise(resolve => setTimeout(resolve, 100)); |
201 | | - }} |
202 | | -/> |
203 | | - |
204 | | -<Story |
205 | | - name="ThinkTagFormat" |
206 | | - args={{ |
207 | | - class: 'max-w-[56rem] w-[calc(100vw-2rem)]', |
208 | | - message: thinkTagMessage |
| 167 | + await new Promise((resolve) => setTimeout(resolve, 100)); |
209 | 168 | }} |
210 | 169 | /> |
211 | | - |
212 | | -<Story |
213 | | - name="ThinkBracketFormat" |
214 | | - args={{ |
215 | | - class: 'max-w-[56rem] w-[calc(100vw-2rem)]', |
216 | | - message: thinkBracketMessage |
217 | | - }} |
218 | | -/> |
219 | | - |
220 | | -<Story |
221 | | - name="StreamingThinkTag" |
222 | | - args={{ |
223 | | - message: streamingThinkMessage |
224 | | - }} |
225 | | - parameters={{ |
226 | | - test: { |
227 | | - timeout: 30000 |
228 | | - } |
229 | | - }} |
230 | | - asChild |
231 | | - play={async () => { |
232 | | - // Phase 1: Stream reasoning content |
233 | | - const thinkingContent = |
234 | | - 'Let me work through this problem systematically:\n\n1. First, I need to understand what the user is asking\n2. Then I should consider different approaches\n3. I need to evaluate the pros and cons\n4. Finally, I should provide a clear recommendation\n\nThis step-by-step approach will ensure accuracy.'; |
235 | | - |
236 | | - streamingThinkMessage.thinking = ''; |
237 | | - streamingThinkMessage.content = ''; |
238 | | - |
239 | | - for (let i = 0; i < thinkingContent.length; i++) { |
240 | | - streamingThinkMessage.thinking += thinkingContent[i]; |
241 | | - await new Promise((resolve) => setTimeout(resolve, 5)); |
242 | | - } |
243 | | - |
244 | | - await new Promise((resolve) => setTimeout(resolve, 200)); |
245 | | - |
246 | | - // Phase 2: Stream main response content |
247 | | - const responseContent = |
248 | | - "Based on my analysis above, here's the solution:\n\n**Key Points:**\n- The approach should be systematic\n- We need to consider all factors\n- Implementation should be step-by-step\n\nThis ensures the best possible outcome."; |
249 | | - |
250 | | - let currentContent = ''; |
251 | | - |
252 | | - for (let i = 0; i < responseContent.length; i++) { |
253 | | - currentContent += responseContent[i]; |
254 | | - streamingThinkMessage.content = currentContent; |
255 | | - await new Promise((resolve) => setTimeout(resolve, 10)); |
256 | | - } |
257 | | - |
258 | | - streamingThinkMessage.timestamp = Date.now(); |
259 | | - }} |
260 | | -> |
261 | | - <div class="w-[56rem]"> |
262 | | - <ChatMessage message={streamingThinkMessage} /> |
263 | | - </div> |
264 | | -</Story> |
265 | | - |
266 | | -<Story |
267 | | - name="StreamingThinkBracket" |
268 | | - args={{ |
269 | | - message: streamingBracketMessage |
270 | | - }} |
271 | | - parameters={{ |
272 | | - test: { |
273 | | - timeout: 30000 |
274 | | - } |
275 | | - }} |
276 | | - asChild |
277 | | - play={async () => { |
278 | | - // Phase 1: Stream DeepSeek-style reasoning content |
279 | | - const thinkingContent = |
280 | | - 'Using the DeepSeek format now:\n\n- This demonstrates the [THINK] bracket format\n- Should behave identically to the <think> format\n- The UI should display this in the thinking section\n- Main content should be separate\n\nBoth formats provide the same functionality.'; |
281 | | - |
282 | | - streamingBracketMessage.thinking = ''; |
283 | | - streamingBracketMessage.content = ''; |
284 | | - |
285 | | - for (let i = 0; i < thinkingContent.length; i++) { |
286 | | - streamingBracketMessage.thinking += thinkingContent[i]; |
287 | | - await new Promise((resolve) => setTimeout(resolve, 5)); |
288 | | - } |
289 | | - |
290 | | - await new Promise((resolve) => setTimeout(resolve, 200)); |
291 | | - |
292 | | - // Phase 2: Stream main response content |
293 | | - const responseContent = |
294 | | - "Here's my response after using the [THINK] format:\n\n**Observations:**\n- Both <think> and [THINK] formats work seamlessly\n- The helper logic handles both cases\n- UI display is consistent across formats\n\nThis demonstrates the enhanced thinking content support."; |
295 | | - |
296 | | - let currentContent = ''; |
297 | | - |
298 | | - for (let i = 0; i < responseContent.length; i++) { |
299 | | - currentContent += responseContent[i]; |
300 | | - streamingBracketMessage.content = currentContent; |
301 | | - await new Promise((resolve) => setTimeout(resolve, 10)); |
302 | | - } |
303 | | - |
304 | | - streamingBracketMessage.timestamp = Date.now(); |
305 | | - }} |
306 | | -> |
307 | | - <div class="w-[56rem]"> |
308 | | - <ChatMessage message={streamingBracketMessage} /> |
309 | | - </div> |
310 | | -</Story> |
0 commit comments