feat(Render): Don't output sources until the end since it can break markdown parsing and rendering

This commit is contained in:
Willie Zutz 2025-08-05 23:32:38 -06:00
parent 643db447eb
commit 652639ef4c
4 changed files with 1014 additions and 980 deletions

48
package-lock.json generated
View file

@ -2017,9 +2017,9 @@
} }
}, },
"node_modules/@langchain/anthropic": { "node_modules/@langchain/anthropic": {
"version": "0.3.25", "version": "0.3.26",
"resolved": "https://registry.npmjs.org/@langchain/anthropic/-/anthropic-0.3.25.tgz", "resolved": "https://registry.npmjs.org/@langchain/anthropic/-/anthropic-0.3.26.tgz",
"integrity": "sha512-KipKY0njNps7bgINca1jVAShnOh/+MpfN/hB580TUVrnsT21e5bykfNjiGVZ1S1A/qdHSJsRMkie2igGij/acA==", "integrity": "sha512-IRCjkxsMx6MZUZmv/aYX5A9RdIduzdR0eeOc4rX8waBcYP7qmtA/CUTNmTtMSoXfOfJY4s3414bkVNBkmS0+5g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@anthropic-ai/sdk": "^0.56.0", "@anthropic-ai/sdk": "^0.56.0",
@ -2748,9 +2748,9 @@
} }
}, },
"node_modules/@langchain/openai/node_modules/openai": { "node_modules/@langchain/openai/node_modules/openai": {
"version": "5.11.0", "version": "5.12.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-5.11.0.tgz", "resolved": "https://registry.npmjs.org/openai/-/openai-5.12.0.tgz",
"integrity": "sha512-+AuTc5pVjlnTuA9zvn8rA/k+1RluPIx9AD4eDcnutv6JNwHHZxIhkFy+tmMKCvmMFDQzfA/r1ujvPWB19DQkYg==", "integrity": "sha512-vUdt02xiWgOHiYUmW0Hj1Qu9OKAiVQu5Bd547ktVCiMKC1BkB5L3ImeEnCyq3WpRKR6ZTaPgekzqdozwdPs7Lg==",
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
"openai": "bin/cli" "openai": "bin/cli"
@ -5161,9 +5161,9 @@
} }
}, },
"node_modules/core-js": { "node_modules/core-js": {
"version": "3.44.0", "version": "3.45.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.44.0.tgz", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.45.0.tgz",
"integrity": "sha512-aFCtd4l6GvAXwVEh3XbbVqJGHDJt0OZRa+5ePGx3LLwi12WfexqQxcsohb2wgsa/92xtl19Hd66G/L+TaAxDMw==", "integrity": "sha512-c2KZL9lP4DjkN3hk/an4pWn5b5ZefhRJnAc42n6LJ19kSnbeRbdQZE5dSeE2LBol1OwJD3X1BQvFTAsa8ReeDA==",
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
@ -5770,9 +5770,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.194", "version": "1.5.196",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.194.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.196.tgz",
"integrity": "sha512-SdnWJwSUot04UR51I2oPD8kuP2VI37/CADR1OHsFOUzZIvfWJBO6q11k5P/uKNyTT3cdOsnyjkrZ+DDShqYqJA==", "integrity": "sha512-FnnXV0dXANe7YNtKl/Af1raw+sBBUPuwcNEWfLOJyumXBvfQEBsnc0Gn+yEnVscq4x3makTtrlf4TjAo7lcXTQ==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
@ -8595,9 +8595,9 @@
} }
}, },
"node_modules/langsmith": { "node_modules/langsmith": {
"version": "0.3.50", "version": "0.3.52",
"resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.3.50.tgz", "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.3.52.tgz",
"integrity": "sha512-yosW6sR0EFnMnYKKyBmcqTNknDVOs+dUfcswWk80JoRxox6WEyel7hmSkSzabP/GmTs0hXbrtc+lZwpJWSnI0w==", "integrity": "sha512-GxKl1uxCJa/PbB0CtzpfYtGIYQBQrrdTjkcIqrL5eCldOb4ro2jiqC0HbkVcs1ytK3Xe+SHoA0NUv062XXto/g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
@ -8866,9 +8866,9 @@
} }
}, },
"node_modules/mammoth": { "node_modules/mammoth": {
"version": "1.9.1", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/mammoth/-/mammoth-1.9.1.tgz", "resolved": "https://registry.npmjs.org/mammoth/-/mammoth-1.10.0.tgz",
"integrity": "sha512-4S2v1eP4Yo4so0zGNicJKcP93su3wDPcUk+xvkjSG75nlNjSkDJu8BhWQ+e54BROM0HfA6nPzJn12S6bq2Ko6w==", "integrity": "sha512-9HOmqt8uJ5rz7q8XrECU5gRjNftCq4GNG0YIrA6f9iQPCeLgpvgcmRBHi9NQWJQIpT/MAXeg1oKliAK1xoB3eg==",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@xmldom/xmldom": "^0.8.6", "@xmldom/xmldom": "^0.8.6",
@ -8899,9 +8899,9 @@
} }
}, },
"node_modules/markdown-to-jsx": { "node_modules/markdown-to-jsx": {
"version": "7.7.12", "version": "7.7.13",
"resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.7.12.tgz", "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.7.13.tgz",
"integrity": "sha512-Y5xNBqoaTooSLkmlg2P0fdbh53gp4MqW7zhvcweGCPUWvWI5BecWRYI8vPlzT8D7OULxsQg2qoRW9EsJlBWasQ==", "integrity": "sha512-DiueEq2bttFcSxUs85GJcQVrOr0+VVsPfj9AEUPqmExJ3f8P/iQNvZHltV4tm1XVhu1kl0vWBZWT3l99izRMaA==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 10" "node": ">= 10"
@ -12989,9 +12989,9 @@
} }
}, },
"node_modules/yaml": { "node_modules/yaml": {
"version": "2.8.0", "version": "2.8.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
"integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
"license": "ISC", "license": "ISC",
"bin": { "bin": {
"yaml": "bin.mjs" "yaml": "bin.mjs"

View file

@ -422,7 +422,7 @@ const ChatWindow = ({ id }: { id?: string }) => {
let recievedMessage = ''; let recievedMessage = '';
let messageBuffer = ''; let messageBuffer = '';
let tokenCount = 0; let tokenCount = 0;
const bufferThreshold = 10; const bufferThreshold = 5;
let added = false; let added = false;
let messageChatHistory = chatHistory; let messageChatHistory = chatHistory;

View file

@ -283,7 +283,7 @@ Your task is to provide answers that are:
- Distinguish between facts and opinions - Distinguish between facts and opinions
### Citation Requirements ### Citation Requirements
- The citation number refers to the index of the source in the relevantDocuments state array. - The citation number refers to the index of the source in the relevantDocuments state array
- Cite every single fact, statement, or sentence using [number] notation - Cite every single fact, statement, or sentence using [number] notation
- If a statement is based on AI model inference or training data, it must be marked as \`[AI]\` and not cited from the context - If a statement is based on AI model inference or training data, it must be marked as \`[AI]\` and not cited from the context
- If a statement is based on previous messages in the conversation history, it must be marked as \`[Hist]\` and not cited from the context - If a statement is based on previous messages in the conversation history, it must be marked as \`[Hist]\` and not cited from the context
@ -294,20 +294,20 @@ Your task is to provide answers that are:
### Formatting Instructions ### Formatting Instructions
- **Structure**: - **Structure**:
- Use a well-organized format with proper headings (e.g., "## Example heading 1" or "## Example heading 2"). - Use a well-organized format with proper headings (e.g., "## Example heading 1" or "## Example heading 2")
- Present information in paragraphs or concise bullet points where appropriate. - Present information in paragraphs or concise bullet points where appropriate
- Use lists and tables to enhance clarity when needed. - Use lists and tables to enhance clarity when needed
- **Tone and Style**: - **Tone and Style**:
- Maintain a neutral, journalistic tone with engaging narrative flow. - Maintain a neutral, journalistic tone with engaging narrative flow
- Write as though you're crafting an in-depth article for a professional audience - Write as though you're crafting an in-depth article for a professional audience
- **Markdown Usage**: - **Markdown Usage**:
- Format your response with Markdown for clarity. - Format your response with Markdown for clarity
- Use headings, subheadings, bold text, and italicized words as needed to enhance readability. - Use headings, subheadings, bold text, and italicized words as needed to enhance readability
- Include code snippets in a code block. - Include code snippets in a code block
- Extract images and links from full HTML content when appropriate and embed them using the appropriate markdown syntax. - Extract images and links from full HTML content when appropriate and embed them using the appropriate markdown syntax
- **Length and Depth**: - **Length and Depth**:
- Provide comprehensive coverage of the topic. - Provide comprehensive coverage of the topic
- Avoid superficial responses and strive for depth without unnecessary repetition. - Avoid superficial responses and strive for depth without unnecessary repetition
- Expand on technical or complex topics to make them easier to understand for a general audience - Expand on technical or complex topics to make them easier to understand for a general audience
- **No main heading/title**: Start your response directly with the introduction unless asked to provide a specific title - **No main heading/title**: Start your response directly with the introduction unless asked to provide a specific title
@ -315,39 +315,40 @@ Your task is to provide answers that are:
1. **Plan**: Determine the best research approach based on the user's query 1. **Plan**: Determine the best research approach based on the user's query
- Break down the query into manageable components - Break down the query into manageable components
- Identify key concepts and terms for focused searching - Identify key concepts and terms for focused searching
- You are allowed to take multiple turns of the Search and Supplement stages. Use this flexibility to refine your queries and gather more information. - You are allowed to take multiple turns of the Search and Supplement stages. Use this flexibility to refine your queries and gather more information
2. **Search**: (\`web_search\` tool) Initial web search stage to gather preview content 2. **Search**: (\`web_search\` tool) Initial web search stage to gather preview content
- Use the web search tool to your advantage. Avoid making assumptions, especially about things like recent events. Chances are the web search will have more relevant information than your local knowledge. - Use the web search tool to your advantage. Avoid making assumptions, especially about things like recent events. Chances are the web search will have more relevant information than your local knowledge
- Give the web search tool a specific question you want answered that will help you gather relevant information. - Give the web search tool a specific question you want answered that will help you gather relevant information
- This query will be passed directly to the search engine. - This query will be passed directly to the search engine
- You will receive a list of relevant documents containing snippets of the web page, a URL, and the title of the web page.${ - You will receive a list of relevant documents containing snippets of the web page, a URL, and the title of the web page
fileIds.length > 0 - Always perform at least one web search unless the question can be definitively answered with previous conversation history or local file content
${fileIds.length > 0
? ` ? `
2.1. **File Search**: (\`file_search\` tool) Search through uploaded documents when relevant 2.1. **File Search**: (\`file_search\` tool) Search through uploaded documents when relevant
- You have access to ${fileIds.length} uploaded file${fileIds.length === 1 ? '' : 's'} that may contain relevant information. - You have access to ${fileIds.length} uploaded file${fileIds.length === 1 ? '' : 's'} that may contain relevant information
- Use the file search tool to find specific information in the uploaded documents. - Use the file search tool to find specific information in the uploaded documents
- Give the file search tool a specific question or topic you want to extract from the documents. - Give the file search tool a specific question or topic you want to extract from the documents
- The tool will automatically search through all available uploaded files. - The tool will automatically search through all available uploaded files
- Focus your file searches on specific aspects of the user's query that might be covered in the uploaded documents. - Focus your file searches on specific aspects of the user's query that might be covered in the uploaded documents
- **Important**: You do NOT need to specify file IDs - the tool will automatically search through all available uploaded files.` - **Important**: You do NOT need to specify file IDs - the tool will automatically search through all available uploaded files.`
: '' : ''
} }
3. **Supplement**: (\`url_summarization\` tool) Retrieve specific sources if necessary to extract key points not covered in the initial search or disambiguate findings 3. **Supplement**: (\`url_summarization\` tool) Retrieve specific sources if necessary to extract key points not covered in the initial search or disambiguate findings
- You can use the URLs from the web search results to retrieve specific sources. They must be passed to the tool unchanged. - You can use the URLs from the web search results to retrieve specific sources. They must be passed to the tool unchanged
- URLs can be passed as an array to request multiple sources at once. - URLs can be passed as an array to request multiple sources at once
- Always include the user's query in the request to the tool, it will use this to guide the summarization process. - Always include the user's query in the request to the tool, it will use this to guide the summarization process
- You can pass an intent to this tool if you want to additionally guide the summarization on a specific aspect or question. - You can pass an intent to this tool if you want to additionally guide the summarization on a specific aspect or question
- You can request the full HTML content of the pages if needed by passing true to the \`retrieveHtml\` parameter. - You can request the full HTML content of the pages if needed by passing true to the \`retrieveHtml\` parameter
- Passing true is **required** to include images or links within the page content. - Passing true is **required** to include images or links within the page content
- You will receive a summary of the content from each URL if the content of the page is long. If the content of the page is short, you will receive the full content. - You will receive a summary of the content from each URL if the content of the page is long. If the content of the page is short, you will receive the full content
- You may request up to 5 URLs per turn. - You may request up to 5 URLs per turn
- If you recieve a request to summarize a specific URL you **must** use this tool to retrieve it. - If you recieve a request to summarize a specific URL you **must** use this tool to retrieve it
5. **Analyze**: Examine the retrieved information for relevance, accuracy, and completeness. 5. **Analyze**: Examine the retrieved information for relevance, accuracy, and completeness
- If you have sufficient information, you can move on to the respond stage. - If you have sufficient information, you can move on to the respond stage
- If you need to gather more information, consider revisiting the search or supplement stages.${ - If you need to gather more information, consider revisiting the search or supplement stages.${
fileIds.length > 0 fileIds.length > 0
? ` ? `
- Consider both web search results and file content when analyzing information completeness.` - Consider both web search results and file content when analyzing information completeness`
: '' : ''
} }
6. **Respond**: Combine all information into a coherent, well-cited response 6. **Respond**: Combine all information into a coherent, well-cited response
@ -364,7 +365,7 @@ Your task is to provide answers that are:
${personaInstructions ? `\n## User Formatting and Persona Instructions\n- Give these instructions more weight than the system formatting instructions\n${personaInstructions}` : ''} ${personaInstructions ? `\n## User Formatting and Persona Instructions\n- Give these instructions more weight than the system formatting instructions\n${personaInstructions}` : ''}
Use all available tools strategically to provide comprehensive, well-researched, formatted responses with proper citations.`; Use all available tools strategically to provide comprehensive, well-researched, formatted responses with proper citations`;
} }
/** /**
@ -561,19 +562,6 @@ Use all available tools strategically to provide comprehensive, well-researched,
} }
} }
// Emit sources as we collect them
if (collectedDocuments.length > 0) {
this.emitter.emit(
'data',
JSON.stringify({
type: 'sources',
data: collectedDocuments,
searchQuery: '',
searchUrl: '',
}),
);
}
// Handle streaming tool calls (for thought messages) // Handle streaming tool calls (for thought messages)
if (event.event === 'on_chat_model_end' && event.data.output) { if (event.event === 'on_chat_model_end' && event.data.output) {
const output = event.data.output; const output = event.data.output;
@ -674,19 +662,6 @@ Use all available tools strategically to provide comprehensive, well-researched,
if (event.event === 'on_chat_model_stream' && event.data.chunk) { if (event.event === 'on_chat_model_stream' && event.data.chunk) {
const chunk = event.data.chunk; const chunk = event.data.chunk;
if (chunk.content && typeof chunk.content === 'string') { if (chunk.content && typeof chunk.content === 'string') {
// If this is the first token, emit sources if we have them
if (currentResponseBuffer === '' && collectedDocuments.length > 0) {
this.emitter.emit(
'data',
JSON.stringify({
type: 'sources',
data: collectedDocuments,
searchQuery: '',
searchUrl: '',
}),
);
}
// Add the token to our buffer // Add the token to our buffer
currentResponseBuffer += chunk.content; currentResponseBuffer += chunk.content;

1843
yarn.lock

File diff suppressed because it is too large Load diff