|
@@ -36,64 +36,36 @@
|
|
|
children: []
|
|
children: []
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- let processingMessage = $state({
|
|
|
|
|
- id: '4',
|
|
|
|
|
- convId: 'conv-1',
|
|
|
|
|
- type: 'message',
|
|
|
|
|
- timestamp: 0, // No timestamp = processing
|
|
|
|
|
- role: 'assistant',
|
|
|
|
|
- content: '',
|
|
|
|
|
- parent: '1',
|
|
|
|
|
- thinking: '',
|
|
|
|
|
- children: []
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- let streamingMessage = $state({
|
|
|
|
|
- id: '5',
|
|
|
|
|
- convId: 'conv-1',
|
|
|
|
|
- type: 'message',
|
|
|
|
|
- timestamp: 0, // No timestamp = streaming
|
|
|
|
|
- role: 'assistant',
|
|
|
|
|
- content: '',
|
|
|
|
|
- parent: '1',
|
|
|
|
|
- thinking: '',
|
|
|
|
|
- children: []
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // Message with <think> format thinking content
|
|
|
|
|
- const thinkTagMessage: DatabaseMessage = {
|
|
|
|
|
- id: '6',
|
|
|
|
|
|
|
+ const assistantWithReasoning: DatabaseMessage = {
|
|
|
|
|
+ id: '3',
|
|
|
convId: 'conv-1',
|
|
convId: 'conv-1',
|
|
|
type: 'message',
|
|
type: 'message',
|
|
|
timestamp: Date.now() - 1000 * 60 * 2,
|
|
timestamp: Date.now() - 1000 * 60 * 2,
|
|
|
role: 'assistant',
|
|
role: 'assistant',
|
|
|
- content:
|
|
|
|
|
- "<think>\nLet 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.\n</think>\n\nHere's my response after thinking through the problem. The thinking content above should be displayed separately from this main response content.",
|
|
|
|
|
|
|
+ content: "Here's the concise answer, now that I've thought it through carefully for you.",
|
|
|
parent: '1',
|
|
parent: '1',
|
|
|
- thinking: '',
|
|
|
|
|
|
|
+ thinking:
|
|
|
|
|
+ "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.",
|
|
|
children: []
|
|
children: []
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
- // Message with [THINK] format thinking content
|
|
|
|
|
- const thinkBracketMessage: DatabaseMessage = {
|
|
|
|
|
- id: '7',
|
|
|
|
|
|
|
+ const rawOutputMessage: DatabaseMessage = {
|
|
|
|
|
+ id: '6',
|
|
|
convId: 'conv-1',
|
|
convId: 'conv-1',
|
|
|
type: 'message',
|
|
type: 'message',
|
|
|
- timestamp: Date.now() - 1000 * 60 * 1,
|
|
|
|
|
|
|
+ timestamp: Date.now() - 1000 * 60,
|
|
|
role: 'assistant',
|
|
role: 'assistant',
|
|
|
content:
|
|
content:
|
|
|
- '[THINK]\nThis is the DeepSeek-style thinking format:\n\n- Using square brackets instead of angle brackets\n- Should work identically to the <think> format\n- Content parsing should extract this reasoning\n- Display should be the same as <think> format\n\nBoth formats should be supported seamlessly.\n[/THINK]\n\nThis is the main response content that comes after the [THINK] block. The reasoning above should be parsed and displayed in the thinking section.',
|
|
|
|
|
|
|
+ '<|channel|>analysis<|message|>User greeted me. Initiating overcomplicated analysis: Is this a trap? No, just a normal hello. Respond calmly, act like a helpful assistant, and do not start explaining quantum physics again. Confidence 0.73. Engaging socially acceptable greeting protocol...<|end|>Hello there! How can I help you today?',
|
|
|
parent: '1',
|
|
parent: '1',
|
|
|
thinking: '',
|
|
thinking: '',
|
|
|
children: []
|
|
children: []
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- // Streaming message for <think> format
|
|
|
|
|
- let streamingThinkMessage = $state({
|
|
|
|
|
- id: '8',
|
|
|
|
|
|
|
+ let processingMessage = $state({
|
|
|
|
|
+ id: '4',
|
|
|
convId: 'conv-1',
|
|
convId: 'conv-1',
|
|
|
type: 'message',
|
|
type: 'message',
|
|
|
- timestamp: 0, // No timestamp = streaming
|
|
|
|
|
|
|
+ timestamp: 0, // No timestamp = processing
|
|
|
role: 'assistant',
|
|
role: 'assistant',
|
|
|
content: '',
|
|
content: '',
|
|
|
parent: '1',
|
|
parent: '1',
|
|
@@ -101,9 +73,8 @@
|
|
|
children: []
|
|
children: []
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- // Streaming message for [THINK] format
|
|
|
|
|
- let streamingBracketMessage = $state({
|
|
|
|
|
- id: '9',
|
|
|
|
|
|
|
+ let streamingMessage = $state({
|
|
|
|
|
+ id: '5',
|
|
|
convId: 'conv-1',
|
|
convId: 'conv-1',
|
|
|
type: 'message',
|
|
type: 'message',
|
|
|
timestamp: 0, // No timestamp = streaming
|
|
timestamp: 0, // No timestamp = streaming
|
|
@@ -120,6 +91,10 @@
|
|
|
args={{
|
|
args={{
|
|
|
message: userMessage
|
|
message: userMessage
|
|
|
}}
|
|
}}
|
|
|
|
|
+ play={async () => {
|
|
|
|
|
+ const { updateConfig } = await import('$lib/stores/settings.svelte');
|
|
|
|
|
+ updateConfig('disableReasoningFormat', false);
|
|
|
|
|
+ }}
|
|
|
/>
|
|
/>
|
|
|
|
|
|
|
|
<Story
|
|
<Story
|
|
@@ -128,15 +103,45 @@
|
|
|
class: 'max-w-[56rem] w-[calc(100vw-2rem)]',
|
|
class: 'max-w-[56rem] w-[calc(100vw-2rem)]',
|
|
|
message: assistantMessage
|
|
message: assistantMessage
|
|
|
}}
|
|
}}
|
|
|
|
|
+ play={async () => {
|
|
|
|
|
+ const { updateConfig } = await import('$lib/stores/settings.svelte');
|
|
|
|
|
+ updateConfig('disableReasoningFormat', false);
|
|
|
|
|
+ }}
|
|
|
|
|
+/>
|
|
|
|
|
+
|
|
|
|
|
+<Story
|
|
|
|
|
+ name="AssistantWithReasoning"
|
|
|
|
|
+ args={{
|
|
|
|
|
+ class: 'max-w-[56rem] w-[calc(100vw-2rem)]',
|
|
|
|
|
+ message: assistantWithReasoning
|
|
|
|
|
+ }}
|
|
|
|
|
+ play={async () => {
|
|
|
|
|
+ const { updateConfig } = await import('$lib/stores/settings.svelte');
|
|
|
|
|
+ updateConfig('disableReasoningFormat', false);
|
|
|
|
|
+ }}
|
|
|
|
|
+/>
|
|
|
|
|
+
|
|
|
|
|
+<Story
|
|
|
|
|
+ name="RawLlmOutput"
|
|
|
|
|
+ args={{
|
|
|
|
|
+ class: 'max-w-[56rem] w-[calc(100vw-2rem)]',
|
|
|
|
|
+ message: rawOutputMessage
|
|
|
|
|
+ }}
|
|
|
|
|
+ play={async () => {
|
|
|
|
|
+ const { updateConfig } = await import('$lib/stores/settings.svelte');
|
|
|
|
|
+ updateConfig('disableReasoningFormat', true);
|
|
|
|
|
+ }}
|
|
|
/>
|
|
/>
|
|
|
|
|
|
|
|
<Story
|
|
<Story
|
|
|
- name="WithThinkingBlock"
|
|
|
|
|
|
|
+ name="WithReasoningContent"
|
|
|
args={{
|
|
args={{
|
|
|
message: streamingMessage
|
|
message: streamingMessage
|
|
|
}}
|
|
}}
|
|
|
asChild
|
|
asChild
|
|
|
play={async () => {
|
|
play={async () => {
|
|
|
|
|
+ const { updateConfig } = await import('$lib/stores/settings.svelte');
|
|
|
|
|
+ updateConfig('disableReasoningFormat', false);
|
|
|
// Phase 1: Stream reasoning content in chunks
|
|
// Phase 1: Stream reasoning content in chunks
|
|
|
let reasoningText =
|
|
let reasoningText =
|
|
|
'I need to think about this carefully. Let me break down the problem:\n\n1. The user is asking for help with something complex\n2. I should provide a thorough and helpful response\n3. I need to consider multiple approaches\n4. The best solution would be to explain step by step\n\nThis approach will ensure clarity and understanding.';
|
|
'I need to think about this carefully. Let me break down the problem:\n\n1. The user is asking for help with something complex\n2. I should provide a thorough and helpful response\n3. I need to consider multiple approaches\n4. The best solution would be to explain step by step\n\nThis approach will ensure clarity and understanding.';
|
|
@@ -187,126 +192,16 @@
|
|
|
message: processingMessage
|
|
message: processingMessage
|
|
|
}}
|
|
}}
|
|
|
play={async () => {
|
|
play={async () => {
|
|
|
|
|
+ const { updateConfig } = await import('$lib/stores/settings.svelte');
|
|
|
|
|
+ updateConfig('disableReasoningFormat', false);
|
|
|
// Import the chat store to simulate loading state
|
|
// Import the chat store to simulate loading state
|
|
|
const { chatStore } = await import('$lib/stores/chat.svelte');
|
|
const { chatStore } = await import('$lib/stores/chat.svelte');
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Set loading state to true to trigger the processing UI
|
|
// Set loading state to true to trigger the processing UI
|
|
|
chatStore.isLoading = true;
|
|
chatStore.isLoading = true;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Simulate the processing state hook behavior
|
|
// Simulate the processing state hook behavior
|
|
|
// This will show the "Generating..." text and parameter details
|
|
// This will show the "Generating..." text and parameter details
|
|
|
- await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
|
- }}
|
|
|
|
|
-/>
|
|
|
|
|
-
|
|
|
|
|
-<Story
|
|
|
|
|
- name="ThinkTagFormat"
|
|
|
|
|
- args={{
|
|
|
|
|
- class: 'max-w-[56rem] w-[calc(100vw-2rem)]',
|
|
|
|
|
- message: thinkTagMessage
|
|
|
|
|
|
|
+ await new Promise((resolve) => setTimeout(resolve, 100));
|
|
|
}}
|
|
}}
|
|
|
/>
|
|
/>
|
|
|
-
|
|
|
|
|
-<Story
|
|
|
|
|
- name="ThinkBracketFormat"
|
|
|
|
|
- args={{
|
|
|
|
|
- class: 'max-w-[56rem] w-[calc(100vw-2rem)]',
|
|
|
|
|
- message: thinkBracketMessage
|
|
|
|
|
- }}
|
|
|
|
|
-/>
|
|
|
|
|
-
|
|
|
|
|
-<Story
|
|
|
|
|
- name="StreamingThinkTag"
|
|
|
|
|
- args={{
|
|
|
|
|
- message: streamingThinkMessage
|
|
|
|
|
- }}
|
|
|
|
|
- parameters={{
|
|
|
|
|
- test: {
|
|
|
|
|
- timeout: 30000
|
|
|
|
|
- }
|
|
|
|
|
- }}
|
|
|
|
|
- asChild
|
|
|
|
|
- play={async () => {
|
|
|
|
|
- // Phase 1: Stream <think> reasoning content
|
|
|
|
|
- const thinkingContent =
|
|
|
|
|
- '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.';
|
|
|
|
|
-
|
|
|
|
|
- let currentContent = '<think>\n';
|
|
|
|
|
- streamingThinkMessage.content = currentContent;
|
|
|
|
|
-
|
|
|
|
|
- for (let i = 0; i < thinkingContent.length; i++) {
|
|
|
|
|
- currentContent += thinkingContent[i];
|
|
|
|
|
- streamingThinkMessage.content = currentContent;
|
|
|
|
|
- await new Promise((resolve) => setTimeout(resolve, 5));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Close the thinking block
|
|
|
|
|
- currentContent += '\n</think>\n\n';
|
|
|
|
|
- streamingThinkMessage.content = currentContent;
|
|
|
|
|
- await new Promise((resolve) => setTimeout(resolve, 200));
|
|
|
|
|
-
|
|
|
|
|
- // Phase 2: Stream main response content
|
|
|
|
|
- const responseContent =
|
|
|
|
|
- "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.";
|
|
|
|
|
-
|
|
|
|
|
- for (let i = 0; i < responseContent.length; i++) {
|
|
|
|
|
- currentContent += responseContent[i];
|
|
|
|
|
- streamingThinkMessage.content = currentContent;
|
|
|
|
|
- await new Promise((resolve) => setTimeout(resolve, 10));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- streamingThinkMessage.timestamp = Date.now();
|
|
|
|
|
- }}
|
|
|
|
|
->
|
|
|
|
|
- <div class="w-[56rem]">
|
|
|
|
|
- <ChatMessage message={streamingThinkMessage} />
|
|
|
|
|
- </div>
|
|
|
|
|
-</Story>
|
|
|
|
|
-
|
|
|
|
|
-<Story
|
|
|
|
|
- name="StreamingThinkBracket"
|
|
|
|
|
- args={{
|
|
|
|
|
- message: streamingBracketMessage
|
|
|
|
|
- }}
|
|
|
|
|
- parameters={{
|
|
|
|
|
- test: {
|
|
|
|
|
- timeout: 30000
|
|
|
|
|
- }
|
|
|
|
|
- }}
|
|
|
|
|
- asChild
|
|
|
|
|
- play={async () => {
|
|
|
|
|
- // Phase 1: Stream [THINK] reasoning content
|
|
|
|
|
- const thinkingContent =
|
|
|
|
|
- 'Using the DeepSeek format now:\n\n- This demonstrates the [THINK] bracket format\n- Should parse identically to <think> tags\n- The UI should display this in the thinking section\n- Main content should be separate\n\nBoth formats provide the same functionality.';
|
|
|
|
|
-
|
|
|
|
|
- let currentContent = '[THINK]\n';
|
|
|
|
|
- streamingBracketMessage.content = currentContent;
|
|
|
|
|
-
|
|
|
|
|
- for (let i = 0; i < thinkingContent.length; i++) {
|
|
|
|
|
- currentContent += thinkingContent[i];
|
|
|
|
|
- streamingBracketMessage.content = currentContent;
|
|
|
|
|
- await new Promise((resolve) => setTimeout(resolve, 5));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Close the thinking block
|
|
|
|
|
- currentContent += '\n[/THINK]\n\n';
|
|
|
|
|
- streamingBracketMessage.content = currentContent;
|
|
|
|
|
- await new Promise((resolve) => setTimeout(resolve, 200));
|
|
|
|
|
-
|
|
|
|
|
- // Phase 2: Stream main response content
|
|
|
|
|
- const responseContent =
|
|
|
|
|
- "Here's my response after using the [THINK] format:\n\n**Observations:**\n- Both <think> and [THINK] formats work seamlessly\n- The parsing logic handles both cases\n- UI display is consistent across formats\n\nThis demonstrates the enhanced thinking content support.";
|
|
|
|
|
-
|
|
|
|
|
- for (let i = 0; i < responseContent.length; i++) {
|
|
|
|
|
- currentContent += responseContent[i];
|
|
|
|
|
- streamingBracketMessage.content = currentContent;
|
|
|
|
|
- await new Promise((resolve) => setTimeout(resolve, 10));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- streamingBracketMessage.timestamp = Date.now();
|
|
|
|
|
- }}
|
|
|
|
|
->
|
|
|
|
|
- <div class="w-[56rem]">
|
|
|
|
|
- <ChatMessage message={streamingBracketMessage} />
|
|
|
|
|
- </div>
|
|
|
|
|
-</Story>
|
|
|