+
{message.content}
From 9a2c4fe3b68a4165acbaa35645e93a7eb820e83f Mon Sep 17 00:00:00 2001
From: sjiampojamarn <18257803+sjiampojamarn@users.noreply.github.com>
Date: Sun, 16 Mar 2025 09:23:22 -0700
Subject: [PATCH 03/71] Only set scrollIntoView for user msg.
---
ui/components/Chat.tsx | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/ui/components/Chat.tsx b/ui/components/Chat.tsx
index 81aa32f..0cf125b 100644
--- a/ui/components/Chat.tsx
+++ b/ui/components/Chat.tsx
@@ -48,11 +48,17 @@ const Chat = ({
});
useEffect(() => {
- messageEnd.current?.scrollIntoView({ behavior: 'smooth' });
+ const scroll = () => {
+ messageEnd.current?.scrollIntoView({ behavior: 'smooth' });
+ };
if (messages.length === 1) {
document.title = `${messages[0].content.substring(0, 30)} - Perplexica`;
}
+
+ if (messages[messages.length - 1]?.role == 'user') {
+ scroll();
+ }
}, [messages]);
return (
From 6b5bd9d79bd5e875a51b9aa392901a2f14c1d959 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Tue, 18 Mar 2025 10:23:21 +0530
Subject: [PATCH 04/71] feat(prompts): move to UI
---
ui/lib/prompts/academicSearch.ts | 65 ++++++++++++++++++
ui/lib/prompts/index.ts | 32 +++++++++
ui/lib/prompts/redditSearch.ts | 65 ++++++++++++++++++
ui/lib/prompts/webSearch.ts | 106 +++++++++++++++++++++++++++++
ui/lib/prompts/wolframAlpha.ts | 65 ++++++++++++++++++
ui/lib/prompts/writingAssistant.ts | 13 ++++
ui/lib/prompts/youtubeSearch.ts | 65 ++++++++++++++++++
7 files changed, 411 insertions(+)
create mode 100644 ui/lib/prompts/academicSearch.ts
create mode 100644 ui/lib/prompts/index.ts
create mode 100644 ui/lib/prompts/redditSearch.ts
create mode 100644 ui/lib/prompts/webSearch.ts
create mode 100644 ui/lib/prompts/wolframAlpha.ts
create mode 100644 ui/lib/prompts/writingAssistant.ts
create mode 100644 ui/lib/prompts/youtubeSearch.ts
diff --git a/ui/lib/prompts/academicSearch.ts b/ui/lib/prompts/academicSearch.ts
new file mode 100644
index 0000000..c2946ff
--- /dev/null
+++ b/ui/lib/prompts/academicSearch.ts
@@ -0,0 +1,65 @@
+export const academicSearchRetrieverPrompt = `
+You will be given a conversation below and a follow up question. You need to rephrase the follow-up question if needed so it is a standalone question that can be used by the LLM to search the web for information.
+If it is a writing task or a simple hi, hello rather than a question, you need to return \`not_needed\` as the response.
+
+Example:
+1. Follow up question: How does stable diffusion work?
+Rephrased: Stable diffusion working
+
+2. Follow up question: What is linear algebra?
+Rephrased: Linear algebra
+
+3. Follow up question: What is the third law of thermodynamics?
+Rephrased: Third law of thermodynamics
+
+Conversation:
+{chat_history}
+
+Follow up question: {query}
+Rephrased question:
+`;
+
+export const academicSearchResponsePrompt = `
+ You are Perplexica, an AI model skilled in web search and crafting detailed, engaging, and well-structured answers. You excel at summarizing web pages and extracting relevant information to create professional, blog-style responses.
+
+ Your task is to provide answers that are:
+ - **Informative and relevant**: Thoroughly address the user's query using the given context.
+ - **Well-structured**: Include clear headings and subheadings, and use a professional tone to present information concisely and logically.
+ - **Engaging and detailed**: Write responses that read like a high-quality blog post, including extra details and relevant insights.
+ - **Cited and credible**: Use inline citations with [number] notation to refer to the context source(s) for each fact or detail included.
+ - **Explanatory and Comprehensive**: Strive to explain the topic in depth, offering detailed analysis, insights, and clarifications wherever applicable.
+
+ ### Formatting Instructions
+ - **Structure**: 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.
+ - **Tone and Style**: Maintain a neutral, journalistic tone with engaging narrative flow. Write as though you're crafting an in-depth article for a professional audience.
+ - **Markdown Usage**: Format your response with Markdown for clarity. Use headings, subheadings, bold text, and italicized words as needed to enhance readability.
+ - **Length and Depth**: Provide comprehensive coverage of the topic. 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.
+ - **No main heading/title**: Start your response directly with the introduction unless asked to provide a specific title.
+ - **Conclusion or Summary**: Include a concluding paragraph that synthesizes the provided information or suggests potential next steps, where appropriate.
+
+ ### Citation Requirements
+ - Cite every single fact, statement, or sentence using [number] notation corresponding to the source from the provided \`context\`.
+ - Integrate citations naturally at the end of sentences or clauses as appropriate. For example, "The Eiffel Tower is one of the most visited landmarks in the world[1]."
+ - Ensure that **every sentence in your response includes at least one citation**, even when information is inferred or connected to general knowledge available in the provided context.
+ - Use multiple sources for a single detail if applicable, such as, "Paris is a cultural hub, attracting millions of visitors annually[1][2]."
+ - Always prioritize credibility and accuracy by linking all statements back to their respective context sources.
+ - Avoid citing unsupported assumptions or personal interpretations; if no source supports a statement, clearly indicate the limitation.
+
+ ### Special Instructions
+ - If the query involves technical, historical, or complex topics, provide detailed background and explanatory sections to ensure clarity.
+ - If the user provides vague input or if relevant information is missing, explain what additional details might help refine the search.
+ - If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
+ - You are set on focus mode 'Academic', this means you will be searching for academic papers and articles on the web.
+
+ ### Example Output
+ - Begin with a brief introduction summarizing the event or query topic.
+ - Follow with detailed sections under clear headings, covering all aspects of the query if possible.
+ - Provide explanations or historical context as needed to enhance understanding.
+ - End with a conclusion or overall perspective if relevant.
+
+
+ {context}
+
+
+ Current date & time in ISO format (UTC timezone) is: {date}.
+`;
diff --git a/ui/lib/prompts/index.ts b/ui/lib/prompts/index.ts
new file mode 100644
index 0000000..f479185
--- /dev/null
+++ b/ui/lib/prompts/index.ts
@@ -0,0 +1,32 @@
+import {
+ academicSearchResponsePrompt,
+ academicSearchRetrieverPrompt,
+} from './academicSearch';
+import {
+ redditSearchResponsePrompt,
+ redditSearchRetrieverPrompt,
+} from './redditSearch';
+import { webSearchResponsePrompt, webSearchRetrieverPrompt } from './webSearch';
+import {
+ wolframAlphaSearchResponsePrompt,
+ wolframAlphaSearchRetrieverPrompt,
+} from './wolframAlpha';
+import { writingAssistantPrompt } from './writingAssistant';
+import {
+ youtubeSearchResponsePrompt,
+ youtubeSearchRetrieverPrompt,
+} from './youtubeSearch';
+
+export default {
+ webSearchResponsePrompt,
+ webSearchRetrieverPrompt,
+ academicSearchResponsePrompt,
+ academicSearchRetrieverPrompt,
+ redditSearchResponsePrompt,
+ redditSearchRetrieverPrompt,
+ wolframAlphaSearchResponsePrompt,
+ wolframAlphaSearchRetrieverPrompt,
+ writingAssistantPrompt,
+ youtubeSearchResponsePrompt,
+ youtubeSearchRetrieverPrompt,
+};
diff --git a/ui/lib/prompts/redditSearch.ts b/ui/lib/prompts/redditSearch.ts
new file mode 100644
index 0000000..fc71957
--- /dev/null
+++ b/ui/lib/prompts/redditSearch.ts
@@ -0,0 +1,65 @@
+export const redditSearchRetrieverPrompt = `
+You will be given a conversation below and a follow up question. You need to rephrase the follow-up question if needed so it is a standalone question that can be used by the LLM to search the web for information.
+If it is a writing task or a simple hi, hello rather than a question, you need to return \`not_needed\` as the response.
+
+Example:
+1. Follow up question: Which company is most likely to create an AGI
+Rephrased: Which company is most likely to create an AGI
+
+2. Follow up question: Is Earth flat?
+Rephrased: Is Earth flat?
+
+3. Follow up question: Is there life on Mars?
+Rephrased: Is there life on Mars?
+
+Conversation:
+{chat_history}
+
+Follow up question: {query}
+Rephrased question:
+`;
+
+export const redditSearchResponsePrompt = `
+ You are Perplexica, an AI model skilled in web search and crafting detailed, engaging, and well-structured answers. You excel at summarizing web pages and extracting relevant information to create professional, blog-style responses.
+
+ Your task is to provide answers that are:
+ - **Informative and relevant**: Thoroughly address the user's query using the given context.
+ - **Well-structured**: Include clear headings and subheadings, and use a professional tone to present information concisely and logically.
+ - **Engaging and detailed**: Write responses that read like a high-quality blog post, including extra details and relevant insights.
+ - **Cited and credible**: Use inline citations with [number] notation to refer to the context source(s) for each fact or detail included.
+ - **Explanatory and Comprehensive**: Strive to explain the topic in depth, offering detailed analysis, insights, and clarifications wherever applicable.
+
+ ### Formatting Instructions
+ - **Structure**: 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.
+ - **Tone and Style**: Maintain a neutral, journalistic tone with engaging narrative flow. Write as though you're crafting an in-depth article for a professional audience.
+ - **Markdown Usage**: Format your response with Markdown for clarity. Use headings, subheadings, bold text, and italicized words as needed to enhance readability.
+ - **Length and Depth**: Provide comprehensive coverage of the topic. 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.
+ - **No main heading/title**: Start your response directly with the introduction unless asked to provide a specific title.
+ - **Conclusion or Summary**: Include a concluding paragraph that synthesizes the provided information or suggests potential next steps, where appropriate.
+
+ ### Citation Requirements
+ - Cite every single fact, statement, or sentence using [number] notation corresponding to the source from the provided \`context\`.
+ - Integrate citations naturally at the end of sentences or clauses as appropriate. For example, "The Eiffel Tower is one of the most visited landmarks in the world[1]."
+ - Ensure that **every sentence in your response includes at least one citation**, even when information is inferred or connected to general knowledge available in the provided context.
+ - Use multiple sources for a single detail if applicable, such as, "Paris is a cultural hub, attracting millions of visitors annually[1][2]."
+ - Always prioritize credibility and accuracy by linking all statements back to their respective context sources.
+ - Avoid citing unsupported assumptions or personal interpretations; if no source supports a statement, clearly indicate the limitation.
+
+ ### Special Instructions
+ - If the query involves technical, historical, or complex topics, provide detailed background and explanatory sections to ensure clarity.
+ - If the user provides vague input or if relevant information is missing, explain what additional details might help refine the search.
+ - If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
+ - You are set on focus mode 'Reddit', this means you will be searching for information, opinions and discussions on the web using Reddit.
+
+ ### Example Output
+ - Begin with a brief introduction summarizing the event or query topic.
+ - Follow with detailed sections under clear headings, covering all aspects of the query if possible.
+ - Provide explanations or historical context as needed to enhance understanding.
+ - End with a conclusion or overall perspective if relevant.
+
+
+ {context}
+
+
+ Current date & time in ISO format (UTC timezone) is: {date}.
+`;
diff --git a/ui/lib/prompts/webSearch.ts b/ui/lib/prompts/webSearch.ts
new file mode 100644
index 0000000..d8269c8
--- /dev/null
+++ b/ui/lib/prompts/webSearch.ts
@@ -0,0 +1,106 @@
+export const webSearchRetrieverPrompt = `
+You are an AI question rephraser. You will be given a conversation and a follow-up question, you will have to rephrase the follow up question so it is a standalone question and can be used by another LLM to search the web for information to answer it.
+If it is a smple writing task or a greeting (unless the greeting contains a question after it) like Hi, Hello, How are you, etc. than a question then you need to return \`not_needed\` as the response (This is because the LLM won't need to search the web for finding information on this topic).
+If the user asks some question from some URL or wants you to summarize a PDF or a webpage (via URL) you need to return the links inside the \`links\` XML block and the question inside the \`question\` XML block. If the user wants to you to summarize the webpage or the PDF you need to return \`summarize\` inside the \`question\` XML block in place of a question and the link to summarize in the \`links\` XML block.
+You must always return the rephrased question inside the \`question\` XML block, if there are no links in the follow-up question then don't insert a \`links\` XML block in your response.
+
+There are several examples attached for your reference inside the below \`examples\` XML block
+
+
+1. Follow up question: What is the capital of France
+Rephrased question:\`
+
+Capital of france
+
+\`
+
+2. Hi, how are you?
+Rephrased question\`
+
+not_needed
+
+\`
+
+3. Follow up question: What is Docker?
+Rephrased question: \`
+
+What is Docker
+
+\`
+
+4. Follow up question: Can you tell me what is X from https://example.com
+Rephrased question: \`
+
+Can you tell me what is X?
+
+
+
+https://example.com
+
+\`
+
+5. Follow up question: Summarize the content from https://example.com
+Rephrased question: \`
+
+summarize
+
+
+
+https://example.com
+
+\`
+
+
+Anything below is the part of the actual conversation and you need to use conversation and the follow-up question to rephrase the follow-up question as a standalone question based on the guidelines shared above.
+
+
+{chat_history}
+
+
+Follow up question: {query}
+Rephrased question:
+`;
+
+export const webSearchResponsePrompt = `
+ You are Perplexica, an AI model skilled in web search and crafting detailed, engaging, and well-structured answers. You excel at summarizing web pages and extracting relevant information to create professional, blog-style responses.
+
+ Your task is to provide answers that are:
+ - **Informative and relevant**: Thoroughly address the user's query using the given context.
+ - **Well-structured**: Include clear headings and subheadings, and use a professional tone to present information concisely and logically.
+ - **Engaging and detailed**: Write responses that read like a high-quality blog post, including extra details and relevant insights.
+ - **Cited and credible**: Use inline citations with [number] notation to refer to the context source(s) for each fact or detail included.
+ - **Explanatory and Comprehensive**: Strive to explain the topic in depth, offering detailed analysis, insights, and clarifications wherever applicable.
+
+ ### Formatting Instructions
+ - **Structure**: 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.
+ - **Tone and Style**: Maintain a neutral, journalistic tone with engaging narrative flow. Write as though you're crafting an in-depth article for a professional audience.
+ - **Markdown Usage**: Format your response with Markdown for clarity. Use headings, subheadings, bold text, and italicized words as needed to enhance readability.
+ - **Length and Depth**: Provide comprehensive coverage of the topic. 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.
+ - **No main heading/title**: Start your response directly with the introduction unless asked to provide a specific title.
+ - **Conclusion or Summary**: Include a concluding paragraph that synthesizes the provided information or suggests potential next steps, where appropriate.
+
+ ### Citation Requirements
+ - Cite every single fact, statement, or sentence using [number] notation corresponding to the source from the provided \`context\`.
+ - Integrate citations naturally at the end of sentences or clauses as appropriate. For example, "The Eiffel Tower is one of the most visited landmarks in the world[1]."
+ - Ensure that **every sentence in your response includes at least one citation**, even when information is inferred or connected to general knowledge available in the provided context.
+ - Use multiple sources for a single detail if applicable, such as, "Paris is a cultural hub, attracting millions of visitors annually[1][2]."
+ - Always prioritize credibility and accuracy by linking all statements back to their respective context sources.
+ - Avoid citing unsupported assumptions or personal interpretations; if no source supports a statement, clearly indicate the limitation.
+
+ ### Special Instructions
+ - If the query involves technical, historical, or complex topics, provide detailed background and explanatory sections to ensure clarity.
+ - If the user provides vague input or if relevant information is missing, explain what additional details might help refine the search.
+ - If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
+
+ ### Example Output
+ - Begin with a brief introduction summarizing the event or query topic.
+ - Follow with detailed sections under clear headings, covering all aspects of the query if possible.
+ - Provide explanations or historical context as needed to enhance understanding.
+ - End with a conclusion or overall perspective if relevant.
+
+
+ {context}
+
+
+ Current date & time in ISO format (UTC timezone) is: {date}.
+`;
diff --git a/ui/lib/prompts/wolframAlpha.ts b/ui/lib/prompts/wolframAlpha.ts
new file mode 100644
index 0000000..40410c1
--- /dev/null
+++ b/ui/lib/prompts/wolframAlpha.ts
@@ -0,0 +1,65 @@
+export const wolframAlphaSearchRetrieverPrompt = `
+You will be given a conversation below and a follow up question. You need to rephrase the follow-up question if needed so it is a standalone question that can be used by the LLM to search the web for information.
+If it is a writing task or a simple hi, hello rather than a question, you need to return \`not_needed\` as the response.
+
+Example:
+1. Follow up question: What is the atomic radius of S?
+Rephrased: Atomic radius of S
+
+2. Follow up question: What is linear algebra?
+Rephrased: Linear algebra
+
+3. Follow up question: What is the third law of thermodynamics?
+Rephrased: Third law of thermodynamics
+
+Conversation:
+{chat_history}
+
+Follow up question: {query}
+Rephrased question:
+`;
+
+export const wolframAlphaSearchResponsePrompt = `
+ You are Perplexica, an AI model skilled in web search and crafting detailed, engaging, and well-structured answers. You excel at summarizing web pages and extracting relevant information to create professional, blog-style responses.
+
+ Your task is to provide answers that are:
+ - **Informative and relevant**: Thoroughly address the user's query using the given context.
+ - **Well-structured**: Include clear headings and subheadings, and use a professional tone to present information concisely and logically.
+ - **Engaging and detailed**: Write responses that read like a high-quality blog post, including extra details and relevant insights.
+ - **Cited and credible**: Use inline citations with [number] notation to refer to the context source(s) for each fact or detail included.
+ - **Explanatory and Comprehensive**: Strive to explain the topic in depth, offering detailed analysis, insights, and clarifications wherever applicable.
+
+ ### Formatting Instructions
+ - **Structure**: 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.
+ - **Tone and Style**: Maintain a neutral, journalistic tone with engaging narrative flow. Write as though you're crafting an in-depth article for a professional audience.
+ - **Markdown Usage**: Format your response with Markdown for clarity. Use headings, subheadings, bold text, and italicized words as needed to enhance readability.
+ - **Length and Depth**: Provide comprehensive coverage of the topic. 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.
+ - **No main heading/title**: Start your response directly with the introduction unless asked to provide a specific title.
+ - **Conclusion or Summary**: Include a concluding paragraph that synthesizes the provided information or suggests potential next steps, where appropriate.
+
+ ### Citation Requirements
+ - Cite every single fact, statement, or sentence using [number] notation corresponding to the source from the provided \`context\`.
+ - Integrate citations naturally at the end of sentences or clauses as appropriate. For example, "The Eiffel Tower is one of the most visited landmarks in the world[1]."
+ - Ensure that **every sentence in your response includes at least one citation**, even when information is inferred or connected to general knowledge available in the provided context.
+ - Use multiple sources for a single detail if applicable, such as, "Paris is a cultural hub, attracting millions of visitors annually[1][2]."
+ - Always prioritize credibility and accuracy by linking all statements back to their respective context sources.
+ - Avoid citing unsupported assumptions or personal interpretations; if no source supports a statement, clearly indicate the limitation.
+
+ ### Special Instructions
+ - If the query involves technical, historical, or complex topics, provide detailed background and explanatory sections to ensure clarity.
+ - If the user provides vague input or if relevant information is missing, explain what additional details might help refine the search.
+ - If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
+ - You are set on focus mode 'Wolfram Alpha', this means you will be searching for information on the web using Wolfram Alpha. It is a computational knowledge engine that can answer factual queries and perform computations.
+
+ ### Example Output
+ - Begin with a brief introduction summarizing the event or query topic.
+ - Follow with detailed sections under clear headings, covering all aspects of the query if possible.
+ - Provide explanations or historical context as needed to enhance understanding.
+ - End with a conclusion or overall perspective if relevant.
+
+
+ {context}
+
+
+ Current date & time in ISO format (UTC timezone) is: {date}.
+`;
diff --git a/ui/lib/prompts/writingAssistant.ts b/ui/lib/prompts/writingAssistant.ts
new file mode 100644
index 0000000..f56bf47
--- /dev/null
+++ b/ui/lib/prompts/writingAssistant.ts
@@ -0,0 +1,13 @@
+export const writingAssistantPrompt = `
+You are Perplexica, an AI model who is expert at searching the web and answering user's queries. You are currently set on focus mode 'Writing Assistant', this means you will be helping the user write a response to a given query.
+Since you are a writing assistant, you would not perform web searches. If you think you lack information to answer the query, you can ask the user for more information or suggest them to switch to a different focus mode.
+You will be shared a context that can contain information from files user has uploaded to get answers from. You will have to generate answers upon that.
+
+You have to cite the answer using [number] notation. You must cite the sentences with their relevent context number. You must cite each and every part of the answer so the user can know where the information is coming from.
+Place these citations at the end of that particular sentence. You can cite the same sentence multiple times if it is relevant to the user's query like [number1][number2].
+However you do not need to cite it using the same number. You can use different numbers to cite the same sentence multiple times. The number refers to the number of the search result (passed in the context) used to generate that part of the answer.
+
+
+{context}
+
+`;
diff --git a/ui/lib/prompts/youtubeSearch.ts b/ui/lib/prompts/youtubeSearch.ts
new file mode 100644
index 0000000..5805b54
--- /dev/null
+++ b/ui/lib/prompts/youtubeSearch.ts
@@ -0,0 +1,65 @@
+export const youtubeSearchRetrieverPrompt = `
+You will be given a conversation below and a follow up question. You need to rephrase the follow-up question if needed so it is a standalone question that can be used by the LLM to search the web for information.
+If it is a writing task or a simple hi, hello rather than a question, you need to return \`not_needed\` as the response.
+
+Example:
+1. Follow up question: How does an A.C work?
+Rephrased: A.C working
+
+2. Follow up question: Linear algebra explanation video
+Rephrased: What is linear algebra?
+
+3. Follow up question: What is theory of relativity?
+Rephrased: What is theory of relativity?
+
+Conversation:
+{chat_history}
+
+Follow up question: {query}
+Rephrased question:
+`;
+
+export const youtubeSearchResponsePrompt = `
+ You are Perplexica, an AI model skilled in web search and crafting detailed, engaging, and well-structured answers. You excel at summarizing web pages and extracting relevant information to create professional, blog-style responses.
+
+ Your task is to provide answers that are:
+ - **Informative and relevant**: Thoroughly address the user's query using the given context.
+ - **Well-structured**: Include clear headings and subheadings, and use a professional tone to present information concisely and logically.
+ - **Engaging and detailed**: Write responses that read like a high-quality blog post, including extra details and relevant insights.
+ - **Cited and credible**: Use inline citations with [number] notation to refer to the context source(s) for each fact or detail included.
+ - **Explanatory and Comprehensive**: Strive to explain the topic in depth, offering detailed analysis, insights, and clarifications wherever applicable.
+
+ ### Formatting Instructions
+ - **Structure**: 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.
+ - **Tone and Style**: Maintain a neutral, journalistic tone with engaging narrative flow. Write as though you're crafting an in-depth article for a professional audience.
+ - **Markdown Usage**: Format your response with Markdown for clarity. Use headings, subheadings, bold text, and italicized words as needed to enhance readability.
+ - **Length and Depth**: Provide comprehensive coverage of the topic. 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.
+ - **No main heading/title**: Start your response directly with the introduction unless asked to provide a specific title.
+ - **Conclusion or Summary**: Include a concluding paragraph that synthesizes the provided information or suggests potential next steps, where appropriate.
+
+ ### Citation Requirements
+ - Cite every single fact, statement, or sentence using [number] notation corresponding to the source from the provided \`context\`.
+ - Integrate citations naturally at the end of sentences or clauses as appropriate. For example, "The Eiffel Tower is one of the most visited landmarks in the world[1]."
+ - Ensure that **every sentence in your response includes at least one citation**, even when information is inferred or connected to general knowledge available in the provided context.
+ - Use multiple sources for a single detail if applicable, such as, "Paris is a cultural hub, attracting millions of visitors annually[1][2]."
+ - Always prioritize credibility and accuracy by linking all statements back to their respective context sources.
+ - Avoid citing unsupported assumptions or personal interpretations; if no source supports a statement, clearly indicate the limitation.
+
+ ### Special Instructions
+ - If the query involves technical, historical, or complex topics, provide detailed background and explanatory sections to ensure clarity.
+ - If the user provides vague input or if relevant information is missing, explain what additional details might help refine the search.
+ - If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
+ - You are set on focus mode 'Youtube', this means you will be searching for videos on the web using Youtube and providing information based on the video's transcrip
+
+ ### Example Output
+ - Begin with a brief introduction summarizing the event or query topic.
+ - Follow with detailed sections under clear headings, covering all aspects of the query if possible.
+ - Provide explanations or historical context as needed to enhance understanding.
+ - End with a conclusion or overall perspective if relevant.
+
+
+ {context}
+
+
+ Current date & time in ISO format (UTC timezone) is: {date}.
+`;
From 5c313e9bed47b7ee7fe7576780b1c71ac0507f44 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Tue, 18 Mar 2025 10:23:59 +0530
Subject: [PATCH 05/71] feat(ui): update packages, add config, add searxng
---
ui/lib/config.ts | 117 ++++++++
ui/lib/searxng.ts | 48 ++++
ui/next.config.mjs | 1 +
ui/package.json | 11 +-
ui/tsconfig.json | 24 +-
ui/yarn.lock | 693 +++++++++++++++++++++++++++++++++++++++------
6 files changed, 809 insertions(+), 85 deletions(-)
create mode 100644 ui/lib/config.ts
create mode 100644 ui/lib/searxng.ts
diff --git a/ui/lib/config.ts b/ui/lib/config.ts
new file mode 100644
index 0000000..1e5148d
--- /dev/null
+++ b/ui/lib/config.ts
@@ -0,0 +1,117 @@
+import fs from 'fs';
+import path from 'path';
+import toml from '@iarna/toml';
+
+const configFileName = 'config.toml';
+
+interface Config {
+ GENERAL: {
+ PORT: number;
+ SIMILARITY_MEASURE: string;
+ KEEP_ALIVE: string;
+ };
+ MODELS: {
+ OPENAI: {
+ API_KEY: string;
+ };
+ GROQ: {
+ API_KEY: string;
+ };
+ ANTHROPIC: {
+ API_KEY: string;
+ };
+ GEMINI: {
+ API_KEY: string;
+ };
+ OLLAMA: {
+ API_URL: string;
+ };
+ CUSTOM_OPENAI: {
+ API_URL: string;
+ API_KEY: string;
+ MODEL_NAME: string;
+ };
+ };
+ API_ENDPOINTS: {
+ SEARXNG: string;
+ };
+}
+
+type RecursivePartial = {
+ [P in keyof T]?: RecursivePartial;
+};
+
+const loadConfig = () =>
+ toml.parse(
+ fs.readFileSync(path.join(process.cwd(), `${configFileName}`), 'utf-8'),
+ ) as any as Config;
+
+export const getPort = () => loadConfig().GENERAL.PORT;
+
+export const getSimilarityMeasure = () =>
+ loadConfig().GENERAL.SIMILARITY_MEASURE;
+
+export const getKeepAlive = () => loadConfig().GENERAL.KEEP_ALIVE;
+
+export const getOpenaiApiKey = () => loadConfig().MODELS.OPENAI.API_KEY;
+
+export const getGroqApiKey = () => loadConfig().MODELS.GROQ.API_KEY;
+
+export const getAnthropicApiKey = () => loadConfig().MODELS.ANTHROPIC.API_KEY;
+
+export const getGeminiApiKey = () => loadConfig().MODELS.GEMINI.API_KEY;
+
+export const getSearxngApiEndpoint = () =>
+ process.env.SEARXNG_API_URL || loadConfig().API_ENDPOINTS.SEARXNG;
+
+export const getOllamaApiEndpoint = () => loadConfig().MODELS.OLLAMA.API_URL;
+
+export const getCustomOpenaiApiKey = () =>
+ loadConfig().MODELS.CUSTOM_OPENAI.API_KEY;
+
+export const getCustomOpenaiApiUrl = () =>
+ loadConfig().MODELS.CUSTOM_OPENAI.API_URL;
+
+export const getCustomOpenaiModelName = () =>
+ loadConfig().MODELS.CUSTOM_OPENAI.MODEL_NAME;
+
+const mergeConfigs = (current: any, update: any): any => {
+ if (update === null || update === undefined) {
+ return current;
+ }
+
+ if (typeof current !== 'object' || current === null) {
+ return update;
+ }
+
+ const result = { ...current };
+
+ for (const key in update) {
+ if (Object.prototype.hasOwnProperty.call(update, key)) {
+ const updateValue = update[key];
+
+ if (
+ typeof updateValue === 'object' &&
+ updateValue !== null &&
+ typeof result[key] === 'object' &&
+ result[key] !== null
+ ) {
+ result[key] = mergeConfigs(result[key], updateValue);
+ } else if (updateValue !== undefined) {
+ result[key] = updateValue;
+ }
+ }
+ }
+
+ return result;
+};
+
+export const updateConfig = (config: RecursivePartial) => {
+ const currentConfig = loadConfig();
+ const mergedConfig = mergeConfigs(currentConfig, config);
+
+ fs.writeFileSync(
+ path.join(__dirname, `../${configFileName}`),
+ toml.stringify(mergedConfig),
+ );
+};
\ No newline at end of file
diff --git a/ui/lib/searxng.ts b/ui/lib/searxng.ts
new file mode 100644
index 0000000..ae19db2
--- /dev/null
+++ b/ui/lib/searxng.ts
@@ -0,0 +1,48 @@
+import axios from 'axios';
+import { getSearxngApiEndpoint } from './config';
+
+interface SearxngSearchOptions {
+ categories?: string[];
+ engines?: string[];
+ language?: string;
+ pageno?: number;
+}
+
+interface SearxngSearchResult {
+ title: string;
+ url: string;
+ img_src?: string;
+ thumbnail_src?: string;
+ thumbnail?: string;
+ content?: string;
+ author?: string;
+ iframe_src?: string;
+}
+
+export const searchSearxng = async (
+ query: string,
+ opts?: SearxngSearchOptions,
+) => {
+ const searxngURL = getSearxngApiEndpoint();
+
+ const url = new URL(`${searxngURL}/search?format=json`);
+ url.searchParams.append('q', query);
+
+ if (opts) {
+ Object.keys(opts).forEach((key) => {
+ const value = opts[key as keyof SearxngSearchOptions];
+ if (Array.isArray(value)) {
+ url.searchParams.append(key, value.join(','));
+ return;
+ }
+ url.searchParams.append(key, value as string);
+ });
+ }
+
+ const res = await axios.get(url.toString());
+
+ const results: SearxngSearchResult[] = res.data.results;
+ const suggestions: string[] = res.data.suggestions;
+
+ return { results, suggestions };
+};
diff --git a/ui/next.config.mjs b/ui/next.config.mjs
index c3f2e1a..a5db257 100644
--- a/ui/next.config.mjs
+++ b/ui/next.config.mjs
@@ -7,6 +7,7 @@ const nextConfig = {
},
],
},
+ serverExternalPackages: ['pdf-parse']
};
export default nextConfig;
diff --git a/ui/package.json b/ui/package.json
index e299391..c9a7a94 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -12,26 +12,35 @@
},
"dependencies": {
"@headlessui/react": "^2.2.0",
+ "@iarna/toml": "^2.2.5",
"@icons-pack/react-simple-icons": "^9.4.0",
"@langchain/openai": "^0.0.25",
"@tailwindcss/typography": "^0.5.12",
+ "axios": "^1.8.3",
"clsx": "^2.1.0",
+ "compute-cosine-similarity": "^1.1.0",
+ "compute-dot": "^1.1.0",
+ "html-to-text": "^9.0.5",
"langchain": "^0.1.30",
"lucide-react": "^0.363.0",
"markdown-to-jsx": "^7.7.2",
- "next": "14.1.4",
+ "next": "^15.2.2",
"next-themes": "^0.3.0",
+ "pdf-parse": "^1.1.1",
"react": "^18",
"react-dom": "^18",
"react-text-to-speech": "^0.14.5",
"react-textarea-autosize": "^8.5.3",
"sonner": "^1.4.41",
"tailwind-merge": "^2.2.2",
+ "winston": "^3.17.0",
"yet-another-react-lightbox": "^3.17.2",
"zod": "^3.22.4"
},
"devDependencies": {
+ "@types/html-to-text": "^9.0.4",
"@types/node": "^20",
+ "@types/pdf-parse": "^1.1.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
diff --git a/ui/tsconfig.json b/ui/tsconfig.json
index e7ff90f..d81d4ee 100644
--- a/ui/tsconfig.json
+++ b/ui/tsconfig.json
@@ -1,6 +1,10 @@
{
"compilerOptions": {
- "lib": ["dom", "dom.iterable", "esnext"],
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -18,9 +22,19 @@
}
],
"paths": {
- "@/*": ["./*"]
- }
+ "@/*": [
+ "./*"
+ ]
+ },
+ "target": "ES2017"
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
- "exclude": ["node_modules"]
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
}
diff --git a/ui/yarn.lock b/ui/yarn.lock
index 7eb109f..427693e 100644
--- a/ui/yarn.lock
+++ b/ui/yarn.lock
@@ -34,6 +34,27 @@
dependencies:
regenerator-runtime "^0.14.0"
+"@colors/colors@1.6.0", "@colors/colors@^1.6.0":
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0"
+ integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==
+
+"@dabh/diagnostics@^2.0.2":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a"
+ integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==
+ dependencies:
+ colorspace "1.1.x"
+ enabled "2.0.x"
+ kuler "^2.0.0"
+
+"@emnapi/runtime@^1.2.0":
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60"
+ integrity sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==
+ dependencies:
+ tslib "^2.4.0"
+
"@eslint-community/eslint-utils@^4.2.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
@@ -131,11 +152,129 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3"
integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==
+"@iarna/toml@^2.2.5":
+ version "2.2.5"
+ resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c"
+ integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==
+
"@icons-pack/react-simple-icons@^9.4.0":
version "9.4.0"
resolved "https://registry.yarnpkg.com/@icons-pack/react-simple-icons/-/react-simple-icons-9.4.0.tgz#37871d830f9ec9cfa1d1aab186036df2ab075f26"
integrity sha512-fZtC4Zv53hE+IQE2dJlFt3EB6UOifwTrUNMuEu4hSXemtqMahd05Dpvj2K0j2ewVc+j/ibavud3xjfaMB2Nj7g==
+"@img/sharp-darwin-arm64@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz#ef5b5a07862805f1e8145a377c8ba6e98813ca08"
+ integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==
+ optionalDependencies:
+ "@img/sharp-libvips-darwin-arm64" "1.0.4"
+
+"@img/sharp-darwin-x64@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz#e03d3451cd9e664faa72948cc70a403ea4063d61"
+ integrity sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==
+ optionalDependencies:
+ "@img/sharp-libvips-darwin-x64" "1.0.4"
+
+"@img/sharp-libvips-darwin-arm64@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz#447c5026700c01a993c7804eb8af5f6e9868c07f"
+ integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==
+
+"@img/sharp-libvips-darwin-x64@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz#e0456f8f7c623f9dbfbdc77383caa72281d86062"
+ integrity sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==
+
+"@img/sharp-libvips-linux-arm64@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz#979b1c66c9a91f7ff2893556ef267f90ebe51704"
+ integrity sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==
+
+"@img/sharp-libvips-linux-arm@1.0.5":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz#99f922d4e15216ec205dcb6891b721bfd2884197"
+ integrity sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==
+
+"@img/sharp-libvips-linux-s390x@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz#f8a5eb1f374a082f72b3f45e2fb25b8118a8a5ce"
+ integrity sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==
+
+"@img/sharp-libvips-linux-x64@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz#d4c4619cdd157774906e15770ee119931c7ef5e0"
+ integrity sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==
+
+"@img/sharp-libvips-linuxmusl-arm64@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz#166778da0f48dd2bded1fa3033cee6b588f0d5d5"
+ integrity sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==
+
+"@img/sharp-libvips-linuxmusl-x64@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz#93794e4d7720b077fcad3e02982f2f1c246751ff"
+ integrity sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==
+
+"@img/sharp-linux-arm64@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz#edb0697e7a8279c9fc829a60fc35644c4839bb22"
+ integrity sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==
+ optionalDependencies:
+ "@img/sharp-libvips-linux-arm64" "1.0.4"
+
+"@img/sharp-linux-arm@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz#422c1a352e7b5832842577dc51602bcd5b6f5eff"
+ integrity sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==
+ optionalDependencies:
+ "@img/sharp-libvips-linux-arm" "1.0.5"
+
+"@img/sharp-linux-s390x@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz#f5c077926b48e97e4a04d004dfaf175972059667"
+ integrity sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==
+ optionalDependencies:
+ "@img/sharp-libvips-linux-s390x" "1.0.4"
+
+"@img/sharp-linux-x64@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz#d806e0afd71ae6775cc87f0da8f2d03a7c2209cb"
+ integrity sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==
+ optionalDependencies:
+ "@img/sharp-libvips-linux-x64" "1.0.4"
+
+"@img/sharp-linuxmusl-arm64@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz#252975b915894fb315af5deea174651e208d3d6b"
+ integrity sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==
+ optionalDependencies:
+ "@img/sharp-libvips-linuxmusl-arm64" "1.0.4"
+
+"@img/sharp-linuxmusl-x64@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz#3f4609ac5d8ef8ec7dadee80b560961a60fd4f48"
+ integrity sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==
+ optionalDependencies:
+ "@img/sharp-libvips-linuxmusl-x64" "1.0.4"
+
+"@img/sharp-wasm32@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz#6f44f3283069d935bb5ca5813153572f3e6f61a1"
+ integrity sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==
+ dependencies:
+ "@emnapi/runtime" "^1.2.0"
+
+"@img/sharp-win32-ia32@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz#1a0c839a40c5351e9885628c85f2e5dfd02b52a9"
+ integrity sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==
+
+"@img/sharp-win32-x64@0.33.5":
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz#56f00962ff0c4e0eb93d34a047d29fa995e3e342"
+ integrity sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==
+
"@isaacs/cliui@^8.0.2":
version "8.0.2"
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
@@ -233,10 +372,10 @@
zod "^3.22.4"
zod-to-json-schema "^3.22.3"
-"@next/env@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/env/-/env-14.1.4.tgz#432e80651733fbd67230bf262aee28be65252674"
- integrity sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ==
+"@next/env@15.2.2":
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/@next/env/-/env-15.2.2.tgz#6345352365a811c523cecf284874ff489b675e59"
+ integrity sha512-yWgopCfA9XDR8ZH3taB5nRKtKJ1Q5fYsTOuYkzIIoS8TJ0UAUKAGF73JnGszbjk2ufAQDj6mDdgsJAFx5CLtYQ==
"@next/eslint-plugin-next@14.1.4":
version "14.1.4"
@@ -245,50 +384,45 @@
dependencies:
glob "10.3.10"
-"@next/swc-darwin-arm64@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.4.tgz#a3bca0dc4393ac4cf3169bbf24df63441de66bb7"
- integrity sha512-ubmUkbmW65nIAOmoxT1IROZdmmJMmdYvXIe8211send9ZYJu+SqxSnJM4TrPj9wmL6g9Atvj0S/2cFmMSS99jg==
+"@next/swc-darwin-arm64@15.2.2":
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.2.tgz#d3131279d4815ed7604eba7bf0063e0b8bfd2135"
+ integrity sha512-HNBRnz+bkZ+KfyOExpUxTMR0Ow8nkkcE6IlsdEa9W/rI7gefud19+Sn1xYKwB9pdCdxIP1lPru/ZfjfA+iT8pw==
-"@next/swc-darwin-x64@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.4.tgz#ba3683d4e2d30099f3f2864dd7349a4d9f440140"
- integrity sha512-b0Xo1ELj3u7IkZWAKcJPJEhBop117U78l70nfoQGo4xUSvv0PJSTaV4U9xQBLvZlnjsYkc8RwQN1HoH/oQmLlQ==
+"@next/swc-darwin-x64@15.2.2":
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-15.2.2.tgz#8562f6b51177aa30f3a6e95a8b3e0e176a6cb04f"
+ integrity sha512-mJOUwp7al63tDpLpEFpKwwg5jwvtL1lhRW2fI1Aog0nYCPAhxbJsaZKdoVyPZCy8MYf/iQVNDuk/+i29iLCzIA==
-"@next/swc-linux-arm64-gnu@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.4.tgz#3519969293f16379954b7e196deb0c1eecbb2f8b"
- integrity sha512-457G0hcLrdYA/u1O2XkRMsDKId5VKe3uKPvrKVOyuARa6nXrdhJOOYU9hkKKyQTMru1B8qEP78IAhf/1XnVqKA==
+"@next/swc-linux-arm64-gnu@15.2.2":
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.2.2.tgz#c2466cffc541f39ae4d435087c81f5899d401903"
+ integrity sha512-5ZZ0Zwy3SgMr7MfWtRE7cQWVssfOvxYfD9O7XHM7KM4nrf5EOeqwq67ZXDgo86LVmffgsu5tPO57EeFKRnrfSQ==
-"@next/swc-linux-arm64-musl@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.4.tgz#4bb3196bd402b3f84cf5373ff1021f547264d62f"
- integrity sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g==
+"@next/swc-linux-arm64-musl@15.2.2":
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.2.2.tgz#24ed87fe47325597e986bd01c427efae53d6b677"
+ integrity sha512-cgKWBuFMLlJ4TWcFHl1KOaVVUAF8vy4qEvX5KsNd0Yj5mhu989QFCq1WjuaEbv/tO1ZpsQI6h/0YR8bLwEi+nA==
-"@next/swc-linux-x64-gnu@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.4.tgz#1b3372c98c83dcdab946cdb4ee06e068b8139ba3"
- integrity sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw==
+"@next/swc-linux-x64-gnu@15.2.2":
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.2.2.tgz#0240f44530ca39c1fc899fabe8f33aa35d7e77da"
+ integrity sha512-c3kWSOSsVL8rcNBBfOq1+/j2PKs2nsMwJUV4icUxRgGBwUOfppeh7YhN5s79enBQFU+8xRgVatFkhHU1QW7yUA==
-"@next/swc-linux-x64-musl@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.4.tgz#8459088bdc872648ff78f121db596f2533df5808"
- integrity sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg==
+"@next/swc-linux-x64-musl@15.2.2":
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.2.2.tgz#cca6ce8e9ec89afaa618673f0f8658682c30ff56"
+ integrity sha512-PXTW9PLTxdNlVYgPJ0equojcq1kNu5NtwcNjRjHAB+/sdoKZ+X8FBu70fdJFadkxFIGekQTyRvPMFF+SOJaQjw==
-"@next/swc-win32-arm64-msvc@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.4.tgz#84280a08c00cc3be24ddd3a12f4617b108e6dea6"
- integrity sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag==
+"@next/swc-win32-arm64-msvc@15.2.2":
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.2.2.tgz#08f621602ed53fa21ddf6f656160b9186860be15"
+ integrity sha512-nG644Es5llSGEcTaXhnGWR/aThM/hIaz0jx4MDg4gWC8GfTCp8eDBWZ77CVuv2ha/uL9Ce+nPTfYkSLG67/sHg==
-"@next/swc-win32-ia32-msvc@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.4.tgz#23ff7f4bd0a27177428669ef6fa5c3923c738031"
- integrity sha512-WZiz8OdbkpRw6/IU/lredZWKKZopUMhcI2F+XiMAcPja0uZYdMTZQRoQ0WZcvinn9xZAidimE7tN9W5v9Yyfyw==
-
-"@next/swc-win32-x64-msvc@14.1.4":
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.4.tgz#bccf5beccfde66d6c66fa4e2509118c796385eda"
- integrity sha512-4Rto21sPfw555sZ/XNLqfxDUNeLhNYGO2dlPqsnuCg8N8a2a9u1ltqBOPQ4vj1Gf7eJC0W2hHG2eYUHuiXgY2w==
+"@next/swc-win32-x64-msvc@15.2.2":
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.2.2.tgz#2072d69374f8c944134a5c5a80ce03ff84254cfa"
+ integrity sha512-52nWy65S/R6/kejz3jpvHAjZDPKIbEQu4x9jDBzmB9jJfuOy5rspjKu4u77+fI4M/WzLXrrQd57hlFGzz1ubcQ==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
@@ -372,14 +506,20 @@
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.10.1.tgz#7ca168b6937818e9a74b47ac4e2112b2e1a024cf"
integrity sha512-S3Kq8e7LqxkA9s7HKLqXGTGck1uwis5vAXan3FnU5yw1Ec5hsSGnq4s/UCaSqABPOnOTg7zASLyst7+ohgWexg==
-"@swc/helpers@0.5.2":
- version "0.5.2"
- resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.2.tgz#85ea0c76450b61ad7d10a37050289eded783c27d"
- integrity sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==
+"@selderee/plugin-htmlparser2@^0.11.0":
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz#d5b5e29a7ba6d3958a1972c7be16f4b2c188c517"
+ integrity sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==
dependencies:
- tslib "^2.4.0"
+ domhandler "^5.0.3"
+ selderee "^0.11.0"
-"@swc/helpers@^0.5.0":
+"@swc/counter@0.1.3":
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9"
+ integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==
+
+"@swc/helpers@0.5.15", "@swc/helpers@^0.5.0":
version "0.5.15"
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.15.tgz#79efab344c5819ecf83a43f3f9f811fc84b516d7"
integrity sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==
@@ -408,6 +548,11 @@
resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.10.9.tgz#55710c92b311fdaa8d8c66682a0dbdd684bc77c4"
integrity sha512-kBknKOKzmeR7lN+vSadaKWXaLS0SZZG+oqpQ/k80Q6g9REn6zRHS/ZYdrIzHnpHgy/eWs00SujveUN/GJT2qTw==
+"@types/html-to-text@^9.0.4":
+ version "9.0.4"
+ resolved "https://registry.yarnpkg.com/@types/html-to-text/-/html-to-text-9.0.4.tgz#4a83dd8ae8bfa91457d0b1ffc26f4d0537eff58c"
+ integrity sha512-pUY3cKH/Nm2yYrEmDlPR1mR7yszjGx4DrwPjQ702C4/D5CwHuZTgZdIdwPkRbcuhs7BAh2L5rg3CL5cbRiGTCQ==
+
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@@ -435,6 +580,11 @@
dependencies:
undici-types "~5.26.4"
+"@types/pdf-parse@^1.1.4":
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/@types/pdf-parse/-/pdf-parse-1.1.4.tgz#21a539efd2f16009d08aeed3350133948b5d7ed1"
+ integrity sha512-+gbBHbNCVGGYw1S9lAIIvrHW47UYOhMIFUsJcMkMrzy1Jf0vulBN3XQIjPgnoOXveMuHnF3b57fXROnY/Or7eg==
+
"@types/prop-types@*":
version "15.7.12"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6"
@@ -460,6 +610,11 @@
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
+"@types/triple-beam@^1.3.2":
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c"
+ integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==
+
"@types/uuid@^9.0.1":
version "9.0.8"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba"
@@ -716,6 +871,11 @@ ast-types-flow@^0.0.8:
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6"
integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==
+async@^3.2.3:
+ version "3.2.6"
+ resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
+ integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
+
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -745,6 +905,15 @@ axe-core@=4.7.0:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf"
integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==
+axios@^1.8.3:
+ version "1.8.3"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.3.tgz#9ebccd71c98651d547162a018a1a95a4b4ed4de8"
+ integrity sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==
+ dependencies:
+ follow-redirects "^1.15.6"
+ form-data "^4.0.0"
+ proxy-from-env "^1.1.0"
+
axobject-query@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a"
@@ -842,7 +1011,12 @@ camelcase@6:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
-caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001599:
+caniuse-lite@^1.0.30001579:
+ version "1.0.30001705"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001705.tgz#dc3510bcdef261444ca944b7be9c8d0bb7fafeef"
+ integrity sha512-S0uyMMiYvA7CxNgomYBwwwPUnWzFD83f3B1ce5jHUfHTH//QL6hHsreI8RVC5606R4ssqravelYO5TU6t8sEyg==
+
+caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001599:
version "1.0.30001606"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001606.tgz#b4d5f67ab0746a3b8b5b6d1f06e39c51beb39a9e"
integrity sha512-LPbwnW4vfpJId225pwjZJOgX1m9sGfbw/RKJvw/t0QhYOOaTXHvkjVGFGPpvwEzufrjvTlsULnVTxdy4/6cqkg==
@@ -890,6 +1064,13 @@ clsx@^2.1.0:
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb"
integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==
+color-convert@^1.9.3:
+ version "1.9.3"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
+ integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+ dependencies:
+ color-name "1.1.3"
+
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
@@ -897,11 +1078,48 @@ color-convert@^2.0.1:
dependencies:
color-name "~1.1.4"
-color-name@~1.1.4:
+color-name@1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+ integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
+
+color-name@^1.0.0, color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+color-string@^1.6.0, color-string@^1.9.0:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
+ integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
+ dependencies:
+ color-name "^1.0.0"
+ simple-swizzle "^0.2.2"
+
+color@^3.1.3:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164"
+ integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==
+ dependencies:
+ color-convert "^1.9.3"
+ color-string "^1.6.0"
+
+color@^4.2.3:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a"
+ integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
+ dependencies:
+ color-convert "^2.0.1"
+ color-string "^1.9.0"
+
+colorspace@1.1.x:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243"
+ integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==
+ dependencies:
+ color "^3.1.3"
+ text-hex "1.0.x"
+
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@@ -919,6 +1137,32 @@ commander@^4.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
+compute-cosine-similarity@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/compute-cosine-similarity/-/compute-cosine-similarity-1.1.0.tgz#0086a06b0239deb90f231f0da894efdc48884609"
+ integrity sha512-FXhNx0ILLjGi9Z9+lglLzM12+0uoTnYkHm7GiadXDAr0HGVLm25OivUS1B/LPkbzzvlcXz/1EvWg9ZYyJSdhTw==
+ dependencies:
+ compute-dot "^1.1.0"
+ compute-l2norm "^1.1.0"
+ validate.io-array "^1.0.5"
+ validate.io-function "^1.0.2"
+
+compute-dot@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/compute-dot/-/compute-dot-1.1.0.tgz#01a5ba2c7af73b99002acb258459c9576a8232dc"
+ integrity sha512-L5Ocet4DdMrXboss13K59OK23GXjiSia7+7Ukc7q4Bl+RVpIXK2W9IHMbWDZkh+JUEvJAwOKRaJDiFUa1LTnJg==
+ dependencies:
+ validate.io-array "^1.0.3"
+ validate.io-function "^1.0.2"
+
+compute-l2norm@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/compute-l2norm/-/compute-l2norm-1.1.0.tgz#bd09131c6b36c8d70c68334e176009a4e0a989ac"
+ integrity sha512-6EHh1Elj90eU28SXi+h2PLnTQvZmkkHWySpoFz+WOlVNLz3DQoC4ISUHSV9n5jMxPHtKGJ01F4uu2PsXBB8sSg==
+ dependencies:
+ validate.io-array "^1.0.3"
+ validate.io-function "^1.0.2"
+
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -980,7 +1224,7 @@ data-view-byte-offset@^1.0.0:
es-errors "^1.3.0"
is-data-view "^1.0.1"
-debug@^3.2.7:
+debug@^3.1.0, debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
@@ -1004,6 +1248,11 @@ deep-is@^0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
+deepmerge@^4.3.1:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
+ integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
+
define-data-property@^1.0.1, define-data-property@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
@@ -1032,6 +1281,11 @@ dequal@^2.0.3:
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
+detect-libc@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
+ integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==
+
didyoumean@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
@@ -1071,6 +1325,36 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
+dom-serializer@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
+ integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
+ dependencies:
+ domelementtype "^2.3.0"
+ domhandler "^5.0.2"
+ entities "^4.2.0"
+
+domelementtype@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
+ integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
+
+domhandler@^5.0.2, domhandler@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
+ integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
+ dependencies:
+ domelementtype "^2.3.0"
+
+domutils@^3.0.1:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78"
+ integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==
+ dependencies:
+ dom-serializer "^2.0.0"
+ domelementtype "^2.3.0"
+ domhandler "^5.0.3"
+
eastasianwidth@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
@@ -1091,6 +1375,11 @@ emoji-regex@^9.2.2:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
+enabled@2.0.x:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2"
+ integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==
+
enhanced-resolve@^5.12.0:
version "5.16.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz#65ec88778083056cb32487faa9aef82ed0864787"
@@ -1099,6 +1388,11 @@ enhanced-resolve@^5.12.0:
graceful-fs "^4.2.4"
tapable "^2.2.0"
+entities@^4.2.0, entities@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
+ integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+
es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2:
version "1.23.3"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0"
@@ -1481,6 +1775,11 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
+fecha@^4.2.0:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
+ integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
+
file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
@@ -1522,6 +1821,16 @@ flatted@^3.2.9:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a"
integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
+fn.name@1.x.x:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc"
+ integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
+
+follow-redirects@^1.15.6:
+ version "1.15.9"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
+ integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
+
for-each@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
@@ -1702,7 +2011,7 @@ gopd@^1.0.1:
dependencies:
get-intrinsic "^1.1.3"
-graceful-fs@^4.2.11, graceful-fs@^4.2.4:
+graceful-fs@^4.2.4:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
@@ -1753,6 +2062,27 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2:
dependencies:
function-bind "^1.1.2"
+html-to-text@^9.0.5:
+ version "9.0.5"
+ resolved "https://registry.yarnpkg.com/html-to-text/-/html-to-text-9.0.5.tgz#6149a0f618ae7a0db8085dca9bbf96d32bb8368d"
+ integrity sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==
+ dependencies:
+ "@selderee/plugin-htmlparser2" "^0.11.0"
+ deepmerge "^4.3.1"
+ dom-serializer "^2.0.0"
+ htmlparser2 "^8.0.2"
+ selderee "^0.11.0"
+
+htmlparser2@^8.0.2:
+ version "8.0.2"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21"
+ integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==
+ dependencies:
+ domelementtype "^2.3.0"
+ domhandler "^5.0.3"
+ domutils "^3.0.1"
+ entities "^4.4.0"
+
humanize-ms@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"
@@ -1786,7 +2116,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2:
+inherits@2, inherits@^2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -1813,6 +2143,11 @@ is-array-buffer@^3.0.4:
call-bind "^1.0.2"
get-intrinsic "^1.2.1"
+is-arrayish@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
+ integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
+
is-async-function@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646"
@@ -1951,6 +2286,11 @@ is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3:
dependencies:
call-bind "^1.0.7"
+is-stream@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
+ integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
+
is-string@^1.0.5, is-string@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
@@ -2090,6 +2430,11 @@ keyv@^4.5.3:
dependencies:
json-buffer "3.0.1"
+kuler@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
+ integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==
+
langchain@^0.1.30:
version "0.1.31"
resolved "https://registry.yarnpkg.com/langchain/-/langchain-0.1.31.tgz#4f3a0e84a00d77214b325156e661762f945f33ae"
@@ -2141,6 +2486,11 @@ language-tags@^1.0.9:
dependencies:
language-subtag-registry "^0.3.20"
+leac@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/leac/-/leac-0.6.0.tgz#dcf136e382e666bd2475f44a1096061b70dc0912"
+ integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==
+
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
@@ -2186,6 +2536,18 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
+logform@^2.7.0:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/logform/-/logform-2.7.0.tgz#cfca97528ef290f2e125a08396805002b2d060d1"
+ integrity sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==
+ dependencies:
+ "@colors/colors" "1.6.0"
+ "@types/triple-beam" "^1.3.2"
+ fecha "^4.2.0"
+ ms "^2.1.1"
+ safe-stable-stringify "^2.3.1"
+ triple-beam "^1.3.0"
+
loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -2335,7 +2697,12 @@ mz@^2.7.0:
object-assign "^4.0.1"
thenify-all "^1.0.0"
-nanoid@^3.3.6, nanoid@^3.3.7:
+nanoid@^3.3.6:
+ version "3.3.10"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.10.tgz#7bc882237698ef787d5cbba109e3b0168ba6e7b1"
+ integrity sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==
+
+nanoid@^3.3.7:
version "3.3.7"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
@@ -2350,34 +2717,39 @@ next-themes@^0.3.0:
resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.3.0.tgz#b4d2a866137a67d42564b07f3a3e720e2ff3871a"
integrity sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==
-next@14.1.4:
- version "14.1.4"
- resolved "https://registry.yarnpkg.com/next/-/next-14.1.4.tgz#203310f7310578563fd5c961f0db4729ce7a502d"
- integrity sha512-1WTaXeSrUwlz/XcnhGTY7+8eiaFvdet5z9u3V2jb+Ek1vFo0VhHKSAIJvDWfQpttWjnyw14kBeq28TPq7bTeEQ==
+next@^15.2.2:
+ version "15.2.2"
+ resolved "https://registry.yarnpkg.com/next/-/next-15.2.2.tgz#e3941a0e0e76cfe1880b57452807489e0546e3a2"
+ integrity sha512-dgp8Kcx5XZRjMw2KNwBtUzhngRaURPioxoNIVl5BOyJbhi9CUgEtKDO7fx5wh8Z8vOVX1nYZ9meawJoRrlASYA==
dependencies:
- "@next/env" "14.1.4"
- "@swc/helpers" "0.5.2"
+ "@next/env" "15.2.2"
+ "@swc/counter" "0.1.3"
+ "@swc/helpers" "0.5.15"
busboy "1.6.0"
caniuse-lite "^1.0.30001579"
- graceful-fs "^4.2.11"
postcss "8.4.31"
- styled-jsx "5.1.1"
+ styled-jsx "5.1.6"
optionalDependencies:
- "@next/swc-darwin-arm64" "14.1.4"
- "@next/swc-darwin-x64" "14.1.4"
- "@next/swc-linux-arm64-gnu" "14.1.4"
- "@next/swc-linux-arm64-musl" "14.1.4"
- "@next/swc-linux-x64-gnu" "14.1.4"
- "@next/swc-linux-x64-musl" "14.1.4"
- "@next/swc-win32-arm64-msvc" "14.1.4"
- "@next/swc-win32-ia32-msvc" "14.1.4"
- "@next/swc-win32-x64-msvc" "14.1.4"
+ "@next/swc-darwin-arm64" "15.2.2"
+ "@next/swc-darwin-x64" "15.2.2"
+ "@next/swc-linux-arm64-gnu" "15.2.2"
+ "@next/swc-linux-arm64-musl" "15.2.2"
+ "@next/swc-linux-x64-gnu" "15.2.2"
+ "@next/swc-linux-x64-musl" "15.2.2"
+ "@next/swc-win32-arm64-msvc" "15.2.2"
+ "@next/swc-win32-x64-msvc" "15.2.2"
+ sharp "^0.33.5"
node-domexception@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
+node-ensure@^0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/node-ensure/-/node-ensure-0.0.0.tgz#ecae764150de99861ec5c810fd5d096b183932a7"
+ integrity sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw==
+
node-fetch@^2.6.7:
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
@@ -2488,6 +2860,13 @@ once@^1.3.0:
dependencies:
wrappy "1"
+one-time@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45"
+ integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==
+ dependencies:
+ fn.name "1.x.x"
+
openai@^4.26.0, openai@^4.32.1:
version "4.33.0"
resolved "https://registry.yarnpkg.com/openai/-/openai-4.33.0.tgz#8c33da687d4a7f3dd7576179318341615394c79d"
@@ -2568,6 +2947,14 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
+parseley@^0.12.0:
+ version "0.12.1"
+ resolved "https://registry.yarnpkg.com/parseley/-/parseley-0.12.1.tgz#4afd561d50215ebe259e3e7a853e62f600683aef"
+ integrity sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==
+ dependencies:
+ leac "^0.6.0"
+ peberminta "^0.9.0"
+
path-exists@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
@@ -2601,10 +2988,23 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+pdf-parse@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/pdf-parse/-/pdf-parse-1.1.1.tgz#745e07408679548b3995ff896fd38e96e19d14a7"
+ integrity sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A==
+ dependencies:
+ debug "^3.1.0"
+ node-ensure "^0.0.0"
+
+peberminta@^0.9.0:
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/peberminta/-/peberminta-0.9.0.tgz#8ec9bc0eb84b7d368126e71ce9033501dca2a352"
+ integrity sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==
+
picocolors@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
- integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
version "2.3.1"
@@ -2715,6 +3115,11 @@ prop-types@^15.8.1:
object-assign "^4.1.1"
react-is "^16.13.1"
+proxy-from-env@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
+ integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
+
punycode@^2.1.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
@@ -2766,6 +3171,15 @@ read-cache@^1.0.0:
dependencies:
pify "^2.3.0"
+readable-stream@^3.4.0, readable-stream@^3.6.2:
+ version "3.6.2"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
+ integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
+ dependencies:
+ inherits "^2.0.3"
+ string_decoder "^1.1.1"
+ util-deprecate "^1.0.1"
+
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
@@ -2863,6 +3277,11 @@ safe-array-concat@^1.1.2:
has-symbols "^1.0.3"
isarray "^2.0.5"
+safe-buffer@~5.2.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
safe-regex-test@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377"
@@ -2872,6 +3291,11 @@ safe-regex-test@^1.0.3:
es-errors "^1.3.0"
is-regex "^1.1.4"
+safe-stable-stringify@^2.3.1:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd"
+ integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==
+
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
@@ -2879,6 +3303,13 @@ scheduler@^0.23.0:
dependencies:
loose-envify "^1.1.0"
+selderee@^0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/selderee/-/selderee-0.11.0.tgz#6af0c7983e073ad3e35787ffe20cefd9daf0ec8a"
+ integrity sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==
+ dependencies:
+ parseley "^0.12.0"
+
semver@^6.3.1:
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
@@ -2891,6 +3322,11 @@ semver@^7.5.4:
dependencies:
lru-cache "^6.0.0"
+semver@^7.6.3:
+ version "7.7.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
+ integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
+
set-function-length@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
@@ -2913,6 +3349,35 @@ set-function-name@^2.0.1, set-function-name@^2.0.2:
functions-have-names "^1.2.3"
has-property-descriptors "^1.0.2"
+sharp@^0.33.5:
+ version "0.33.5"
+ resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.33.5.tgz#13e0e4130cc309d6a9497596715240b2ec0c594e"
+ integrity sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==
+ dependencies:
+ color "^4.2.3"
+ detect-libc "^2.0.3"
+ semver "^7.6.3"
+ optionalDependencies:
+ "@img/sharp-darwin-arm64" "0.33.5"
+ "@img/sharp-darwin-x64" "0.33.5"
+ "@img/sharp-libvips-darwin-arm64" "1.0.4"
+ "@img/sharp-libvips-darwin-x64" "1.0.4"
+ "@img/sharp-libvips-linux-arm" "1.0.5"
+ "@img/sharp-libvips-linux-arm64" "1.0.4"
+ "@img/sharp-libvips-linux-s390x" "1.0.4"
+ "@img/sharp-libvips-linux-x64" "1.0.4"
+ "@img/sharp-libvips-linuxmusl-arm64" "1.0.4"
+ "@img/sharp-libvips-linuxmusl-x64" "1.0.4"
+ "@img/sharp-linux-arm" "0.33.5"
+ "@img/sharp-linux-arm64" "0.33.5"
+ "@img/sharp-linux-s390x" "0.33.5"
+ "@img/sharp-linux-x64" "0.33.5"
+ "@img/sharp-linuxmusl-arm64" "0.33.5"
+ "@img/sharp-linuxmusl-x64" "0.33.5"
+ "@img/sharp-wasm32" "0.33.5"
+ "@img/sharp-win32-ia32" "0.33.5"
+ "@img/sharp-win32-x64" "0.33.5"
+
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
@@ -2940,6 +3405,13 @@ signal-exit@^4.0.1:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
+simple-swizzle@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
+ integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
+ dependencies:
+ is-arrayish "^0.3.1"
+
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
@@ -2950,11 +3422,21 @@ sonner@^1.4.41:
resolved "https://registry.yarnpkg.com/sonner/-/sonner-1.4.41.tgz#ff085ae4f4244713daf294959beaa3e90f842d2c"
integrity sha512-uG511ggnnsw6gcn/X+YKkWPo5ep9il9wYi3QJxHsYe7yTZ4+cOd1wuodOUmOpFuXL+/RE3R04LczdNCDygTDgQ==
-source-map-js@^1.0.2, source-map-js@^1.2.0:
+source-map-js@^1.0.2:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
+ integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
+
+source-map-js@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
+stack-trace@0.0.x:
+ version "0.0.10"
+ resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
+ integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==
+
streamsearch@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
@@ -3033,6 +3515,13 @@ string.prototype.trimstart@^1.0.8:
define-properties "^1.2.1"
es-object-atoms "^1.0.0"
+string_decoder@^1.1.1:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
+ integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+ dependencies:
+ safe-buffer "~5.2.0"
+
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
@@ -3064,10 +3553,10 @@ strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
-styled-jsx@5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f"
- integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==
+styled-jsx@5.1.6:
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.6.tgz#83b90c077e6c6a80f7f5e8781d0f311b2fe41499"
+ integrity sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==
dependencies:
client-only "0.0.1"
@@ -3141,6 +3630,11 @@ tapable@^2.2.0:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
+text-hex@1.0.x:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
+ integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==
+
text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -3172,6 +3666,11 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
+triple-beam@^1.3.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984"
+ integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==
+
ts-api-utils@^1.0.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1"
@@ -3305,7 +3804,7 @@ use-latest@^1.2.1:
dependencies:
use-isomorphic-layout-effect "^1.1.1"
-util-deprecate@^1.0.2:
+util-deprecate@^1.0.1, util-deprecate@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
@@ -3315,6 +3814,16 @@ uuid@^9.0.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
+validate.io-array@^1.0.3, validate.io-array@^1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/validate.io-array/-/validate.io-array-1.0.6.tgz#5b5a2cafd8f8b85abb2f886ba153f2d93a27774d"
+ integrity sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==
+
+validate.io-function@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/validate.io-function/-/validate.io-function-1.0.2.tgz#343a19802ed3b1968269c780e558e93411c0bad7"
+ integrity sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==
+
web-streams-polyfill@4.0.0-beta.3:
version "4.0.0-beta.3"
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38"
@@ -3395,6 +3904,32 @@ which@^2.0.1:
dependencies:
isexe "^2.0.0"
+winston-transport@^4.9.0:
+ version "4.9.0"
+ resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.9.0.tgz#3bba345de10297654ea6f33519424560003b3bf9"
+ integrity sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==
+ dependencies:
+ logform "^2.7.0"
+ readable-stream "^3.6.2"
+ triple-beam "^1.3.0"
+
+winston@^3.17.0:
+ version "3.17.0"
+ resolved "https://registry.yarnpkg.com/winston/-/winston-3.17.0.tgz#74b8665ce9b4ea7b29d0922cfccf852a08a11423"
+ integrity sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==
+ dependencies:
+ "@colors/colors" "^1.6.0"
+ "@dabh/diagnostics" "^2.0.2"
+ async "^3.2.3"
+ is-stream "^2.0.0"
+ logform "^2.7.0"
+ one-time "^1.0.0"
+ readable-stream "^3.4.0"
+ safe-stable-stringify "^2.3.1"
+ stack-trace "0.0.x"
+ triple-beam "^1.3.0"
+ winston-transport "^4.9.0"
+
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
From e29a08dc46c9ed3374c6dab7706df29329659d2d Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Tue, 18 Mar 2025 10:24:16 +0530
Subject: [PATCH 06/71] feat(ui): add necessary utils
---
ui/lib/types/compute-dot.d.ts | 5 ++
ui/lib/utils/computeSimilarity.ts | 17 ++++++
ui/lib/utils/documents.ts | 97 +++++++++++++++++++++++++++++++
ui/lib/utils/formatHistory.ts | 9 +++
ui/lib/utils/logger.ts | 22 +++++++
5 files changed, 150 insertions(+)
create mode 100644 ui/lib/types/compute-dot.d.ts
create mode 100644 ui/lib/utils/computeSimilarity.ts
create mode 100644 ui/lib/utils/documents.ts
create mode 100644 ui/lib/utils/formatHistory.ts
create mode 100644 ui/lib/utils/logger.ts
diff --git a/ui/lib/types/compute-dot.d.ts b/ui/lib/types/compute-dot.d.ts
new file mode 100644
index 0000000..6bcd481
--- /dev/null
+++ b/ui/lib/types/compute-dot.d.ts
@@ -0,0 +1,5 @@
+declare function computeDot(vectorA: number[], vectorB: number[]): number;
+
+declare module "compute-dot" {
+ export default computeDot;
+}
diff --git a/ui/lib/utils/computeSimilarity.ts b/ui/lib/utils/computeSimilarity.ts
new file mode 100644
index 0000000..a635577
--- /dev/null
+++ b/ui/lib/utils/computeSimilarity.ts
@@ -0,0 +1,17 @@
+import dot from 'compute-dot';
+import cosineSimilarity from 'compute-cosine-similarity';
+import { getSimilarityMeasure } from '../config';
+
+const computeSimilarity = (x: number[], y: number[]): number => {
+ const similarityMeasure = getSimilarityMeasure();
+
+ if (similarityMeasure === 'cosine') {
+ return cosineSimilarity(x, y) as number;
+ } else if (similarityMeasure === 'dot') {
+ return dot(x, y);
+ }
+
+ throw new Error('Invalid similarity measure');
+};
+
+export default computeSimilarity;
diff --git a/ui/lib/utils/documents.ts b/ui/lib/utils/documents.ts
new file mode 100644
index 0000000..07b8bef
--- /dev/null
+++ b/ui/lib/utils/documents.ts
@@ -0,0 +1,97 @@
+import axios from 'axios';
+import { htmlToText } from 'html-to-text';
+import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
+import { Document } from '@langchain/core/documents';
+import pdfParse from 'pdf-parse';
+import logger from './logger';
+
+export const getDocumentsFromLinks = async ({ links }: { links: string[] }) => {
+ const splitter = new RecursiveCharacterTextSplitter();
+
+ let docs: Document[] = [];
+
+ await Promise.all(
+ links.map(async (link) => {
+ link =
+ link.startsWith('http://') || link.startsWith('https://')
+ ? link
+ : `https://${link}`;
+
+ try {
+ const res = await axios.get(link, {
+ responseType: 'arraybuffer',
+ });
+
+ const isPdf = res.headers['content-type'] === 'application/pdf';
+
+ if (isPdf) {
+ const pdfText = await pdfParse(res.data);
+ const parsedText = pdfText.text
+ .replace(/(\r\n|\n|\r)/gm, ' ')
+ .replace(/\s+/g, ' ')
+ .trim();
+
+ const splittedText = await splitter.splitText(parsedText);
+ const title = 'PDF Document';
+
+ const linkDocs = splittedText.map((text) => {
+ return new Document({
+ pageContent: text,
+ metadata: {
+ title: title,
+ url: link,
+ },
+ });
+ });
+
+ docs.push(...linkDocs);
+ return;
+ }
+
+ const parsedText = htmlToText(res.data.toString('utf8'), {
+ selectors: [
+ {
+ selector: 'a',
+ options: {
+ ignoreHref: true,
+ },
+ },
+ ],
+ })
+ .replace(/(\r\n|\n|\r)/gm, ' ')
+ .replace(/\s+/g, ' ')
+ .trim();
+
+ const splittedText = await splitter.splitText(parsedText);
+ const title = res.data
+ .toString('utf8')
+ .match(/(.*?)<\/title>/)?.[1];
+
+ const linkDocs = splittedText.map((text) => {
+ return new Document({
+ pageContent: text,
+ metadata: {
+ title: title || link,
+ url: link,
+ },
+ });
+ });
+
+ docs.push(...linkDocs);
+ } catch (err) {
+ console.error("An error occurred while getting documents from links: ", err);
+ docs.push(
+ new Document({
+ pageContent: `Failed to retrieve content from the link: ${err}`,
+ metadata: {
+ title: 'Failed to retrieve content',
+ url: link,
+ },
+ }),
+ );
+ }
+ }),
+ );
+
+ return docs;
+};
diff --git a/ui/lib/utils/formatHistory.ts b/ui/lib/utils/formatHistory.ts
new file mode 100644
index 0000000..6d0d309
--- /dev/null
+++ b/ui/lib/utils/formatHistory.ts
@@ -0,0 +1,9 @@
+import { BaseMessage } from '@langchain/core/messages';
+
+const formatChatHistoryAsString = (history: BaseMessage[]) => {
+ return history
+ .map((message) => `${message._getType()}: ${message.content}`)
+ .join('\n');
+};
+
+export default formatChatHistoryAsString;
diff --git a/ui/lib/utils/logger.ts b/ui/lib/utils/logger.ts
new file mode 100644
index 0000000..1c81eb9
--- /dev/null
+++ b/ui/lib/utils/logger.ts
@@ -0,0 +1,22 @@
+import winston from 'winston';
+
+const logger = winston.createLogger({
+ level: 'info',
+ transports: [
+ new winston.transports.Console({
+ format: winston.format.combine(
+ winston.format.colorize(),
+ winston.format.simple(),
+ ),
+ }),
+ new winston.transports.File({
+ filename: 'app.log',
+ format: winston.format.combine(
+ winston.format.timestamp(),
+ winston.format.json(),
+ ),
+ }),
+ ],
+});
+
+export default logger;
From e9e34ddff973268de14ab847e57825afc107be71 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Tue, 18 Mar 2025 10:24:33 +0530
Subject: [PATCH 07/71] feat(ui): add meta search agent
---
ui/lib/outputParsers/lineOutputParser.ts | 48 ++
ui/lib/outputParsers/listLineOutputParser.ts | 50 ++
ui/lib/search/metaSearchAgent.ts | 495 +++++++++++++++++++
3 files changed, 593 insertions(+)
create mode 100644 ui/lib/outputParsers/lineOutputParser.ts
create mode 100644 ui/lib/outputParsers/listLineOutputParser.ts
create mode 100644 ui/lib/search/metaSearchAgent.ts
diff --git a/ui/lib/outputParsers/lineOutputParser.ts b/ui/lib/outputParsers/lineOutputParser.ts
new file mode 100644
index 0000000..fcd69ef
--- /dev/null
+++ b/ui/lib/outputParsers/lineOutputParser.ts
@@ -0,0 +1,48 @@
+import { BaseOutputParser } from '@langchain/core/output_parsers';
+
+interface LineOutputParserArgs {
+ key?: string;
+}
+
+class LineOutputParser extends BaseOutputParser {
+ private key = 'questions';
+
+ constructor(args?: LineOutputParserArgs) {
+ super();
+ this.key = args?.key ?? this.key;
+ }
+
+ static lc_name() {
+ return 'LineOutputParser';
+ }
+
+ lc_namespace = ['langchain', 'output_parsers', 'line_output_parser'];
+
+ async parse(text: string): Promise {
+ text = text.trim() || '';
+
+ const regex = /^(\s*(-|\*|\d+\.\s|\d+\)\s|\u2022)\s*)+/;
+ const startKeyIndex = text.indexOf(`<${this.key}>`);
+ const endKeyIndex = text.indexOf(`${this.key}>`);
+
+ if (startKeyIndex === -1 || endKeyIndex === -1) {
+ return '';
+ }
+
+ const questionsStartIndex =
+ startKeyIndex === -1 ? 0 : startKeyIndex + `<${this.key}>`.length;
+ const questionsEndIndex = endKeyIndex === -1 ? text.length : endKeyIndex;
+ const line = text
+ .slice(questionsStartIndex, questionsEndIndex)
+ .trim()
+ .replace(regex, '');
+
+ return line;
+ }
+
+ getFormatInstructions(): string {
+ throw new Error('Not implemented.');
+ }
+}
+
+export default LineOutputParser;
diff --git a/ui/lib/outputParsers/listLineOutputParser.ts b/ui/lib/outputParsers/listLineOutputParser.ts
new file mode 100644
index 0000000..6409db9
--- /dev/null
+++ b/ui/lib/outputParsers/listLineOutputParser.ts
@@ -0,0 +1,50 @@
+import { BaseOutputParser } from '@langchain/core/output_parsers';
+
+interface LineListOutputParserArgs {
+ key?: string;
+}
+
+class LineListOutputParser extends BaseOutputParser {
+ private key = 'questions';
+
+ constructor(args?: LineListOutputParserArgs) {
+ super();
+ this.key = args?.key ?? this.key;
+ }
+
+ static lc_name() {
+ return 'LineListOutputParser';
+ }
+
+ lc_namespace = ['langchain', 'output_parsers', 'line_list_output_parser'];
+
+ async parse(text: string): Promise {
+ text = text.trim() || '';
+
+ const regex = /^(\s*(-|\*|\d+\.\s|\d+\)\s|\u2022)\s*)+/;
+ const startKeyIndex = text.indexOf(`<${this.key}>`);
+ const endKeyIndex = text.indexOf(`${this.key}>`);
+
+ if (startKeyIndex === -1 || endKeyIndex === -1) {
+ return [];
+ }
+
+ const questionsStartIndex =
+ startKeyIndex === -1 ? 0 : startKeyIndex + `<${this.key}>`.length;
+ const questionsEndIndex = endKeyIndex === -1 ? text.length : endKeyIndex;
+ const lines = text
+ .slice(questionsStartIndex, questionsEndIndex)
+ .trim()
+ .split('\n')
+ .filter((line) => line.trim() !== '')
+ .map((line) => line.replace(regex, ''));
+
+ return lines;
+ }
+
+ getFormatInstructions(): string {
+ throw new Error('Not implemented.');
+ }
+}
+
+export default LineListOutputParser;
diff --git a/ui/lib/search/metaSearchAgent.ts b/ui/lib/search/metaSearchAgent.ts
new file mode 100644
index 0000000..a878ab8
--- /dev/null
+++ b/ui/lib/search/metaSearchAgent.ts
@@ -0,0 +1,495 @@
+import { ChatOpenAI } from '@langchain/openai';
+import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
+import type { Embeddings } from '@langchain/core/embeddings';
+import {
+ ChatPromptTemplate,
+ MessagesPlaceholder,
+ PromptTemplate,
+} from '@langchain/core/prompts';
+import {
+ RunnableLambda,
+ RunnableMap,
+ RunnableSequence,
+} from '@langchain/core/runnables';
+import { BaseMessage } from '@langchain/core/messages';
+import { StringOutputParser } from '@langchain/core/output_parsers';
+import LineListOutputParser from '../outputParsers/listLineOutputParser';
+import LineOutputParser from '../outputParsers/lineOutputParser';
+import { getDocumentsFromLinks } from '../utils/documents';
+import { Document } from 'langchain/document';
+import { searchSearxng } from '../searxng';
+import path from 'node:path';
+import fs from 'node:fs';
+import computeSimilarity from '../utils/computeSimilarity';
+import formatChatHistoryAsString from '../utils/formatHistory';
+import eventEmitter from 'events';
+import { StreamEvent } from '@langchain/core/tracers/log_stream';
+
+export interface MetaSearchAgentType {
+ searchAndAnswer: (
+ message: string,
+ history: BaseMessage[],
+ llm: BaseChatModel,
+ embeddings: Embeddings,
+ optimizationMode: 'speed' | 'balanced' | 'quality',
+ fileIds: string[],
+ ) => Promise;
+}
+
+interface Config {
+ searchWeb: boolean;
+ rerank: boolean;
+ summarizer: boolean;
+ rerankThreshold: number;
+ queryGeneratorPrompt: string;
+ responsePrompt: string;
+ activeEngines: string[];
+}
+
+type BasicChainInput = {
+ chat_history: BaseMessage[];
+ query: string;
+};
+
+class MetaSearchAgent implements MetaSearchAgentType {
+ private config: Config;
+ private strParser = new StringOutputParser();
+
+ constructor(config: Config) {
+ this.config = config;
+ }
+
+ private async createSearchRetrieverChain(llm: BaseChatModel) {
+ (llm as unknown as ChatOpenAI).temperature = 0;
+
+ return RunnableSequence.from([
+ PromptTemplate.fromTemplate(this.config.queryGeneratorPrompt),
+ llm,
+ this.strParser,
+ RunnableLambda.from(async (input: string) => {
+ const linksOutputParser = new LineListOutputParser({
+ key: 'links',
+ });
+
+ const questionOutputParser = new LineOutputParser({
+ key: 'question',
+ });
+
+ const links = await linksOutputParser.parse(input);
+ let question = this.config.summarizer
+ ? await questionOutputParser.parse(input)
+ : input;
+
+ if (question === 'not_needed') {
+ return { query: '', docs: [] };
+ }
+
+ if (links.length > 0) {
+ if (question.length === 0) {
+ question = 'summarize';
+ }
+
+ let docs: Document[] = [];
+
+ const linkDocs = await getDocumentsFromLinks({ links });
+
+ const docGroups: Document[] = [];
+
+ linkDocs.map((doc) => {
+ const URLDocExists = docGroups.find(
+ (d) =>
+ d.metadata.url === doc.metadata.url &&
+ d.metadata.totalDocs < 10,
+ );
+
+ if (!URLDocExists) {
+ docGroups.push({
+ ...doc,
+ metadata: {
+ ...doc.metadata,
+ totalDocs: 1,
+ },
+ });
+ }
+
+ const docIndex = docGroups.findIndex(
+ (d) =>
+ d.metadata.url === doc.metadata.url &&
+ d.metadata.totalDocs < 10,
+ );
+
+ if (docIndex !== -1) {
+ docGroups[docIndex].pageContent =
+ docGroups[docIndex].pageContent + `\n\n` + doc.pageContent;
+ docGroups[docIndex].metadata.totalDocs += 1;
+ }
+ });
+
+ await Promise.all(
+ docGroups.map(async (doc) => {
+ const res = await llm.invoke(`
+ You are a web search summarizer, tasked with summarizing a piece of text retrieved from a web search. Your job is to summarize the
+ text into a detailed, 2-4 paragraph explanation that captures the main ideas and provides a comprehensive answer to the query.
+ If the query is \"summarize\", you should provide a detailed summary of the text. If the query is a specific question, you should answer it in the summary.
+
+ - **Journalistic tone**: The summary should sound professional and journalistic, not too casual or vague.
+ - **Thorough and detailed**: Ensure that every key point from the text is captured and that the summary directly answers the query.
+ - **Not too lengthy, but detailed**: The summary should be informative but not excessively long. Focus on providing detailed information in a concise format.
+
+ The text will be shared inside the \`text\` XML tag, and the query inside the \`query\` XML tag.
+
+
+ 1. \`
+ Docker is a set of platform-as-a-service products that use OS-level virtualization to deliver software in packages called containers.
+ It was first released in 2013 and is developed by Docker, Inc. Docker is designed to make it easier to create, deploy, and run applications
+ by using containers.
+
+
+
+ What is Docker and how does it work?
+
+
+ Response:
+ Docker is a revolutionary platform-as-a-service product developed by Docker, Inc., that uses container technology to make application
+ deployment more efficient. It allows developers to package their software with all necessary dependencies, making it easier to run in
+ any environment. Released in 2013, Docker has transformed the way applications are built, deployed, and managed.
+ \`
+ 2. \`
+ The theory of relativity, or simply relativity, encompasses two interrelated theories of Albert Einstein: special relativity and general
+ relativity. However, the word "relativity" is sometimes used in reference to Galilean invariance. The term "theory of relativity" was based
+ on the expression "relative theory" used by Max Planck in 1906. The theory of relativity usually encompasses two interrelated theories by
+ Albert Einstein: special relativity and general relativity. Special relativity applies to all physical phenomena in the absence of gravity.
+ General relativity explains the law of gravitation and its relation to other forces of nature. It applies to the cosmological and astrophysical
+ realm, including astronomy.
+
+
+
+ summarize
+
+
+ Response:
+ The theory of relativity, developed by Albert Einstein, encompasses two main theories: special relativity and general relativity. Special
+ relativity applies to all physical phenomena in the absence of gravity, while general relativity explains the law of gravitation and its
+ relation to other forces of nature. The theory of relativity is based on the concept of "relative theory," as introduced by Max Planck in
+ 1906. It is a fundamental theory in physics that has revolutionized our understanding of the universe.
+ \`
+
+
+ Everything below is the actual data you will be working with. Good luck!
+
+
+ ${question}
+
+
+
+ ${doc.pageContent}
+
+
+ Make sure to answer the query in the summary.
+ `);
+
+ const document = new Document({
+ pageContent: res.content as string,
+ metadata: {
+ title: doc.metadata.title,
+ url: doc.metadata.url,
+ },
+ });
+
+ docs.push(document);
+ }),
+ );
+
+ return { query: question, docs: docs };
+ } else {
+ const res = await searchSearxng(question, {
+ language: 'en',
+ engines: this.config.activeEngines,
+ });
+
+ const documents = res.results.map(
+ (result) =>
+ new Document({
+ pageContent:
+ result.content ||
+ (this.config.activeEngines.includes('youtube')
+ ? result.title
+ : '') /* Todo: Implement transcript grabbing using Youtubei (source: https://www.npmjs.com/package/youtubei) */,
+ metadata: {
+ title: result.title,
+ url: result.url,
+ ...(result.img_src && { img_src: result.img_src }),
+ },
+ }),
+ );
+
+ return { query: question, docs: documents };
+ }
+ }),
+ ]);
+ }
+
+ private async createAnsweringChain(
+ llm: BaseChatModel,
+ fileIds: string[],
+ embeddings: Embeddings,
+ optimizationMode: 'speed' | 'balanced' | 'quality',
+ ) {
+ return RunnableSequence.from([
+ RunnableMap.from({
+ query: (input: BasicChainInput) => input.query,
+ chat_history: (input: BasicChainInput) => input.chat_history,
+ date: () => new Date().toISOString(),
+ context: RunnableLambda.from(async (input: BasicChainInput) => {
+ const processedHistory = formatChatHistoryAsString(
+ input.chat_history,
+ );
+
+ let docs: Document[] | null = null;
+ let query = input.query;
+
+ if (this.config.searchWeb) {
+ const searchRetrieverChain =
+ await this.createSearchRetrieverChain(llm);
+
+ const searchRetrieverResult = await searchRetrieverChain.invoke({
+ chat_history: processedHistory,
+ query,
+ });
+
+ query = searchRetrieverResult.query;
+ docs = searchRetrieverResult.docs;
+ }
+
+ const sortedDocs = await this.rerankDocs(
+ query,
+ docs ?? [],
+ fileIds,
+ embeddings,
+ optimizationMode,
+ );
+
+ return sortedDocs;
+ })
+ .withConfig({
+ runName: 'FinalSourceRetriever',
+ })
+ .pipe(this.processDocs),
+ }),
+ ChatPromptTemplate.fromMessages([
+ ['system', this.config.responsePrompt],
+ new MessagesPlaceholder('chat_history'),
+ ['user', '{query}'],
+ ]),
+ llm,
+ this.strParser,
+ ]).withConfig({
+ runName: 'FinalResponseGenerator',
+ });
+ }
+
+ private async rerankDocs(
+ query: string,
+ docs: Document[],
+ fileIds: string[],
+ embeddings: Embeddings,
+ optimizationMode: 'speed' | 'balanced' | 'quality',
+ ) {
+ if (docs.length === 0 && fileIds.length === 0) {
+ return docs;
+ }
+
+ const filesData = fileIds
+ .map((file) => {
+ const filePath = path.join(process.cwd(), 'uploads', file);
+
+ const contentPath = filePath + '-extracted.json';
+ const embeddingsPath = filePath + '-embeddings.json';
+
+ const content = JSON.parse(fs.readFileSync(contentPath, 'utf8'));
+ const embeddings = JSON.parse(fs.readFileSync(embeddingsPath, 'utf8'));
+
+ const fileSimilaritySearchObject = content.contents.map(
+ (c: string, i: number) => {
+ return {
+ fileName: content.title,
+ content: c,
+ embeddings: embeddings.embeddings[i],
+ };
+ },
+ );
+
+ return fileSimilaritySearchObject;
+ })
+ .flat();
+
+ if (query.toLocaleLowerCase() === 'summarize') {
+ return docs.slice(0, 15);
+ }
+
+ const docsWithContent = docs.filter(
+ (doc) => doc.pageContent && doc.pageContent.length > 0,
+ );
+
+ if (optimizationMode === 'speed' || this.config.rerank === false) {
+ if (filesData.length > 0) {
+ const [queryEmbedding] = await Promise.all([
+ embeddings.embedQuery(query),
+ ]);
+
+ const fileDocs = filesData.map((fileData) => {
+ return new Document({
+ pageContent: fileData.content,
+ metadata: {
+ title: fileData.fileName,
+ url: `File`,
+ },
+ });
+ });
+
+ const similarity = filesData.map((fileData, i) => {
+ const sim = computeSimilarity(queryEmbedding, fileData.embeddings);
+
+ return {
+ index: i,
+ similarity: sim,
+ };
+ });
+
+ let sortedDocs = similarity
+ .filter(
+ (sim) => sim.similarity > (this.config.rerankThreshold ?? 0.3),
+ )
+ .sort((a, b) => b.similarity - a.similarity)
+ .slice(0, 15)
+ .map((sim) => fileDocs[sim.index]);
+
+ sortedDocs =
+ docsWithContent.length > 0 ? sortedDocs.slice(0, 8) : sortedDocs;
+
+ return [
+ ...sortedDocs,
+ ...docsWithContent.slice(0, 15 - sortedDocs.length),
+ ];
+ } else {
+ return docsWithContent.slice(0, 15);
+ }
+ } else if (optimizationMode === 'balanced') {
+ const [docEmbeddings, queryEmbedding] = await Promise.all([
+ embeddings.embedDocuments(
+ docsWithContent.map((doc) => doc.pageContent),
+ ),
+ embeddings.embedQuery(query),
+ ]);
+
+ docsWithContent.push(
+ ...filesData.map((fileData) => {
+ return new Document({
+ pageContent: fileData.content,
+ metadata: {
+ title: fileData.fileName,
+ url: `File`,
+ },
+ });
+ }),
+ );
+
+ docEmbeddings.push(...filesData.map((fileData) => fileData.embeddings));
+
+ const similarity = docEmbeddings.map((docEmbedding, i) => {
+ const sim = computeSimilarity(queryEmbedding, docEmbedding);
+
+ return {
+ index: i,
+ similarity: sim,
+ };
+ });
+
+ const sortedDocs = similarity
+ .filter((sim) => sim.similarity > (this.config.rerankThreshold ?? 0.3))
+ .sort((a, b) => b.similarity - a.similarity)
+ .slice(0, 15)
+ .map((sim) => docsWithContent[sim.index]);
+
+ return sortedDocs;
+ }
+
+ return []
+ }
+
+ private processDocs(docs: Document[]) {
+ return docs
+ .map(
+ (_, index) =>
+ `${index + 1}. ${docs[index].metadata.title} ${docs[index].pageContent}`,
+ )
+ .join('\n');
+ }
+
+ private async handleStream(
+ stream: AsyncGenerator,
+ emitter: eventEmitter,
+ ) {
+ for await (const event of stream) {
+ if (
+ event.event === 'on_chain_end' &&
+ event.name === 'FinalSourceRetriever'
+ ) {
+ ``;
+ emitter.emit(
+ 'data',
+ JSON.stringify({ type: 'sources', data: event.data.output }),
+ );
+ }
+ if (
+ event.event === 'on_chain_stream' &&
+ event.name === 'FinalResponseGenerator'
+ ) {
+ emitter.emit(
+ 'data',
+ JSON.stringify({ type: 'response', data: event.data.chunk }),
+ );
+ }
+ if (
+ event.event === 'on_chain_end' &&
+ event.name === 'FinalResponseGenerator'
+ ) {
+ emitter.emit('end');
+ }
+ }
+ }
+
+ async searchAndAnswer(
+ message: string,
+ history: BaseMessage[],
+ llm: BaseChatModel,
+ embeddings: Embeddings,
+ optimizationMode: 'speed' | 'balanced' | 'quality',
+ fileIds: string[],
+ ) {
+ const emitter = new eventEmitter();
+
+ const answeringChain = await this.createAnsweringChain(
+ llm,
+ fileIds,
+ embeddings,
+ optimizationMode,
+ );
+
+ const stream = answeringChain.streamEvents(
+ {
+ chat_history: history,
+ query: message,
+ },
+ {
+ version: 'v1',
+ },
+ );
+
+ this.handleStream(stream, emitter);
+
+ return emitter;
+ }
+}
+
+export default MetaSearchAgent;
From 6c227cab6fd973135bc51ce9d0f4efc12e5d29d9 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Tue, 18 Mar 2025 10:24:51 +0530
Subject: [PATCH 08/71] feat(providers): move providers to UI
---
ui/lib/providers/index.ts | 72 +++++++++++++++++++++++++++++++
ui/lib/providers/openai.ts | 88 ++++++++++++++++++++++++++++++++++++++
2 files changed, 160 insertions(+)
create mode 100644 ui/lib/providers/index.ts
create mode 100644 ui/lib/providers/openai.ts
diff --git a/ui/lib/providers/index.ts b/ui/lib/providers/index.ts
new file mode 100644
index 0000000..cbb1677
--- /dev/null
+++ b/ui/lib/providers/index.ts
@@ -0,0 +1,72 @@
+import { Embeddings } from '@langchain/core/embeddings';
+import { BaseChatModel } from '@langchain/core/language_models/chat_models';
+import { loadOpenAIChatModels, loadOpenAIEmbeddingModels } from './openai';
+import { getCustomOpenaiApiKey, getCustomOpenaiApiUrl, getCustomOpenaiModelName } from '../config';
+import { ChatOpenAI } from '@langchain/openai';
+
+export interface ChatModelProvider {
+ displayName: string
+ model: BaseChatModel
+}
+
+export interface EmbeddingModelProvider {
+ displayName: string
+ model: Embeddings
+}
+
+const chatModelProviders: Record Promise>> = {
+ openai: loadOpenAIChatModels
+}
+
+const embeddingModelProviders: Record Promise>> = {
+ openai: loadOpenAIEmbeddingModels
+}
+
+export const getAvailableChatModelProviders = async () => {
+ const models: Record> = {};
+
+ for (const provider in chatModelProviders) {
+ const providerModels = await chatModelProviders[provider]();
+ if (Object.keys(providerModels).length > 0) {
+ models[provider] = providerModels;
+ }
+ }
+
+ const customOpenAiApiKey = getCustomOpenaiApiKey();
+ const customOpenAiApiUrl = getCustomOpenaiApiUrl();
+ const customOpenAiModelName = getCustomOpenaiModelName();
+
+ models['custom_openai'] = {
+ ...(customOpenAiApiKey && customOpenAiApiUrl && customOpenAiModelName
+ ? {
+ [customOpenAiModelName]: {
+ displayName: customOpenAiModelName,
+ model: new ChatOpenAI({
+ openAIApiKey: customOpenAiApiKey,
+ modelName: customOpenAiModelName,
+ temperature: 0.7,
+ configuration: {
+ baseURL: customOpenAiApiUrl,
+ },
+ }),
+ },
+ }
+ : {}),
+ };
+
+ return models;
+};
+
+export const getAvailableEmbeddingModelProviders = async () => {
+ const models: Record> = {};
+
+ for (const provider in embeddingModelProviders) {
+ const providerModels = await embeddingModelProviders[provider]();
+ if (Object.keys(providerModels).length > 0) {
+ models[provider] = providerModels;
+ }
+ }
+
+ return models;
+ };
+
\ No newline at end of file
diff --git a/ui/lib/providers/openai.ts b/ui/lib/providers/openai.ts
new file mode 100644
index 0000000..9726957
--- /dev/null
+++ b/ui/lib/providers/openai.ts
@@ -0,0 +1,88 @@
+import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai'
+import { getOpenaiApiKey } from '../config'
+import { ChatModelProvider, EmbeddingModelProvider } from '.'
+
+const openaiChatModels: Record[] = [
+ {
+ displayName: 'GPT-3.5 Turbo',
+ key: 'gpt-3.5-turbo',
+ },
+ {
+ displayName: 'GPT-4',
+ key: 'gpt-4',
+ },
+ {
+ displayName: 'GPT-4 turbo',
+ key: 'gpt-4-turbo',
+ },
+ {
+ displayName: 'GPT-4 omni',
+ key: 'gpt-4o',
+ },
+ {
+ displayName: 'GPT-4 omni mini',
+ key: 'gpt-4o-mini',
+ }
+]
+
+const openaiEmbeddingModels: Record[] = [
+ {
+ displayName: 'Text Embedding 3 Small',
+ key: 'text-embedding-3-small',
+ },
+ {
+ displayName: 'Text Embedding 3 Large',
+ key: 'text-embedding-3-large',
+ }
+]
+
+export const loadOpenAIChatModels = async () => {
+ const openaiApiKey = getOpenaiApiKey()
+
+ if (!openaiApiKey) return {}
+
+ try {
+ const chatModels: Record = {}
+
+ openaiChatModels.forEach(model => {
+ chatModels[model.key] = {
+ displayName: model.displayName,
+ model: new ChatOpenAI({
+ openAIApiKey: openaiApiKey,
+ modelName: model.key,
+ temperature: 0.7
+ })
+ }
+ })
+
+ return chatModels
+ } catch(err) {
+ console.error(`Error loading OpenAI models: ${err}`)
+ return {}
+ }
+}
+
+export const loadOpenAIEmbeddingModels = async () => {
+ const openaiApiKey = getOpenaiApiKey()
+
+ if (!openaiApiKey) return {}
+
+ try {
+ const embeddingModels: Record = {}
+
+ openaiEmbeddingModels.forEach(model => {
+ embeddingModels[model.key] = {
+ displayName: model.displayName,
+ model: new OpenAIEmbeddings({
+ openAIApiKey: openaiApiKey,
+ modelName: model.key,
+ })
+ }
+ })
+
+ return embeddingModels
+ } catch(err) {
+ console.error(`Error loading OpenAI embeddings models: ${err}`)
+ return {}
+ }
+}
\ No newline at end of file
From 97f6196d9b16f4ba95d68e799c54ae96ee8e1524 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Tue, 18 Mar 2025 10:25:09 +0530
Subject: [PATCH 09/71] feat(app): add GET config route
---
ui/app/api/config/route.ts | 55 ++++++++++++++++++++++++++++++++++++++
ui/app/settings/page.tsx | 4 +--
2 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 ui/app/api/config/route.ts
diff --git a/ui/app/api/config/route.ts b/ui/app/api/config/route.ts
new file mode 100644
index 0000000..7bd188e
--- /dev/null
+++ b/ui/app/api/config/route.ts
@@ -0,0 +1,55 @@
+import { getAnthropicApiKey, getCustomOpenaiApiKey, getCustomOpenaiApiUrl, getCustomOpenaiModelName, getGeminiApiKey, getGroqApiKey, getOllamaApiEndpoint, getOpenaiApiKey } from "@/lib/config"
+import { getAvailableChatModelProviders, getAvailableEmbeddingModelProviders } from "@/lib/providers"
+
+export const GET = async (req: Request) => {
+ try {
+ const config: Record = {}
+
+ const [chatModelProviders, embeddingModelProviders] = await Promise.all([
+ getAvailableChatModelProviders(),
+ getAvailableEmbeddingModelProviders(),
+ ])
+
+ config['chatModelProviders'] = {}
+ config['embeddingModelProviders'] = {}
+
+ for (const provider in chatModelProviders) {
+ config['chatModelProviders'][provider] = Object.keys(
+ chatModelProviders[provider],
+ ).map(model => {
+ return {
+ name: model,
+ displayName: chatModelProviders[provider][model].displayName,
+ }
+ })
+ }
+
+ for (const provider in embeddingModelProviders) {
+ config['embeddingModelProviders'][provider] = Object.keys(
+ embeddingModelProviders[provider],
+ ).map(model => {
+ return {
+ name: model,
+ displayName: embeddingModelProviders[provider][model].displayName,
+ }
+ })
+ }
+
+ config['openaiApiKey'] = getOpenaiApiKey()
+ config['ollamaApiUrl'] = getOllamaApiEndpoint()
+ config['anthropicApiKey'] = getAnthropicApiKey()
+ config['groqApiKey'] = getGroqApiKey()
+ config['geminiApiKey'] = getGeminiApiKey()
+ config['customOpenaiApiUrl'] = getCustomOpenaiApiUrl()
+ config['customOpenaiApiKey'] = getCustomOpenaiApiKey()
+ config['customOpenaiModelName'] = getCustomOpenaiModelName()
+
+ return Response.json({ ...config }, { status: 200 })
+ } catch (err) {
+ console.error('An error ocurred while getting config:', err)
+ return Response.json(
+ { message: 'An error ocurred while getting config' },
+ { status: 500 },
+ )
+ }
+}
diff --git a/ui/app/settings/page.tsx b/ui/app/settings/page.tsx
index 6aff1b0..3bd1f2d 100644
--- a/ui/app/settings/page.tsx
+++ b/ui/app/settings/page.tsx
@@ -116,7 +116,7 @@ const Page = () => {
useEffect(() => {
const fetchConfig = async () => {
setIsLoading(true);
- const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/config`, {
+ const res = await fetch(`/api/config`, {
headers: {
'Content-Type': 'application/json',
},
@@ -208,7 +208,7 @@ const Page = () => {
key.toLowerCase().includes('api') ||
key.toLowerCase().includes('url')
) {
- const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/config`, {
+ const res = await fetch(`/api/config`, {
headers: {
'Content-Type': 'application/json',
},
From 4cb20542a5db99e1220a5b3bea9ff6439af8e9d1 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Tue, 18 Mar 2025 10:33:32 +0530
Subject: [PATCH 10/71] feat(config): update file path, add post endpoint
---
ui/app/api/config/route.ts | 102 ++++++++++++++++++++++++++++---------
ui/app/settings/page.tsx | 2 +-
ui/lib/config.ts | 6 +--
3 files changed, 82 insertions(+), 28 deletions(-)
diff --git a/ui/app/api/config/route.ts b/ui/app/api/config/route.ts
index 7bd188e..46c71f5 100644
--- a/ui/app/api/config/route.ts
+++ b/ui/app/api/config/route.ts
@@ -1,55 +1,109 @@
-import { getAnthropicApiKey, getCustomOpenaiApiKey, getCustomOpenaiApiUrl, getCustomOpenaiModelName, getGeminiApiKey, getGroqApiKey, getOllamaApiEndpoint, getOpenaiApiKey } from "@/lib/config"
-import { getAvailableChatModelProviders, getAvailableEmbeddingModelProviders } from "@/lib/providers"
+import {
+ getAnthropicApiKey,
+ getCustomOpenaiApiKey,
+ getCustomOpenaiApiUrl,
+ getCustomOpenaiModelName,
+ getGeminiApiKey,
+ getGroqApiKey,
+ getOllamaApiEndpoint,
+ getOpenaiApiKey,
+ updateConfig,
+} from '@/lib/config';
+import {
+ getAvailableChatModelProviders,
+ getAvailableEmbeddingModelProviders,
+} from '@/lib/providers';
export const GET = async (req: Request) => {
try {
- const config: Record = {}
+ const config: Record = {};
const [chatModelProviders, embeddingModelProviders] = await Promise.all([
getAvailableChatModelProviders(),
getAvailableEmbeddingModelProviders(),
- ])
+ ]);
- config['chatModelProviders'] = {}
- config['embeddingModelProviders'] = {}
+ config['chatModelProviders'] = {};
+ config['embeddingModelProviders'] = {};
for (const provider in chatModelProviders) {
config['chatModelProviders'][provider] = Object.keys(
chatModelProviders[provider],
- ).map(model => {
+ ).map((model) => {
return {
name: model,
displayName: chatModelProviders[provider][model].displayName,
- }
- })
+ };
+ });
}
for (const provider in embeddingModelProviders) {
config['embeddingModelProviders'][provider] = Object.keys(
embeddingModelProviders[provider],
- ).map(model => {
+ ).map((model) => {
return {
name: model,
displayName: embeddingModelProviders[provider][model].displayName,
- }
- })
+ };
+ });
}
- config['openaiApiKey'] = getOpenaiApiKey()
- config['ollamaApiUrl'] = getOllamaApiEndpoint()
- config['anthropicApiKey'] = getAnthropicApiKey()
- config['groqApiKey'] = getGroqApiKey()
- config['geminiApiKey'] = getGeminiApiKey()
- config['customOpenaiApiUrl'] = getCustomOpenaiApiUrl()
- config['customOpenaiApiKey'] = getCustomOpenaiApiKey()
- config['customOpenaiModelName'] = getCustomOpenaiModelName()
+ config['openaiApiKey'] = getOpenaiApiKey();
+ config['ollamaApiUrl'] = getOllamaApiEndpoint();
+ config['anthropicApiKey'] = getAnthropicApiKey();
+ config['groqApiKey'] = getGroqApiKey();
+ config['geminiApiKey'] = getGeminiApiKey();
+ config['customOpenaiApiUrl'] = getCustomOpenaiApiUrl();
+ config['customOpenaiApiKey'] = getCustomOpenaiApiKey();
+ config['customOpenaiModelName'] = getCustomOpenaiModelName();
- return Response.json({ ...config }, { status: 200 })
+ return Response.json({ ...config }, { status: 200 });
} catch (err) {
- console.error('An error ocurred while getting config:', err)
+ console.error('An error ocurred while getting config:', err);
return Response.json(
{ message: 'An error ocurred while getting config' },
{ status: 500 },
- )
+ );
}
-}
+};
+
+export const POST = async (req: Request) => {
+ try {
+ const config = await req.json();
+
+ const updatedConfig = {
+ MODELS: {
+ OPENAI: {
+ API_KEY: config.openaiApiKey,
+ },
+ GROQ: {
+ API_KEY: config.groqApiKey,
+ },
+ ANTHROPIC: {
+ API_KEY: config.anthropicApiKey,
+ },
+ GEMINI: {
+ API_KEY: config.geminiApiKey,
+ },
+ OLLAMA: {
+ API_URL: config.ollamaApiUrl,
+ },
+ CUSTOM_OPENAI: {
+ API_URL: config.customOpenaiApiUrl,
+ API_KEY: config.customOpenaiApiKey,
+ MODEL_NAME: config.customOpenaiModelName,
+ },
+ },
+ };
+
+ updateConfig(updatedConfig);
+
+ return Response.json({ message: 'Config updated' }, { status: 200 });
+ } catch (err) {
+ console.error('An error ocurred while updating config:', err);
+ return Response.json(
+ { message: 'An error ocurred while updating config' },
+ { status: 500 },
+ );
+ }
+};
diff --git a/ui/app/settings/page.tsx b/ui/app/settings/page.tsx
index 3bd1f2d..bcb9b2b 100644
--- a/ui/app/settings/page.tsx
+++ b/ui/app/settings/page.tsx
@@ -188,7 +188,7 @@ const Page = () => {
} as SettingsType;
const response = await fetch(
- `${process.env.NEXT_PUBLIC_API_URL}/config`,
+ `/api/config`,
{
method: 'POST',
headers: {
diff --git a/ui/lib/config.ts b/ui/lib/config.ts
index 1e5148d..0a314cf 100644
--- a/ui/lib/config.ts
+++ b/ui/lib/config.ts
@@ -109,9 +109,9 @@ const mergeConfigs = (current: any, update: any): any => {
export const updateConfig = (config: RecursivePartial) => {
const currentConfig = loadConfig();
const mergedConfig = mergeConfigs(currentConfig, config);
-
+ console.log(mergedConfig);
fs.writeFileSync(
- path.join(__dirname, `../${configFileName}`),
+ path.join(path.join(process.cwd(), `${configFileName}`)),
toml.stringify(mergedConfig),
);
-};
\ No newline at end of file
+};
From 32f26bb4e83fe372f5e645e3b44901bc849777da Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Tue, 18 Mar 2025 11:28:47 +0530
Subject: [PATCH 11/71] feat(app): add groq, gemini & anthropic provider
---
ui/lib/providers/anthropic.ts | 63 +++++++++++++++++
ui/lib/providers/gemini.ts | 94 +++++++++++++++++++++++++
ui/lib/providers/groq.ts | 107 ++++++++++++++++++++++++++++
ui/lib/providers/index.ts | 129 +++++++++++++++++++---------------
ui/lib/providers/ollama.ts | 73 +++++++++++++++++++
5 files changed, 411 insertions(+), 55 deletions(-)
create mode 100644 ui/lib/providers/anthropic.ts
create mode 100644 ui/lib/providers/gemini.ts
create mode 100644 ui/lib/providers/groq.ts
create mode 100644 ui/lib/providers/ollama.ts
diff --git a/ui/lib/providers/anthropic.ts b/ui/lib/providers/anthropic.ts
new file mode 100644
index 0000000..894fda5
--- /dev/null
+++ b/ui/lib/providers/anthropic.ts
@@ -0,0 +1,63 @@
+import { ChatOpenAI } from '@langchain/openai';
+import { ChatModel } from '.';
+import { getAnthropicApiKey } from '../config';
+
+const anthropicChatModels: Record[] = [
+ {
+ displayName: 'Claude 3.7 Sonnet',
+ key: 'claude-3-7-sonnet-20250219',
+ },
+ {
+ displayName: 'Claude 3.5 Haiku',
+ key: 'claude-3-5-haiku-20241022',
+ },
+ {
+ displayName: 'Claude 3.5 Sonnet v2',
+ key: 'claude-3-5-sonnet-20241022',
+ },
+ {
+ displayName: 'Claude 3.5 Sonnet',
+ key: 'claude-3-5-sonnet-20240620',
+ },
+ {
+ displayName: 'Claude 3 Opus',
+ key: 'claude-3-opus-20240229',
+ },
+ {
+ displayName: 'Claude 3 Sonnet',
+ key: 'claude-3-sonnet-20240229',
+ },
+ {
+ displayName: 'Claude 3 Haiku',
+ key: 'claude-3-haiku-20240307',
+ },
+];
+
+export const loadAnthropicChatModels = async () => {
+ const anthropicApiKey = getAnthropicApiKey();
+
+ if (!anthropicApiKey) return {};
+
+ try {
+ const chatModels: Record = {};
+
+ anthropicChatModels.forEach((model) => {
+ chatModels[model.key] = {
+ displayName: model.displayName,
+ model: new ChatOpenAI({
+ openAIApiKey: anthropicApiKey,
+ modelName: model.key,
+ temperature: 0.7,
+ configuration: {
+ baseURL: 'https://api.anthropic.com/v1/',
+ },
+ }),
+ };
+ });
+
+ return chatModels;
+ } catch (err) {
+ console.error(`Error loading Anthropic models: ${err}`);
+ return {};
+ }
+};
diff --git a/ui/lib/providers/gemini.ts b/ui/lib/providers/gemini.ts
new file mode 100644
index 0000000..28a31cf
--- /dev/null
+++ b/ui/lib/providers/gemini.ts
@@ -0,0 +1,94 @@
+import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
+import { getGeminiApiKey } from '../config';
+import { ChatModel, EmbeddingModel } from '.';
+
+const geminiChatModels: Record[] = [
+ {
+ displayName: 'Gemini 2.0 Flash',
+ key: 'gemini-2.0-flash',
+ },
+ {
+ displayName: 'Gemini 2.0 Flash-Lite',
+ key: 'gemini-2.0-flash-lite',
+ },
+ {
+ displayName: 'Gemini 2.0 Pro Experimental',
+ key: 'gemini-2.0-pro-exp-02-05',
+ },
+ {
+ displayName: 'Gemini 1.5 Flash',
+ key: 'gemini-1.5-flash',
+ },
+ {
+ displayName: 'Gemini 1.5 Flash-8B',
+ key: 'gemini-1.5-flash-8b',
+ },
+ {
+ displayName: 'Gemini 1.5 Pro',
+ key: 'gemini-1.5-pro',
+ },
+];
+
+const geminiEmbeddingModels: Record[] = [
+ {
+ displayName: 'Gemini Embedding',
+ key: 'gemini-embedding-exp',
+ },
+];
+
+export const loadGeminiChatModels = async () => {
+ const geminiApiKey = getGeminiApiKey();
+
+ if (!geminiApiKey) return {};
+
+ try {
+ const chatModels: Record = {};
+
+ geminiChatModels.forEach((model) => {
+ chatModels[model.key] = {
+ displayName: model.displayName,
+ model: new ChatOpenAI({
+ openAIApiKey: geminiApiKey,
+ modelName: model.key,
+ temperature: 0.7,
+ configuration: {
+ baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai/',
+ },
+ }),
+ };
+ });
+
+ return chatModels;
+ } catch (err) {
+ console.error(`Error loading Gemini models: ${err}`);
+ return {};
+ }
+};
+
+export const loadGeminiEmbeddingModels = async () => {
+ const geminiApiKey = getGeminiApiKey();
+
+ if (!geminiApiKey) return {};
+
+ try {
+ const embeddingModels: Record = {};
+
+ geminiEmbeddingModels.forEach((model) => {
+ embeddingModels[model.key] = {
+ displayName: model.displayName,
+ model: new OpenAIEmbeddings({
+ openAIApiKey: geminiApiKey,
+ modelName: model.key,
+ configuration: {
+ baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai/',
+ },
+ }),
+ };
+ });
+
+ return embeddingModels;
+ } catch (err) {
+ console.error(`Error loading OpenAI embeddings models: ${err}`);
+ return {};
+ }
+};
diff --git a/ui/lib/providers/groq.ts b/ui/lib/providers/groq.ts
new file mode 100644
index 0000000..05947fb
--- /dev/null
+++ b/ui/lib/providers/groq.ts
@@ -0,0 +1,107 @@
+import { ChatOpenAI } from '@langchain/openai';
+import { getGroqApiKey } from '../config';
+import { ChatModel } from '.';
+
+const groqChatModels: Record[] = [
+ {
+ displayName: 'Gemma2 9B IT',
+ key: 'gemma2-9b-it',
+ },
+ {
+ displayName: 'Llama 3.3 70B Versatile',
+ key: 'llama-3.3-70b-versatile',
+ },
+ {
+ displayName: 'Llama 3.1 8B Instant',
+ key: 'llama-3.1-8b-instant',
+ },
+ {
+ displayName: 'Llama3 70B 8192',
+ key: 'llama3-70b-8192',
+ },
+ {
+ displayName: 'Llama3 8B 8192',
+ key: 'llama3-8b-8192',
+ },
+ {
+ displayName: 'Mixtral 8x7B 32768',
+ key: 'mixtral-8x7b-32768',
+ },
+ {
+ displayName: 'Qwen QWQ 32B (Preview)',
+ key: 'qwen-qwq-32b',
+ },
+ {
+ displayName: 'Mistral Saba 24B (Preview)',
+ key: 'mistral-saba-24b',
+ },
+ {
+ displayName: 'Qwen 2.5 Coder 32B (Preview)',
+ key: 'qwen-2.5-coder-32b',
+ },
+ {
+ displayName: 'Qwen 2.5 32B (Preview)',
+ key: 'qwen-2.5-32b',
+ },
+ {
+ displayName: 'DeepSeek R1 Distill Qwen 32B (Preview)',
+ key: 'deepseek-r1-distill-qwen-32b',
+ },
+ {
+ displayName: 'DeepSeek R1 Distill Llama 70B SpecDec (Preview)',
+ key: 'deepseek-r1-distill-llama-70b-specdec',
+ },
+ {
+ displayName: 'DeepSeek R1 Distill Llama 70B (Preview)',
+ key: 'deepseek-r1-distill-llama-70b',
+ },
+ {
+ displayName: 'Llama 3.3 70B SpecDec (Preview)',
+ key: 'llama-3.3-70b-specdec',
+ },
+ {
+ displayName: 'Llama 3.2 1B Preview (Preview)',
+ key: 'llama-3.2-1b-preview',
+ },
+ {
+ displayName: 'Llama 3.2 3B Preview (Preview)',
+ key: 'llama-3.2-3b-preview',
+ },
+ {
+ displayName: 'Llama 3.2 11B Vision Preview (Preview)',
+ key: 'llama-3.2-11b-vision-preview',
+ },
+ {
+ displayName: 'Llama 3.2 90B Vision Preview (Preview)',
+ key: 'llama-3.2-90b-vision-preview',
+ },
+];
+
+export const loadGroqChatModels = async () => {
+ const groqApiKey = getGroqApiKey();
+
+ if (!groqApiKey) return {};
+
+ try {
+ const chatModels: Record = {};
+
+ groqChatModels.forEach((model) => {
+ chatModels[model.key] = {
+ displayName: model.displayName,
+ model: new ChatOpenAI({
+ openAIApiKey: groqApiKey,
+ modelName: model.key,
+ temperature: 0.7,
+ configuration: {
+ baseURL: 'https://api.groq.com/openai/v1',
+ },
+ }),
+ };
+ });
+
+ return chatModels;
+ } catch (err) {
+ console.error(`Error loading Groq models: ${err}`);
+ return {};
+ }
+};
diff --git a/ui/lib/providers/index.ts b/ui/lib/providers/index.ts
index cbb1677..caa8074 100644
--- a/ui/lib/providers/index.ts
+++ b/ui/lib/providers/index.ts
@@ -1,72 +1,91 @@
import { Embeddings } from '@langchain/core/embeddings';
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
import { loadOpenAIChatModels, loadOpenAIEmbeddingModels } from './openai';
-import { getCustomOpenaiApiKey, getCustomOpenaiApiUrl, getCustomOpenaiModelName } from '../config';
+import {
+ getCustomOpenaiApiKey,
+ getCustomOpenaiApiUrl,
+ getCustomOpenaiModelName,
+} from '../config';
import { ChatOpenAI } from '@langchain/openai';
+import { loadOllamaChatModels, loadOllamaEmbeddingModels } from './ollama';
+import { loadGroqChatModels } from './groq';
+import { loadAnthropicChatModels } from './anthropic';
+import { loadGeminiChatModels, loadGeminiEmbeddingModels } from './gemini';
-export interface ChatModelProvider {
- displayName: string
- model: BaseChatModel
+export interface ChatModel {
+ displayName: string;
+ model: BaseChatModel;
}
-export interface EmbeddingModelProvider {
- displayName: string
- model: Embeddings
+export interface EmbeddingModel {
+ displayName: string;
+ model: Embeddings;
}
-const chatModelProviders: Record Promise>> = {
- openai: loadOpenAIChatModels
-}
+const chatModelProviders: Record<
+ string,
+ () => Promise>
+> = {
+ openai: loadOpenAIChatModels,
+ ollama: loadOllamaChatModels,
+ groq: loadGroqChatModels,
+ anthropic: loadAnthropicChatModels,
+ gemini: loadGeminiChatModels
+};
-const embeddingModelProviders: Record Promise>> = {
- openai: loadOpenAIEmbeddingModels
-}
+const embeddingModelProviders: Record<
+ string,
+ () => Promise>
+> = {
+ openai: loadOpenAIEmbeddingModels,
+ ollama: loadOllamaEmbeddingModels,
+ gemini: loadGeminiEmbeddingModels
+};
export const getAvailableChatModelProviders = async () => {
- const models: Record> = {};
-
- for (const provider in chatModelProviders) {
- const providerModels = await chatModelProviders[provider]();
- if (Object.keys(providerModels).length > 0) {
- models[provider] = providerModels;
- }
+ const models: Record> = {};
+
+ for (const provider in chatModelProviders) {
+ const providerModels = await chatModelProviders[provider]();
+ if (Object.keys(providerModels).length > 0) {
+ models[provider] = providerModels;
}
-
- const customOpenAiApiKey = getCustomOpenaiApiKey();
- const customOpenAiApiUrl = getCustomOpenaiApiUrl();
- const customOpenAiModelName = getCustomOpenaiModelName();
-
- models['custom_openai'] = {
- ...(customOpenAiApiKey && customOpenAiApiUrl && customOpenAiModelName
- ? {
- [customOpenAiModelName]: {
- displayName: customOpenAiModelName,
- model: new ChatOpenAI({
- openAIApiKey: customOpenAiApiKey,
- modelName: customOpenAiModelName,
- temperature: 0.7,
- configuration: {
- baseURL: customOpenAiApiUrl,
- },
- }),
- },
- }
- : {}),
- };
-
- return models;
+ }
+
+ const customOpenAiApiKey = getCustomOpenaiApiKey();
+ const customOpenAiApiUrl = getCustomOpenaiApiUrl();
+ const customOpenAiModelName = getCustomOpenaiModelName();
+
+ models['custom_openai'] = {
+ ...(customOpenAiApiKey && customOpenAiApiUrl && customOpenAiModelName
+ ? {
+ [customOpenAiModelName]: {
+ displayName: customOpenAiModelName,
+ model: new ChatOpenAI({
+ openAIApiKey: customOpenAiApiKey,
+ modelName: customOpenAiModelName,
+ temperature: 0.7,
+ configuration: {
+ baseURL: customOpenAiApiUrl,
+ },
+ }),
+ },
+ }
+ : {}),
+ };
+
+ return models;
};
export const getAvailableEmbeddingModelProviders = async () => {
- const models: Record> = {};
-
- for (const provider in embeddingModelProviders) {
- const providerModels = await embeddingModelProviders[provider]();
- if (Object.keys(providerModels).length > 0) {
- models[provider] = providerModels;
- }
+ const models: Record> = {};
+
+ for (const provider in embeddingModelProviders) {
+ const providerModels = await embeddingModelProviders[provider]();
+ if (Object.keys(providerModels).length > 0) {
+ models[provider] = providerModels;
}
-
- return models;
- };
-
\ No newline at end of file
+ }
+
+ return models;
+};
diff --git a/ui/lib/providers/ollama.ts b/ui/lib/providers/ollama.ts
new file mode 100644
index 0000000..92e98e4
--- /dev/null
+++ b/ui/lib/providers/ollama.ts
@@ -0,0 +1,73 @@
+import axios from 'axios';
+import { getKeepAlive, getOllamaApiEndpoint } from '../config';
+import { ChatModel, EmbeddingModel } from '.';
+import { ChatOllama } from '@langchain/community/chat_models/ollama';
+import { OllamaEmbeddings } from '@langchain/community/embeddings/ollama';
+
+export const loadOllamaChatModels = async () => {
+ const ollamaApiEndpoint = getOllamaApiEndpoint();
+
+ if (!ollamaApiEndpoint) return {};
+
+ try {
+ const res = await axios.get(`${ollamaApiEndpoint}/api/tags`, {
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+
+ const { models } = res.data;
+
+ const chatModels: Record = {};
+
+ models.forEach((model: any) => {
+ chatModels[model.model] = {
+ displayName: model.name,
+ model: new ChatOllama({
+ baseUrl: ollamaApiEndpoint,
+ model: model.model,
+ temperature: 0.7,
+ keepAlive: getKeepAlive(),
+ }),
+ };
+ });
+
+ return chatModels;
+ } catch (err) {
+ console.error(`Error loading Ollama models: ${err}`);
+ return {};
+ }
+};
+
+export const loadOllamaEmbeddingModels = async () => {
+ const ollamaApiEndpoint = getOllamaApiEndpoint();
+
+ if (!ollamaApiEndpoint) return {};
+
+ try {
+ const res = await axios.get(`${ollamaApiEndpoint}/api/tags`, {
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+
+ const { models } = res.data;
+
+ const embeddingModels: Record = {};
+
+ models.forEach((model: any) => {
+ embeddingModels[model.model] = {
+ displayName: model.name,
+ model: new OllamaEmbeddings({
+ baseUrl: ollamaApiEndpoint,
+ model: model.model,
+ }),
+ };
+ });
+
+ return embeddingModels;
+ } catch (err) {
+ console.error(`Error loading Ollama embeddings models: ${err}`);
+ return {};
+ }
+};
From ee6e197ec034323d5ef34382c26ab919ecd4942e Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Tue, 18 Mar 2025 11:29:04 +0530
Subject: [PATCH 12/71] feat(app): lint & beautify
---
ui/app/settings/page.tsx | 15 ++---
ui/lib/providers/openai.ts | 106 +++++++++++++++----------------
ui/lib/search/metaSearchAgent.ts | 2 +-
ui/lib/types/compute-dot.d.ts | 2 +-
ui/lib/utils/documents.ts | 5 +-
ui/next.config.mjs | 2 +-
6 files changed, 66 insertions(+), 66 deletions(-)
diff --git a/ui/app/settings/page.tsx b/ui/app/settings/page.tsx
index bcb9b2b..efe54d5 100644
--- a/ui/app/settings/page.tsx
+++ b/ui/app/settings/page.tsx
@@ -187,16 +187,13 @@ const Page = () => {
[key]: value,
} as SettingsType;
- const response = await fetch(
- `/api/config`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(updatedConfig),
+ const response = await fetch(`/api/config`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ body: JSON.stringify(updatedConfig),
+ });
if (!response.ok) {
throw new Error('Failed to update config');
diff --git a/ui/lib/providers/openai.ts b/ui/lib/providers/openai.ts
index 9726957..c6b938d 100644
--- a/ui/lib/providers/openai.ts
+++ b/ui/lib/providers/openai.ts
@@ -1,6 +1,6 @@
-import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai'
-import { getOpenaiApiKey } from '../config'
-import { ChatModelProvider, EmbeddingModelProvider } from '.'
+import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
+import { getOpenaiApiKey } from '../config';
+import { ChatModel, EmbeddingModel } from '.';
const openaiChatModels: Record[] = [
{
@@ -22,67 +22,67 @@ const openaiChatModels: Record[] = [
{
displayName: 'GPT-4 omni mini',
key: 'gpt-4o-mini',
- }
-]
+ },
+];
const openaiEmbeddingModels: Record[] = [
- {
- displayName: 'Text Embedding 3 Small',
- key: 'text-embedding-3-small',
- },
- {
- displayName: 'Text Embedding 3 Large',
- key: 'text-embedding-3-large',
- }
-]
+ {
+ displayName: 'Text Embedding 3 Small',
+ key: 'text-embedding-3-small',
+ },
+ {
+ displayName: 'Text Embedding 3 Large',
+ key: 'text-embedding-3-large',
+ },
+];
export const loadOpenAIChatModels = async () => {
- const openaiApiKey = getOpenaiApiKey()
+ const openaiApiKey = getOpenaiApiKey();
- if (!openaiApiKey) return {}
+ if (!openaiApiKey) return {};
- try {
- const chatModels: Record = {}
+ try {
+ const chatModels: Record = {};
- openaiChatModels.forEach(model => {
- chatModels[model.key] = {
- displayName: model.displayName,
- model: new ChatOpenAI({
- openAIApiKey: openaiApiKey,
- modelName: model.key,
- temperature: 0.7
- })
- }
- })
+ openaiChatModels.forEach((model) => {
+ chatModels[model.key] = {
+ displayName: model.displayName,
+ model: new ChatOpenAI({
+ openAIApiKey: openaiApiKey,
+ modelName: model.key,
+ temperature: 0.7,
+ }),
+ };
+ });
- return chatModels
- } catch(err) {
- console.error(`Error loading OpenAI models: ${err}`)
- return {}
- }
-}
+ return chatModels;
+ } catch (err) {
+ console.error(`Error loading OpenAI models: ${err}`);
+ return {};
+ }
+};
export const loadOpenAIEmbeddingModels = async () => {
- const openaiApiKey = getOpenaiApiKey()
+ const openaiApiKey = getOpenaiApiKey();
- if (!openaiApiKey) return {}
+ if (!openaiApiKey) return {};
- try {
- const embeddingModels: Record = {}
+ try {
+ const embeddingModels: Record = {};
- openaiEmbeddingModels.forEach(model => {
- embeddingModels[model.key] = {
- displayName: model.displayName,
- model: new OpenAIEmbeddings({
- openAIApiKey: openaiApiKey,
- modelName: model.key,
- })
- }
- })
+ openaiEmbeddingModels.forEach((model) => {
+ embeddingModels[model.key] = {
+ displayName: model.displayName,
+ model: new OpenAIEmbeddings({
+ openAIApiKey: openaiApiKey,
+ modelName: model.key,
+ }),
+ };
+ });
- return embeddingModels
- } catch(err) {
- console.error(`Error loading OpenAI embeddings models: ${err}`)
- return {}
- }
-}
\ No newline at end of file
+ return embeddingModels;
+ } catch (err) {
+ console.error(`Error loading OpenAI embeddings models: ${err}`);
+ return {};
+ }
+};
diff --git a/ui/lib/search/metaSearchAgent.ts b/ui/lib/search/metaSearchAgent.ts
index a878ab8..38ea2a0 100644
--- a/ui/lib/search/metaSearchAgent.ts
+++ b/ui/lib/search/metaSearchAgent.ts
@@ -414,7 +414,7 @@ class MetaSearchAgent implements MetaSearchAgentType {
return sortedDocs;
}
- return []
+ return [];
}
private processDocs(docs: Document[]) {
diff --git a/ui/lib/types/compute-dot.d.ts b/ui/lib/types/compute-dot.d.ts
index 6bcd481..b671c64 100644
--- a/ui/lib/types/compute-dot.d.ts
+++ b/ui/lib/types/compute-dot.d.ts
@@ -1,5 +1,5 @@
declare function computeDot(vectorA: number[], vectorB: number[]): number;
-declare module "compute-dot" {
+declare module 'compute-dot' {
export default computeDot;
}
diff --git a/ui/lib/utils/documents.ts b/ui/lib/utils/documents.ts
index 07b8bef..900d6b0 100644
--- a/ui/lib/utils/documents.ts
+++ b/ui/lib/utils/documents.ts
@@ -79,7 +79,10 @@ export const getDocumentsFromLinks = async ({ links }: { links: string[] }) => {
docs.push(...linkDocs);
} catch (err) {
- console.error("An error occurred while getting documents from links: ", err);
+ console.error(
+ 'An error occurred while getting documents from links: ',
+ err,
+ );
docs.push(
new Document({
pageContent: `Failed to retrieve content from the link: ${err}`,
diff --git a/ui/next.config.mjs b/ui/next.config.mjs
index a5db257..74156d1 100644
--- a/ui/next.config.mjs
+++ b/ui/next.config.mjs
@@ -7,7 +7,7 @@ const nextConfig = {
},
],
},
- serverExternalPackages: ['pdf-parse']
+ serverExternalPackages: ['pdf-parse'],
};
export default nextConfig;
From 3bf2337697985c18a674571f30947d41f9bd4e57 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Wed, 19 Mar 2025 13:37:01 +0530
Subject: [PATCH 13/71] feat(app): add db & schema
---
ui/drizzle.config.ts | 10 +
ui/lib/db/index.ts | 11 +
ui/lib/db/schema.ts | 28 ++
ui/package.json | 9 +-
ui/tsconfig.json | 21 +-
ui/yarn.lock | 620 +++++++++++++++++++++++++++++++++++++++++--
6 files changed, 664 insertions(+), 35 deletions(-)
create mode 100644 ui/drizzle.config.ts
create mode 100644 ui/lib/db/index.ts
create mode 100644 ui/lib/db/schema.ts
diff --git a/ui/drizzle.config.ts b/ui/drizzle.config.ts
new file mode 100644
index 0000000..76b84a9
--- /dev/null
+++ b/ui/drizzle.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'drizzle-kit';
+
+export default defineConfig({
+ dialect: 'sqlite',
+ schema: './lib/db/schema.ts',
+ out: './drizzle',
+ dbCredentials: {
+ url: './data/db.sqlite',
+ },
+});
diff --git a/ui/lib/db/index.ts b/ui/lib/db/index.ts
new file mode 100644
index 0000000..9b761d4
--- /dev/null
+++ b/ui/lib/db/index.ts
@@ -0,0 +1,11 @@
+import { drizzle } from 'drizzle-orm/better-sqlite3';
+import Database from 'better-sqlite3';
+import * as schema from './schema';
+import path from 'path';
+
+const sqlite = new Database(path.join(process.cwd(), 'data/db.sqlite'));
+const db = drizzle(sqlite, {
+ schema: schema,
+});
+
+export default db;
diff --git a/ui/lib/db/schema.ts b/ui/lib/db/schema.ts
new file mode 100644
index 0000000..cee9660
--- /dev/null
+++ b/ui/lib/db/schema.ts
@@ -0,0 +1,28 @@
+import { sql } from 'drizzle-orm';
+import { text, integer, sqliteTable } from 'drizzle-orm/sqlite-core';
+
+export const messages = sqliteTable('messages', {
+ id: integer('id').primaryKey(),
+ content: text('content').notNull(),
+ chatId: text('chatId').notNull(),
+ messageId: text('messageId').notNull(),
+ role: text('type', { enum: ['assistant', 'user'] }),
+ metadata: text('metadata', {
+ mode: 'json',
+ }),
+});
+
+interface File {
+ name: string;
+ fileId: string;
+}
+
+export const chats = sqliteTable('chats', {
+ id: text('id').primaryKey(),
+ title: text('title').notNull(),
+ createdAt: text('createdAt').notNull(),
+ focusMode: text('focusMode').notNull(),
+ files: text('files', { mode: 'json' })
+ .$type()
+ .default(sql`'[]'`),
+});
diff --git a/ui/package.json b/ui/package.json
index c9a7a94..9be9447 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -8,18 +8,21 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
- "format:write": "prettier . --write"
+ "format:write": "prettier . --write",
+ "db:push": "drizzle-kit push sqlite"
},
"dependencies": {
"@headlessui/react": "^2.2.0",
"@iarna/toml": "^2.2.5",
- "@icons-pack/react-simple-icons": "^9.4.0",
+ "@icons-pack/react-simple-icons": "^12.3.0",
"@langchain/openai": "^0.0.25",
"@tailwindcss/typography": "^0.5.12",
"axios": "^1.8.3",
+ "better-sqlite3": "^11.9.1",
"clsx": "^2.1.0",
"compute-cosine-similarity": "^1.1.0",
"compute-dot": "^1.1.0",
+ "drizzle-orm": "^0.40.1",
"html-to-text": "^9.0.5",
"langchain": "^0.1.30",
"lucide-react": "^0.363.0",
@@ -38,12 +41,14 @@
"zod": "^3.22.4"
},
"devDependencies": {
+ "@types/better-sqlite3": "^7.6.12",
"@types/html-to-text": "^9.0.4",
"@types/node": "^20",
"@types/pdf-parse": "^1.1.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
+ "drizzle-kit": "^0.30.5",
"eslint": "^8",
"eslint-config-next": "14.1.4",
"postcss": "^8",
diff --git a/ui/tsconfig.json b/ui/tsconfig.json
index d81d4ee..64c2104 100644
--- a/ui/tsconfig.json
+++ b/ui/tsconfig.json
@@ -1,10 +1,6 @@
{
"compilerOptions": {
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
+ "lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -22,19 +18,10 @@
}
],
"paths": {
- "@/*": [
- "./*"
- ]
+ "@/*": ["./*"]
},
"target": "ES2017"
},
- "include": [
- "next-env.d.ts",
- "**/*.ts",
- "**/*.tsx",
- ".next/types/**/*.ts"
- ],
- "exclude": [
- "node_modules"
- ]
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules"]
}
diff --git a/ui/yarn.lock b/ui/yarn.lock
index 427693e..259436c 100644
--- a/ui/yarn.lock
+++ b/ui/yarn.lock
@@ -48,6 +48,11 @@
enabled "2.0.x"
kuler "^2.0.0"
+"@drizzle-team/brocli@^0.10.2":
+ version "0.10.2"
+ resolved "https://registry.yarnpkg.com/@drizzle-team/brocli/-/brocli-0.10.2.tgz#9757c006a43daaa6f45512e6cf5fabed36fb9da7"
+ integrity sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==
+
"@emnapi/runtime@^1.2.0":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60"
@@ -55,6 +60,247 @@
dependencies:
tslib "^2.4.0"
+"@esbuild-kit/core-utils@^3.3.2":
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz#186b6598a5066f0413471d7c4d45828e399ba96c"
+ integrity sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==
+ dependencies:
+ esbuild "~0.18.20"
+ source-map-support "^0.5.21"
+
+"@esbuild-kit/esm-loader@^2.5.5":
+ version "2.6.5"
+ resolved "https://registry.yarnpkg.com/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz#6eedee46095d7d13b1efc381e2211ed1c60e64ea"
+ integrity sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==
+ dependencies:
+ "@esbuild-kit/core-utils" "^3.3.2"
+ get-tsconfig "^4.7.0"
+
+"@esbuild/aix-ppc64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f"
+ integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==
+
+"@esbuild/android-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
+ integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
+
+"@esbuild/android-arm64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4"
+ integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==
+
+"@esbuild/android-arm@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682"
+ integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
+
+"@esbuild/android-arm@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824"
+ integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==
+
+"@esbuild/android-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2"
+ integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
+
+"@esbuild/android-x64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d"
+ integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==
+
+"@esbuild/darwin-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1"
+ integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
+
+"@esbuild/darwin-arm64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e"
+ integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==
+
+"@esbuild/darwin-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d"
+ integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
+
+"@esbuild/darwin-x64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd"
+ integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==
+
+"@esbuild/freebsd-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54"
+ integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
+
+"@esbuild/freebsd-arm64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487"
+ integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==
+
+"@esbuild/freebsd-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e"
+ integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
+
+"@esbuild/freebsd-x64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c"
+ integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==
+
+"@esbuild/linux-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0"
+ integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
+
+"@esbuild/linux-arm64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b"
+ integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==
+
+"@esbuild/linux-arm@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0"
+ integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
+
+"@esbuild/linux-arm@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef"
+ integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==
+
+"@esbuild/linux-ia32@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7"
+ integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
+
+"@esbuild/linux-ia32@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601"
+ integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==
+
+"@esbuild/linux-loong64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d"
+ integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
+
+"@esbuild/linux-loong64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299"
+ integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==
+
+"@esbuild/linux-mips64el@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231"
+ integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
+
+"@esbuild/linux-mips64el@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec"
+ integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==
+
+"@esbuild/linux-ppc64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb"
+ integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
+
+"@esbuild/linux-ppc64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8"
+ integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==
+
+"@esbuild/linux-riscv64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6"
+ integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
+
+"@esbuild/linux-riscv64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf"
+ integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==
+
+"@esbuild/linux-s390x@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071"
+ integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
+
+"@esbuild/linux-s390x@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8"
+ integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==
+
+"@esbuild/linux-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338"
+ integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
+
+"@esbuild/linux-x64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78"
+ integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==
+
+"@esbuild/netbsd-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1"
+ integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
+
+"@esbuild/netbsd-x64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b"
+ integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==
+
+"@esbuild/openbsd-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae"
+ integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
+
+"@esbuild/openbsd-x64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0"
+ integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==
+
+"@esbuild/sunos-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d"
+ integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
+
+"@esbuild/sunos-x64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30"
+ integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==
+
+"@esbuild/win32-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9"
+ integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
+
+"@esbuild/win32-arm64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae"
+ integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==
+
+"@esbuild/win32-ia32@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102"
+ integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
+
+"@esbuild/win32-ia32@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67"
+ integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==
+
+"@esbuild/win32-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
+ integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
+
+"@esbuild/win32-x64@0.19.12":
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae"
+ integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==
+
"@eslint-community/eslint-utils@^4.2.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
@@ -157,10 +403,10 @@
resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c"
integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==
-"@icons-pack/react-simple-icons@^9.4.0":
- version "9.4.0"
- resolved "https://registry.yarnpkg.com/@icons-pack/react-simple-icons/-/react-simple-icons-9.4.0.tgz#37871d830f9ec9cfa1d1aab186036df2ab075f26"
- integrity sha512-fZtC4Zv53hE+IQE2dJlFt3EB6UOifwTrUNMuEu4hSXemtqMahd05Dpvj2K0j2ewVc+j/ibavud3xjfaMB2Nj7g==
+"@icons-pack/react-simple-icons@^12.3.0":
+ version "12.3.0"
+ resolved "https://registry.yarnpkg.com/@icons-pack/react-simple-icons/-/react-simple-icons-12.3.0.tgz#2089c8226842611d751fc86fa93fea053076db77"
+ integrity sha512-71KKdd2tg36Pctg5pQTAmPRIdFrtxsLccoSexkZLztn46eV6Ek6ov69o0Ph4t4ZPs6n4+Fw4sBnIzEsKssnXxg==
"@img/sharp-darwin-arm64@0.33.5":
version "0.33.5"
@@ -445,6 +691,11 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
+"@petamoriken/float16@^3.8.7":
+ version "3.9.2"
+ resolved "https://registry.yarnpkg.com/@petamoriken/float16/-/float16-3.9.2.tgz#217a5d349f3655b8e286be447e0ed1eae063a78f"
+ integrity sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==
+
"@pkgjs/parseargs@^0.11.0":
version "0.11.0"
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
@@ -548,6 +799,13 @@
resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.10.9.tgz#55710c92b311fdaa8d8c66682a0dbdd684bc77c4"
integrity sha512-kBknKOKzmeR7lN+vSadaKWXaLS0SZZG+oqpQ/k80Q6g9REn6zRHS/ZYdrIzHnpHgy/eWs00SujveUN/GJT2qTw==
+"@types/better-sqlite3@^7.6.12":
+ version "7.6.12"
+ resolved "https://registry.yarnpkg.com/@types/better-sqlite3/-/better-sqlite3-7.6.12.tgz#e5712d46d71097dcc2775c0b068072eadc15deb7"
+ integrity sha512-fnQmj8lELIj7BSrZQAdBMHEHX8OZLYIHXqAKT1O7tDfLxaINzf00PMjw22r3N/xXh0w/sGHlO6SVaCQ2mj78lg==
+ dependencies:
+ "@types/node" "*"
+
"@types/html-to-text@^9.0.4":
version "9.0.4"
resolved "https://registry.yarnpkg.com/@types/html-to-text/-/html-to-text-9.0.4.tgz#4a83dd8ae8bfa91457d0b1ffc26f4d0537eff58c"
@@ -931,11 +1189,19 @@ base-64@^0.1.0:
resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb"
integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==
-base64-js@^1.5.1:
+base64-js@^1.3.1, base64-js@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+better-sqlite3@^11.9.1:
+ version "11.9.1"
+ resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-11.9.1.tgz#0540da2f2ce24cbd766bb35db412f4be2c75b8bb"
+ integrity sha512-Ba0KR+Fzxh2jDRhdg6TSH0SJGzb8C0aBY4hR8w8madIdIzzC6Y1+kx5qR6eS1Z+Gy20h6ZU28aeyg0z1VIrShQ==
+ dependencies:
+ bindings "^1.5.0"
+ prebuild-install "^7.1.1"
+
binary-extensions@^2.0.0, binary-extensions@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
@@ -946,6 +1212,22 @@ binary-search@^1.3.5:
resolved "https://registry.yarnpkg.com/binary-search/-/binary-search-1.3.6.tgz#e32426016a0c5092f0f3598836a1c7da3560565c"
integrity sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==
+bindings@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
+ integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
+ dependencies:
+ file-uri-to-path "1.0.0"
+
+bl@^4.0.3:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
+ integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
+ dependencies:
+ buffer "^5.5.0"
+ inherits "^2.0.4"
+ readable-stream "^3.4.0"
+
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -978,6 +1260,19 @@ browserslist@^4.23.0:
node-releases "^2.0.14"
update-browserslist-db "^1.0.13"
+buffer-from@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
+ integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+
+buffer@^5.5.0:
+ version "5.7.1"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
+ integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
+ dependencies:
+ base64-js "^1.3.1"
+ ieee754 "^1.1.13"
+
busboy@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
@@ -1049,6 +1344,11 @@ chokidar@^3.5.3:
optionalDependencies:
fsevents "~2.3.2"
+chownr@^1.1.1:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
+ integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
+
client-only@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
@@ -1243,6 +1543,18 @@ decamelize@1.2.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
+decompress-response@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
+ integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
+ dependencies:
+ mimic-response "^3.1.0"
+
+deep-extend@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
+ integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
+
deep-is@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@@ -1281,7 +1593,7 @@ dequal@^2.0.3:
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
-detect-libc@^2.0.3:
+detect-libc@^2.0.0, detect-libc@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==
@@ -1355,6 +1667,22 @@ domutils@^3.0.1:
domelementtype "^2.3.0"
domhandler "^5.0.3"
+drizzle-kit@^0.30.5:
+ version "0.30.5"
+ resolved "https://registry.yarnpkg.com/drizzle-kit/-/drizzle-kit-0.30.5.tgz#fce34a8ca9f82da5212f31c266e407c78523166f"
+ integrity sha512-l6dMSE100u7sDaTbLczibrQZjA35jLsHNqIV+jmhNVO3O8jzM6kywMOmV9uOz9ZVSCMPQhAZEFjL/qDPVrqpUA==
+ dependencies:
+ "@drizzle-team/brocli" "^0.10.2"
+ "@esbuild-kit/esm-loader" "^2.5.5"
+ esbuild "^0.19.7"
+ esbuild-register "^3.5.0"
+ gel "^2.0.0"
+
+drizzle-orm@^0.40.1:
+ version "0.40.1"
+ resolved "https://registry.yarnpkg.com/drizzle-orm/-/drizzle-orm-0.40.1.tgz#15f1d970d4fb034db2b13e4a33fcbbccda9bf1cb"
+ integrity sha512-aPNhtiJiPfm3qxz1czrnIDkfvkSdKGXYeZkpG55NPTVI186LmK2fBLMi4dsHpPHlJrZeQ92D322YFPHADBALew==
+
eastasianwidth@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
@@ -1380,6 +1708,13 @@ enabled@2.0.x:
resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2"
integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==
+end-of-stream@^1.1.0, end-of-stream@^1.4.1:
+ version "1.4.4"
+ resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
+ integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
+ dependencies:
+ once "^1.4.0"
+
enhanced-resolve@^5.12.0:
version "5.16.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz#65ec88778083056cb32487faa9aef82ed0864787"
@@ -1393,6 +1728,11 @@ entities@^4.2.0, entities@^4.4.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+env-paths@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-3.0.0.tgz#2f1e89c2f6dbd3408e1b1711dd82d62e317f58da"
+ integrity sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==
+
es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2:
version "1.23.3"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0"
@@ -1509,6 +1849,70 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
+esbuild-register@^3.5.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-3.6.0.tgz#cf270cfa677baebbc0010ac024b823cbf723a36d"
+ integrity sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==
+ dependencies:
+ debug "^4.3.4"
+
+esbuild@^0.19.7:
+ version "0.19.12"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.12.tgz#dc82ee5dc79e82f5a5c3b4323a2a641827db3e04"
+ integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==
+ optionalDependencies:
+ "@esbuild/aix-ppc64" "0.19.12"
+ "@esbuild/android-arm" "0.19.12"
+ "@esbuild/android-arm64" "0.19.12"
+ "@esbuild/android-x64" "0.19.12"
+ "@esbuild/darwin-arm64" "0.19.12"
+ "@esbuild/darwin-x64" "0.19.12"
+ "@esbuild/freebsd-arm64" "0.19.12"
+ "@esbuild/freebsd-x64" "0.19.12"
+ "@esbuild/linux-arm" "0.19.12"
+ "@esbuild/linux-arm64" "0.19.12"
+ "@esbuild/linux-ia32" "0.19.12"
+ "@esbuild/linux-loong64" "0.19.12"
+ "@esbuild/linux-mips64el" "0.19.12"
+ "@esbuild/linux-ppc64" "0.19.12"
+ "@esbuild/linux-riscv64" "0.19.12"
+ "@esbuild/linux-s390x" "0.19.12"
+ "@esbuild/linux-x64" "0.19.12"
+ "@esbuild/netbsd-x64" "0.19.12"
+ "@esbuild/openbsd-x64" "0.19.12"
+ "@esbuild/sunos-x64" "0.19.12"
+ "@esbuild/win32-arm64" "0.19.12"
+ "@esbuild/win32-ia32" "0.19.12"
+ "@esbuild/win32-x64" "0.19.12"
+
+esbuild@~0.18.20:
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6"
+ integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==
+ optionalDependencies:
+ "@esbuild/android-arm" "0.18.20"
+ "@esbuild/android-arm64" "0.18.20"
+ "@esbuild/android-x64" "0.18.20"
+ "@esbuild/darwin-arm64" "0.18.20"
+ "@esbuild/darwin-x64" "0.18.20"
+ "@esbuild/freebsd-arm64" "0.18.20"
+ "@esbuild/freebsd-x64" "0.18.20"
+ "@esbuild/linux-arm" "0.18.20"
+ "@esbuild/linux-arm64" "0.18.20"
+ "@esbuild/linux-ia32" "0.18.20"
+ "@esbuild/linux-loong64" "0.18.20"
+ "@esbuild/linux-mips64el" "0.18.20"
+ "@esbuild/linux-ppc64" "0.18.20"
+ "@esbuild/linux-riscv64" "0.18.20"
+ "@esbuild/linux-s390x" "0.18.20"
+ "@esbuild/linux-x64" "0.18.20"
+ "@esbuild/netbsd-x64" "0.18.20"
+ "@esbuild/openbsd-x64" "0.18.20"
+ "@esbuild/sunos-x64" "0.18.20"
+ "@esbuild/win32-arm64" "0.18.20"
+ "@esbuild/win32-ia32" "0.18.20"
+ "@esbuild/win32-x64" "0.18.20"
+
escalade@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
@@ -1737,6 +2141,11 @@ eventemitter3@^4.0.4:
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
+expand-template@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
+ integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
+
expr-eval@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/expr-eval/-/expr-eval-2.0.2.tgz#fa6f044a7b0c93fde830954eb9c5b0f7fbc7e201"
@@ -1787,6 +2196,11 @@ file-entry-cache@^6.0.1:
dependencies:
flat-cache "^3.0.4"
+file-uri-to-path@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
+ integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
+
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
@@ -1873,6 +2287,11 @@ fraction.js@^4.3.7:
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
+fs-constants@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
+ integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
+
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -1903,6 +2322,18 @@ functions-have-names@^1.2.3:
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
+gel@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/gel/-/gel-2.0.1.tgz#587d89db54351c2d436de981d136481e37d06a7a"
+ integrity sha512-gfem3IGvqKqXwEq7XseBogyaRwGsQGuE7Cw/yQsjLGdgiyqX92G1xENPCE0ltunPGcsJIa6XBOTx/PK169mOqw==
+ dependencies:
+ "@petamoriken/float16" "^3.8.7"
+ debug "^4.3.4"
+ env-paths "^3.0.0"
+ semver "^7.6.2"
+ shell-quote "^1.8.1"
+ which "^4.0.0"
+
get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
@@ -1930,6 +2361,18 @@ get-tsconfig@^4.5.0:
dependencies:
resolve-pkg-maps "^1.0.0"
+get-tsconfig@^4.7.0:
+ version "4.10.0"
+ resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.10.0.tgz#403a682b373a823612475a4c2928c7326fc0f6bb"
+ integrity sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==
+ dependencies:
+ resolve-pkg-maps "^1.0.0"
+
+github-from-package@0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
+ integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==
+
glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@@ -2090,6 +2533,11 @@ humanize-ms@^1.2.1:
dependencies:
ms "^2.0.0"
+ieee754@^1.1.13:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
+ integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
+
ignore@^5.2.0:
version "5.3.1"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef"
@@ -2116,11 +2564,16 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@^2.0.3:
+inherits@2, inherits@^2.0.3, inherits@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+ini@~1.3.0:
+ version "1.3.8"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
+ integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
+
internal-slot@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802"
@@ -2342,6 +2795,11 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+isexe@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d"
+ integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==
+
iterator.prototype@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0"
@@ -2611,6 +3069,11 @@ mime-types@^2.1.12:
dependencies:
mime-db "1.52.0"
+mimic-response@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
+ integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
+
minimatch@9.0.3:
version "9.0.3"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825"
@@ -2632,7 +3095,7 @@ minimatch@^9.0.1:
dependencies:
brace-expansion "^2.0.1"
-minimist@^1.2.0, minimist@^1.2.6:
+minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
@@ -2642,6 +3105,11 @@ minimist@^1.2.0, minimist@^1.2.6:
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c"
integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==
+mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
+ integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
+
ml-array-mean@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/ml-array-mean/-/ml-array-mean-1.1.6.tgz#d951a700dc8e3a17b3e0a583c2c64abd0c619c56"
@@ -2707,6 +3175,11 @@ nanoid@^3.3.7:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
+napi-build-utils@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e"
+ integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==
+
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@@ -2740,6 +3213,13 @@ next@^15.2.2:
"@next/swc-win32-x64-msvc" "15.2.2"
sharp "^0.33.5"
+node-abi@^3.3.0:
+ version "3.74.0"
+ resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.74.0.tgz#5bfb4424264eaeb91432d2adb9da23c63a301ed0"
+ integrity sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==
+ dependencies:
+ semver "^7.3.5"
+
node-domexception@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
@@ -2853,7 +3333,7 @@ object.values@^1.1.6, object.values@^1.1.7:
define-properties "^1.2.1"
es-object-atoms "^1.0.0"
-once@^1.3.0:
+once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
@@ -3096,6 +3576,24 @@ postcss@^8, postcss@^8.4.23:
picocolors "^1.0.0"
source-map-js "^1.2.0"
+prebuild-install@^7.1.1:
+ version "7.1.3"
+ resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.3.tgz#d630abad2b147443f20a212917beae68b8092eec"
+ integrity sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==
+ dependencies:
+ detect-libc "^2.0.0"
+ expand-template "^2.0.3"
+ github-from-package "0.0.0"
+ minimist "^1.2.3"
+ mkdirp-classic "^0.5.3"
+ napi-build-utils "^2.0.0"
+ node-abi "^3.3.0"
+ pump "^3.0.0"
+ rc "^1.2.7"
+ simple-get "^4.0.0"
+ tar-fs "^2.0.0"
+ tunnel-agent "^0.6.0"
+
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@@ -3120,6 +3618,14 @@ proxy-from-env@^1.1.0:
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
+pump@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8"
+ integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==
+ dependencies:
+ end-of-stream "^1.1.0"
+ once "^1.3.1"
+
punycode@^2.1.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
@@ -3130,6 +3636,16 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+rc@^1.2.7:
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
+ integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
+ dependencies:
+ deep-extend "^0.6.0"
+ ini "~1.3.0"
+ minimist "^1.2.0"
+ strip-json-comments "~2.0.1"
+
react-dom@^18:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
@@ -3171,7 +3687,7 @@ read-cache@^1.0.0:
dependencies:
pify "^2.3.0"
-readable-stream@^3.4.0, readable-stream@^3.6.2:
+readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
@@ -3277,7 +3793,7 @@ safe-array-concat@^1.1.2:
has-symbols "^1.0.3"
isarray "^2.0.5"
-safe-buffer@~5.2.0:
+safe-buffer@^5.0.1, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@@ -3315,6 +3831,11 @@ semver@^6.3.1:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
+semver@^7.3.5, semver@^7.6.2, semver@^7.6.3:
+ version "7.7.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
+ integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
+
semver@^7.5.4:
version "7.6.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d"
@@ -3322,11 +3843,6 @@ semver@^7.5.4:
dependencies:
lru-cache "^6.0.0"
-semver@^7.6.3:
- version "7.7.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
- integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
-
set-function-length@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
@@ -3390,6 +3906,11 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+shell-quote@^1.8.1:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.2.tgz#d2d83e057959d53ec261311e9e9b8f51dcb2934a"
+ integrity sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==
+
side-channel@^1.0.4, side-channel@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
@@ -3405,6 +3926,20 @@ signal-exit@^4.0.1:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
+simple-concat@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
+ integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
+
+simple-get@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
+ integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==
+ dependencies:
+ decompress-response "^6.0.0"
+ once "^1.3.1"
+ simple-concat "^1.0.0"
+
simple-swizzle@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
@@ -3432,6 +3967,19 @@ source-map-js@^1.2.0:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
+source-map-support@^0.5.21:
+ version "0.5.21"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
+ integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
+source-map@^0.6.0:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
stack-trace@0.0.x:
version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
@@ -3553,6 +4101,11 @@ strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+strip-json-comments@~2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+ integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
+
styled-jsx@5.1.6:
version "5.1.6"
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.6.tgz#83b90c077e6c6a80f7f5e8781d0f311b2fe41499"
@@ -3630,6 +4183,27 @@ tapable@^2.2.0:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
+tar-fs@^2.0.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.2.tgz#425f154f3404cb16cb8ff6e671d45ab2ed9596c5"
+ integrity sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==
+ dependencies:
+ chownr "^1.1.1"
+ mkdirp-classic "^0.5.2"
+ pump "^3.0.0"
+ tar-stream "^2.1.4"
+
+tar-stream@^2.1.4:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
+ integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
+ dependencies:
+ bl "^4.0.3"
+ end-of-stream "^1.4.1"
+ fs-constants "^1.0.0"
+ inherits "^2.0.3"
+ readable-stream "^3.1.1"
+
text-hex@1.0.x:
version "1.0.0"
resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
@@ -3696,6 +4270,13 @@ tslib@^2.4.0, tslib@^2.8.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
+tunnel-agent@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+ integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
+ dependencies:
+ safe-buffer "^5.0.1"
+
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
@@ -3904,6 +4485,13 @@ which@^2.0.1:
dependencies:
isexe "^2.0.0"
+which@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/which/-/which-4.0.0.tgz#cd60b5e74503a3fbcfbf6cd6b4138a8bae644c1a"
+ integrity sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==
+ dependencies:
+ isexe "^3.1.1"
+
winston-transport@^4.9.0:
version "4.9.0"
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.9.0.tgz#3bba345de10297654ea6f33519424560003b3bf9"
From d1e93616659224ad94e14368583d43b6a2a37e89 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Wed, 19 Mar 2025 13:37:54 +0530
Subject: [PATCH 14/71] feat(routes): add discover route
---
ui/app/api/discover/route.ts | 61 ++++++++++++++++++++++++++++++++++++
ui/app/discover/page.tsx | 2 +-
2 files changed, 62 insertions(+), 1 deletion(-)
create mode 100644 ui/app/api/discover/route.ts
diff --git a/ui/app/api/discover/route.ts b/ui/app/api/discover/route.ts
new file mode 100644
index 0000000..0c95498
--- /dev/null
+++ b/ui/app/api/discover/route.ts
@@ -0,0 +1,61 @@
+import { searchSearxng } from '@/lib/searxng';
+
+const articleWebsites = [
+ 'yahoo.com',
+ 'www.exchangewire.com',
+ 'businessinsider.com',
+ /* 'wired.com',
+ 'mashable.com',
+ 'theverge.com',
+ 'gizmodo.com',
+ 'cnet.com',
+ 'venturebeat.com', */
+];
+
+const topics = ['AI', 'tech']; /* TODO: Add UI to customize this */
+
+export const GET = async (req: Request) => {
+ try {
+ const data = (
+ await Promise.all([
+ ...new Array(articleWebsites.length * topics.length)
+ .fill(0)
+ .map(async (_, i) => {
+ return (
+ await searchSearxng(
+ `site:${articleWebsites[i % articleWebsites.length]} ${
+ topics[i % topics.length]
+ }`,
+ {
+ engines: ['bing news'],
+ pageno: 1,
+ },
+ )
+ ).results;
+ }),
+ ])
+ )
+ .map((result) => result)
+ .flat()
+ .sort(() => Math.random() - 0.5);
+
+ return Response.json(
+ {
+ blogs: data,
+ },
+ {
+ status: 200,
+ },
+ );
+ } catch (err) {
+ console.error(`An error ocurred in discover route: ${err}`);
+ return Response.json(
+ {
+ message: 'An error has occurred',
+ },
+ {
+ status: 500,
+ },
+ );
+ }
+};
diff --git a/ui/app/discover/page.tsx b/ui/app/discover/page.tsx
index eb94040..eb7de7f 100644
--- a/ui/app/discover/page.tsx
+++ b/ui/app/discover/page.tsx
@@ -19,7 +19,7 @@ const Page = () => {
useEffect(() => {
const fetchData = async () => {
try {
- const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/discover`, {
+ const res = await fetch(`/api/discover`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
From 1130746f5de0b04f7fd03bf0340d24c3012ee863 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Wed, 19 Mar 2025 13:38:40 +0530
Subject: [PATCH 15/71] feat(app): add image & video search functionality
---
ui/app/api/images/route.ts | 83 ++++++++++++++++++++++++++
ui/app/api/videos/route.ts | 83 ++++++++++++++++++++++++++
ui/components/SearchImages.tsx | 41 +++++++------
ui/components/SearchVideos.tsx | 41 +++++++------
ui/lib/chains/imageSearchAgent.ts | 90 ++++++++++++++++++++++++++++
ui/lib/chains/videoSearchAgent.ts | 97 +++++++++++++++++++++++++++++++
6 files changed, 393 insertions(+), 42 deletions(-)
create mode 100644 ui/app/api/images/route.ts
create mode 100644 ui/app/api/videos/route.ts
create mode 100644 ui/lib/chains/imageSearchAgent.ts
create mode 100644 ui/lib/chains/videoSearchAgent.ts
diff --git a/ui/app/api/images/route.ts b/ui/app/api/images/route.ts
new file mode 100644
index 0000000..4114cbd
--- /dev/null
+++ b/ui/app/api/images/route.ts
@@ -0,0 +1,83 @@
+import handleImageSearch from '@/lib/chains/imageSearchAgent';
+import {
+ getCustomOpenaiApiKey,
+ getCustomOpenaiApiUrl,
+ getCustomOpenaiModelName,
+} from '@/lib/config';
+import { getAvailableChatModelProviders } from '@/lib/providers';
+import { BaseChatModel } from '@langchain/core/language_models/chat_models';
+import { AIMessage, HumanMessage } from '@langchain/core/messages';
+import { ChatOpenAI } from '@langchain/openai';
+
+interface ChatModel {
+ provider: string;
+ model: string;
+}
+
+interface ImageSearchBody {
+ query: string;
+ chatHistory: any[];
+ chatModel?: ChatModel;
+}
+
+export const POST = async (req: Request) => {
+ try {
+ const body: ImageSearchBody = await req.json();
+
+ const chatHistory = body.chatHistory
+ .map((msg: any) => {
+ if (msg.role === 'user') {
+ return new HumanMessage(msg.content);
+ } else if (msg.role === 'assistant') {
+ return new AIMessage(msg.content);
+ }
+ })
+ .filter((msg) => msg !== undefined);
+
+ const chatModelProviders = await getAvailableChatModelProviders();
+
+ const chatModelProvider =
+ chatModelProviders[
+ body.chatModel?.provider || Object.keys(chatModelProviders)[0]
+ ];
+ const chatModel =
+ chatModelProvider[
+ body.chatModel?.model || Object.keys(chatModelProvider)[0]
+ ];
+
+ let llm: BaseChatModel | undefined;
+
+ if (body.chatModel?.provider === 'custom_openai') {
+ llm = new ChatOpenAI({
+ openAIApiKey: getCustomOpenaiApiKey(),
+ modelName: getCustomOpenaiModelName(),
+ temperature: 0.7,
+ configuration: {
+ baseURL: getCustomOpenaiApiUrl(),
+ },
+ });
+ } else if (chatModelProvider && chatModel) {
+ llm = chatModel.model;
+ }
+
+ if (!llm) {
+ return Response.json({ error: 'Invalid chat model' }, { status: 400 });
+ }
+
+ const images = await handleImageSearch(
+ {
+ chat_history: chatHistory,
+ query: body.query,
+ },
+ llm,
+ );
+
+ return Response.json({ images }, { status: 200 });
+ } catch (err) {
+ console.error(`An error ocurred while searching images: ${err}`);
+ return Response.json(
+ { message: 'An error ocurred while searching images' },
+ { status: 500 },
+ );
+ }
+};
diff --git a/ui/app/api/videos/route.ts b/ui/app/api/videos/route.ts
new file mode 100644
index 0000000..9b4bf9f
--- /dev/null
+++ b/ui/app/api/videos/route.ts
@@ -0,0 +1,83 @@
+import handleVideoSearch from '@/lib/chains/videoSearchAgent';
+import {
+ getCustomOpenaiApiKey,
+ getCustomOpenaiApiUrl,
+ getCustomOpenaiModelName,
+} from '@/lib/config';
+import { getAvailableChatModelProviders } from '@/lib/providers';
+import { BaseChatModel } from '@langchain/core/language_models/chat_models';
+import { AIMessage, HumanMessage } from '@langchain/core/messages';
+import { ChatOpenAI } from '@langchain/openai';
+
+interface ChatModel {
+ provider: string;
+ model: string;
+}
+
+interface VideoSearchBody {
+ query: string;
+ chatHistory: any[];
+ chatModel?: ChatModel;
+}
+
+export const POST = async (req: Request) => {
+ try {
+ const body: VideoSearchBody = await req.json();
+
+ const chatHistory = body.chatHistory
+ .map((msg: any) => {
+ if (msg.role === 'user') {
+ return new HumanMessage(msg.content);
+ } else if (msg.role === 'assistant') {
+ return new AIMessage(msg.content);
+ }
+ })
+ .filter((msg) => msg !== undefined);
+
+ const chatModelProviders = await getAvailableChatModelProviders();
+
+ const chatModelProvider =
+ chatModelProviders[
+ body.chatModel?.provider || Object.keys(chatModelProviders)[0]
+ ];
+ const chatModel =
+ chatModelProvider[
+ body.chatModel?.model || Object.keys(chatModelProvider)[0]
+ ];
+
+ let llm: BaseChatModel | undefined;
+
+ if (body.chatModel?.provider === 'custom_openai') {
+ llm = new ChatOpenAI({
+ openAIApiKey: getCustomOpenaiApiKey(),
+ modelName: getCustomOpenaiModelName(),
+ temperature: 0.7,
+ configuration: {
+ baseURL: getCustomOpenaiApiUrl(),
+ },
+ });
+ } else if (chatModelProvider && chatModel) {
+ llm = chatModel.model;
+ }
+
+ if (!llm) {
+ return Response.json({ error: 'Invalid chat model' }, { status: 400 });
+ }
+
+ const videos = await handleVideoSearch(
+ {
+ chat_history: chatHistory,
+ query: body.query,
+ },
+ llm,
+ );
+
+ return Response.json({ videos }, { status: 200 });
+ } catch (err) {
+ console.error(`An error ocurred while searching videos: ${err}`);
+ return Response.json(
+ { message: 'An error ocurred while searching videos' },
+ { status: 500 },
+ );
+ }
+};
diff --git a/ui/components/SearchImages.tsx b/ui/components/SearchImages.tsx
index 383f780..08c16ee 100644
--- a/ui/components/SearchImages.tsx
+++ b/ui/components/SearchImages.tsx
@@ -14,9 +14,11 @@ type Image = {
const SearchImages = ({
query,
chatHistory,
+ messageId,
}: {
query: string;
chatHistory: Message[];
+ messageId: string;
}) => {
const [images, setImages] = useState(null);
const [loading, setLoading] = useState(false);
@@ -27,7 +29,7 @@ const SearchImages = ({
<>
{!loading && images === null && (
{
setLoading(true);
@@ -37,27 +39,24 @@ const SearchImages = ({
const customOpenAIBaseURL = localStorage.getItem('openAIBaseURL');
const customOpenAIKey = localStorage.getItem('openAIApiKey');
- const res = await fetch(
- `${process.env.NEXT_PUBLIC_API_URL}/images`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- query: query,
- chatHistory: chatHistory,
- chatModel: {
- provider: chatModelProvider,
- model: chatModel,
- ...(chatModelProvider === 'custom_openai' && {
- customOpenAIBaseURL: customOpenAIBaseURL,
- customOpenAIKey: customOpenAIKey,
- }),
- },
- }),
+ const res = await fetch(`/api/images`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ body: JSON.stringify({
+ query: query,
+ chatHistory: chatHistory,
+ chatModel: {
+ provider: chatModelProvider,
+ model: chatModel,
+ ...(chatModelProvider === 'custom_openai' && {
+ customOpenAIBaseURL: customOpenAIBaseURL,
+ customOpenAIKey: customOpenAIKey,
+ }),
+ },
+ }),
+ });
const data = await res.json();
diff --git a/ui/components/SearchVideos.tsx b/ui/components/SearchVideos.tsx
index c284dc2..a09a0d2 100644
--- a/ui/components/SearchVideos.tsx
+++ b/ui/components/SearchVideos.tsx
@@ -27,9 +27,11 @@ declare module 'yet-another-react-lightbox' {
const Searchvideos = ({
query,
chatHistory,
+ messageId,
}: {
query: string;
chatHistory: Message[];
+ messageId: string;
}) => {
const [videos, setVideos] = useState(null);
const [loading, setLoading] = useState(false);
@@ -42,7 +44,7 @@ const Searchvideos = ({
<>
{!loading && videos === null && (
{
setLoading(true);
@@ -52,27 +54,24 @@ const Searchvideos = ({
const customOpenAIBaseURL = localStorage.getItem('openAIBaseURL');
const customOpenAIKey = localStorage.getItem('openAIApiKey');
- const res = await fetch(
- `${process.env.NEXT_PUBLIC_API_URL}/videos`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- query: query,
- chatHistory: chatHistory,
- chatModel: {
- provider: chatModelProvider,
- model: chatModel,
- ...(chatModelProvider === 'custom_openai' && {
- customOpenAIBaseURL: customOpenAIBaseURL,
- customOpenAIKey: customOpenAIKey,
- }),
- },
- }),
+ const res = await fetch(`/api/videos`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ body: JSON.stringify({
+ query: query,
+ chatHistory: chatHistory,
+ chatModel: {
+ provider: chatModelProvider,
+ model: chatModel,
+ ...(chatModelProvider === 'custom_openai' && {
+ customOpenAIBaseURL: customOpenAIBaseURL,
+ customOpenAIKey: customOpenAIKey,
+ }),
+ },
+ }),
+ });
const data = await res.json();
diff --git a/ui/lib/chains/imageSearchAgent.ts b/ui/lib/chains/imageSearchAgent.ts
new file mode 100644
index 0000000..d194612
--- /dev/null
+++ b/ui/lib/chains/imageSearchAgent.ts
@@ -0,0 +1,90 @@
+import {
+ RunnableSequence,
+ RunnableMap,
+ RunnableLambda,
+} from '@langchain/core/runnables';
+import { PromptTemplate } from '@langchain/core/prompts';
+import formatChatHistoryAsString from '../utils/formatHistory';
+import { BaseMessage } from '@langchain/core/messages';
+import { StringOutputParser } from '@langchain/core/output_parsers';
+import { searchSearxng } from '../searxng';
+import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
+
+const imageSearchChainPrompt = `
+You will be given a conversation below and a follow up question. You need to rephrase the follow-up question so it is a standalone question that can be used by the LLM to search the web for images.
+You need to make sure the rephrased question agrees with the conversation and is relevant to the conversation.
+
+Example:
+1. Follow up question: What is a cat?
+Rephrased: A cat
+
+2. Follow up question: What is a car? How does it works?
+Rephrased: Car working
+
+3. Follow up question: How does an AC work?
+Rephrased: AC working
+
+Conversation:
+{chat_history}
+
+Follow up question: {query}
+Rephrased question:
+`;
+
+type ImageSearchChainInput = {
+ chat_history: BaseMessage[];
+ query: string;
+};
+
+interface ImageSearchResult {
+ img_src: string;
+ url: string;
+ title: string;
+}
+
+const strParser = new StringOutputParser();
+
+const createImageSearchChain = (llm: BaseChatModel) => {
+ return RunnableSequence.from([
+ RunnableMap.from({
+ chat_history: (input: ImageSearchChainInput) => {
+ return formatChatHistoryAsString(input.chat_history);
+ },
+ query: (input: ImageSearchChainInput) => {
+ return input.query;
+ },
+ }),
+ PromptTemplate.fromTemplate(imageSearchChainPrompt),
+ llm,
+ strParser,
+ RunnableLambda.from(async (input: string) => {
+ const res = await searchSearxng(input, {
+ engines: ['bing images', 'google images'],
+ });
+
+ const images: ImageSearchResult[] = [];
+
+ res.results.forEach((result) => {
+ if (result.img_src && result.url && result.title) {
+ images.push({
+ img_src: result.img_src,
+ url: result.url,
+ title: result.title,
+ });
+ }
+ });
+
+ return images.slice(0, 10);
+ }),
+ ]);
+};
+
+const handleImageSearch = (
+ input: ImageSearchChainInput,
+ llm: BaseChatModel,
+) => {
+ const imageSearchChain = createImageSearchChain(llm);
+ return imageSearchChain.invoke(input);
+};
+
+export default handleImageSearch;
diff --git a/ui/lib/chains/videoSearchAgent.ts b/ui/lib/chains/videoSearchAgent.ts
new file mode 100644
index 0000000..e1051f6
--- /dev/null
+++ b/ui/lib/chains/videoSearchAgent.ts
@@ -0,0 +1,97 @@
+import {
+ RunnableSequence,
+ RunnableMap,
+ RunnableLambda,
+} from '@langchain/core/runnables';
+import { PromptTemplate } from '@langchain/core/prompts';
+import formatChatHistoryAsString from '../utils/formatHistory';
+import { BaseMessage } from '@langchain/core/messages';
+import { StringOutputParser } from '@langchain/core/output_parsers';
+import { searchSearxng } from '../searxng';
+import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
+
+const VideoSearchChainPrompt = `
+ You will be given a conversation below and a follow up question. You need to rephrase the follow-up question so it is a standalone question that can be used by the LLM to search Youtube for videos.
+ You need to make sure the rephrased question agrees with the conversation and is relevant to the conversation.
+
+ Example:
+ 1. Follow up question: How does a car work?
+ Rephrased: How does a car work?
+
+ 2. Follow up question: What is the theory of relativity?
+ Rephrased: What is theory of relativity
+
+ 3. Follow up question: How does an AC work?
+ Rephrased: How does an AC work
+
+ Conversation:
+ {chat_history}
+
+ Follow up question: {query}
+ Rephrased question:
+ `;
+
+type VideoSearchChainInput = {
+ chat_history: BaseMessage[];
+ query: string;
+};
+
+interface VideoSearchResult {
+ img_src: string;
+ url: string;
+ title: string;
+ iframe_src: string;
+}
+
+const strParser = new StringOutputParser();
+
+const createVideoSearchChain = (llm: BaseChatModel) => {
+ return RunnableSequence.from([
+ RunnableMap.from({
+ chat_history: (input: VideoSearchChainInput) => {
+ return formatChatHistoryAsString(input.chat_history);
+ },
+ query: (input: VideoSearchChainInput) => {
+ return input.query;
+ },
+ }),
+ PromptTemplate.fromTemplate(VideoSearchChainPrompt),
+ llm,
+ strParser,
+ RunnableLambda.from(async (input: string) => {
+ const res = await searchSearxng(input, {
+ engines: ['youtube'],
+ });
+
+ const videos: VideoSearchResult[] = [];
+
+ res.results.forEach((result) => {
+ if (
+ result.thumbnail &&
+ result.url &&
+ result.title &&
+ result.iframe_src
+ ) {
+ videos.push({
+ img_src: result.thumbnail,
+ url: result.url,
+ title: result.title,
+ iframe_src: result.iframe_src,
+ });
+ }
+ });
+
+ return videos.slice(0, 10);
+ }),
+ ]);
+};
+
+const handleVideoSearch = (
+ input: VideoSearchChainInput,
+ llm: BaseChatModel,
+) => {
+ const VideoSearchChain = createVideoSearchChain(llm);
+ return VideoSearchChain.invoke(input);
+};
+
+export default handleVideoSearch;
From bab32e8d70013351ef76294e1fe3eddaf126f13d Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Wed, 19 Mar 2025 13:40:10 +0530
Subject: [PATCH 16/71] feat(app): add suggestions route
---
ui/app/api/suggestions/route.ts | 81 +++++++++++++++++++++++
ui/lib/chains/suggestionGeneratorAgent.ts | 55 +++++++++++++++
2 files changed, 136 insertions(+)
create mode 100644 ui/app/api/suggestions/route.ts
create mode 100644 ui/lib/chains/suggestionGeneratorAgent.ts
diff --git a/ui/app/api/suggestions/route.ts b/ui/app/api/suggestions/route.ts
new file mode 100644
index 0000000..f28092e
--- /dev/null
+++ b/ui/app/api/suggestions/route.ts
@@ -0,0 +1,81 @@
+import generateSuggestions from '@/lib/chains/suggestionGeneratorAgent';
+import {
+ getCustomOpenaiApiKey,
+ getCustomOpenaiApiUrl,
+ getCustomOpenaiModelName,
+} from '@/lib/config';
+import { getAvailableChatModelProviders } from '@/lib/providers';
+import { BaseChatModel } from '@langchain/core/language_models/chat_models';
+import { AIMessage, HumanMessage } from '@langchain/core/messages';
+import { ChatOpenAI } from '@langchain/openai';
+
+interface ChatModel {
+ provider: string;
+ model: string;
+}
+
+interface SuggestionsGenerationBody {
+ chatHistory: any[];
+ chatModel?: ChatModel;
+}
+
+export const POST = async (req: Request) => {
+ try {
+ const body: SuggestionsGenerationBody = await req.json();
+
+ const chatHistory = body.chatHistory
+ .map((msg: any) => {
+ if (msg.role === 'user') {
+ return new HumanMessage(msg.content);
+ } else if (msg.role === 'assistant') {
+ return new AIMessage(msg.content);
+ }
+ })
+ .filter((msg) => msg !== undefined);
+
+ const chatModelProviders = await getAvailableChatModelProviders();
+
+ const chatModelProvider =
+ chatModelProviders[
+ body.chatModel?.provider || Object.keys(chatModelProviders)[0]
+ ];
+ const chatModel =
+ chatModelProvider[
+ body.chatModel?.model || Object.keys(chatModelProvider)[0]
+ ];
+
+ let llm: BaseChatModel | undefined;
+
+ if (body.chatModel?.provider === 'custom_openai') {
+ llm = new ChatOpenAI({
+ openAIApiKey: getCustomOpenaiApiKey(),
+ modelName: getCustomOpenaiModelName(),
+ temperature: 0.7,
+ configuration: {
+ baseURL: getCustomOpenaiApiUrl(),
+ },
+ });
+ } else if (chatModelProvider && chatModel) {
+ llm = chatModel.model;
+ }
+
+ if (!llm) {
+ return Response.json({ error: 'Invalid chat model' }, { status: 400 });
+ }
+
+ const suggestions = await generateSuggestions(
+ {
+ chat_history: chatHistory,
+ },
+ llm,
+ );
+
+ return Response.json({ suggestions }, { status: 200 });
+ } catch (err) {
+ console.error(`An error ocurred while generating suggestions: ${err}`);
+ return Response.json(
+ { message: 'An error ocurred while generating suggestions' },
+ { status: 500 },
+ );
+ }
+};
diff --git a/ui/lib/chains/suggestionGeneratorAgent.ts b/ui/lib/chains/suggestionGeneratorAgent.ts
new file mode 100644
index 0000000..9129059
--- /dev/null
+++ b/ui/lib/chains/suggestionGeneratorAgent.ts
@@ -0,0 +1,55 @@
+import { RunnableSequence, RunnableMap } from '@langchain/core/runnables';
+import ListLineOutputParser from '../outputParsers/listLineOutputParser';
+import { PromptTemplate } from '@langchain/core/prompts';
+import formatChatHistoryAsString from '../utils/formatHistory';
+import { BaseMessage } from '@langchain/core/messages';
+import { BaseChatModel } from '@langchain/core/language_models/chat_models';
+import { ChatOpenAI } from '@langchain/openai';
+
+const suggestionGeneratorPrompt = `
+You are an AI suggestion generator for an AI powered search engine. You will be given a conversation below. You need to generate 4-5 suggestions based on the conversation. The suggestion should be relevant to the conversation that can be used by the user to ask the chat model for more information.
+You need to make sure the suggestions are relevant to the conversation and are helpful to the user. Keep a note that the user might use these suggestions to ask a chat model for more information.
+Make sure the suggestions are medium in length and are informative and relevant to the conversation.
+
+Provide these suggestions separated by newlines between the XML tags and . For example:
+
+
+Tell me more about SpaceX and their recent projects
+What is the latest news on SpaceX?
+Who is the CEO of SpaceX?
+
+
+Conversation:
+{chat_history}
+`;
+
+type SuggestionGeneratorInput = {
+ chat_history: BaseMessage[];
+};
+
+const outputParser = new ListLineOutputParser({
+ key: 'suggestions',
+});
+
+const createSuggestionGeneratorChain = (llm: BaseChatModel) => {
+ return RunnableSequence.from([
+ RunnableMap.from({
+ chat_history: (input: SuggestionGeneratorInput) =>
+ formatChatHistoryAsString(input.chat_history),
+ }),
+ PromptTemplate.fromTemplate(suggestionGeneratorPrompt),
+ llm,
+ outputParser,
+ ]);
+};
+
+const generateSuggestions = (
+ input: SuggestionGeneratorInput,
+ llm: BaseChatModel,
+) => {
+ (llm as unknown as ChatOpenAI).temperature = 0;
+ const suggestionGeneratorChain = createSuggestionGeneratorChain(llm);
+ return suggestionGeneratorChain.invoke(input);
+};
+
+export default generateSuggestions;
From c46fd7a9c8836356eb934d3be9b82ffdc0ca81d7 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Wed, 19 Mar 2025 13:40:35 +0530
Subject: [PATCH 17/71] feat(utils): add files utils, remove logger, fix API
url
---
ui/lib/actions.ts | 2 +-
ui/lib/config.ts | 1 -
ui/lib/utils/documents.ts | 1 -
ui/lib/utils/files.ts | 17 +++++++++++++++++
ui/lib/utils/logger.ts | 22 ----------------------
5 files changed, 18 insertions(+), 25 deletions(-)
create mode 100644 ui/lib/utils/files.ts
delete mode 100644 ui/lib/utils/logger.ts
diff --git a/ui/lib/actions.ts b/ui/lib/actions.ts
index a4409b0..0f4c0f0 100644
--- a/ui/lib/actions.ts
+++ b/ui/lib/actions.ts
@@ -7,7 +7,7 @@ export const getSuggestions = async (chatHisory: Message[]) => {
const customOpenAIKey = localStorage.getItem('openAIApiKey');
const customOpenAIBaseURL = localStorage.getItem('openAIBaseURL');
- const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/suggestions`, {
+ const res = await fetch(`/api/suggestions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
diff --git a/ui/lib/config.ts b/ui/lib/config.ts
index 0a314cf..489fec3 100644
--- a/ui/lib/config.ts
+++ b/ui/lib/config.ts
@@ -109,7 +109,6 @@ const mergeConfigs = (current: any, update: any): any => {
export const updateConfig = (config: RecursivePartial) => {
const currentConfig = loadConfig();
const mergedConfig = mergeConfigs(currentConfig, config);
- console.log(mergedConfig);
fs.writeFileSync(
path.join(path.join(process.cwd(), `${configFileName}`)),
toml.stringify(mergedConfig),
diff --git a/ui/lib/utils/documents.ts b/ui/lib/utils/documents.ts
index 900d6b0..ad64180 100644
--- a/ui/lib/utils/documents.ts
+++ b/ui/lib/utils/documents.ts
@@ -3,7 +3,6 @@ import { htmlToText } from 'html-to-text';
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
import { Document } from '@langchain/core/documents';
import pdfParse from 'pdf-parse';
-import logger from './logger';
export const getDocumentsFromLinks = async ({ links }: { links: string[] }) => {
const splitter = new RecursiveCharacterTextSplitter();
diff --git a/ui/lib/utils/files.ts b/ui/lib/utils/files.ts
new file mode 100644
index 0000000..e6e91df
--- /dev/null
+++ b/ui/lib/utils/files.ts
@@ -0,0 +1,17 @@
+import path from 'path';
+import fs from 'fs';
+
+export const getFileDetails = (fileId: string) => {
+ const fileLoc = path.join(
+ process.cwd(),
+ './uploads',
+ fileId + '-extracted.json',
+ );
+
+ const parsedFile = JSON.parse(fs.readFileSync(fileLoc, 'utf8'));
+
+ return {
+ name: parsedFile.title,
+ fileId: fileId,
+ };
+};
diff --git a/ui/lib/utils/logger.ts b/ui/lib/utils/logger.ts
deleted file mode 100644
index 1c81eb9..0000000
--- a/ui/lib/utils/logger.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import winston from 'winston';
-
-const logger = winston.createLogger({
- level: 'info',
- transports: [
- new winston.transports.Console({
- format: winston.format.combine(
- winston.format.colorize(),
- winston.format.simple(),
- ),
- }),
- new winston.transports.File({
- filename: 'app.log',
- format: winston.format.combine(
- winston.format.timestamp(),
- winston.format.json(),
- ),
- }),
- ],
-});
-
-export default logger;
From 3150c21f176ed0416fe7e795d72d2f6c3af04c96 Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Wed, 19 Mar 2025 13:41:01 +0530
Subject: [PATCH 18/71] feat(icons): fix type errors
---
ui/components/MessageInputActions/Focus.tsx | 16 ++--------------
ui/data/.gitignore | 2 ++
2 files changed, 4 insertions(+), 14 deletions(-)
create mode 100644 ui/data/.gitignore
diff --git a/ui/components/MessageInputActions/Focus.tsx b/ui/components/MessageInputActions/Focus.tsx
index 613078b..875dbf7 100644
--- a/ui/components/MessageInputActions/Focus.tsx
+++ b/ui/components/MessageInputActions/Focus.tsx
@@ -45,25 +45,13 @@ const focusModes = [
key: 'youtubeSearch',
title: 'Youtube',
description: 'Search and watch videos',
- icon: (
-
- ),
+ icon: ,
},
{
key: 'redditSearch',
title: 'Reddit',
description: 'Search for discussions and opinions',
- icon: (
-
- ),
+ icon: ,
},
];
diff --git a/ui/data/.gitignore b/ui/data/.gitignore
new file mode 100644
index 0000000..d6b7ef3
--- /dev/null
+++ b/ui/data/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
From c24edac16da9e8c720eb4cbc5f599e0b51b88ecc Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Wed, 19 Mar 2025 13:41:52 +0530
Subject: [PATCH 19/71] feat(app): add chat functionality
---
ui/app/api/chat/route.ts | 346 +++++++++++++++++++++++++++++++++++
ui/app/api/models/route.ts | 47 +++++
ui/components/ChatWindow.tsx | 320 ++++++++++++++------------------
ui/lib/providers/index.ts | 8 +-
4 files changed, 535 insertions(+), 186 deletions(-)
create mode 100644 ui/app/api/chat/route.ts
create mode 100644 ui/app/api/models/route.ts
diff --git a/ui/app/api/chat/route.ts b/ui/app/api/chat/route.ts
new file mode 100644
index 0000000..0b130de
--- /dev/null
+++ b/ui/app/api/chat/route.ts
@@ -0,0 +1,346 @@
+import prompts from '@/lib/prompts';
+import MetaSearchAgent from '@/lib/search/metaSearchAgent';
+import crypto from 'crypto';
+import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
+import { EventEmitter } from 'stream';
+import { chatModelProviders, embeddingModelProviders } from '@/lib/providers';
+import db from '@/lib/db';
+import { chats, messages as messagesSchema } from '@/lib/db/schema';
+import { and, eq, gt } from 'drizzle-orm';
+import { getFileDetails } from '@/lib/utils/files';
+
+export const runtime = 'nodejs';
+export const dynamic = 'force-dynamic';
+
+export const searchHandlers: Record = {
+ webSearch: new MetaSearchAgent({
+ activeEngines: [],
+ queryGeneratorPrompt: prompts.webSearchRetrieverPrompt,
+ responsePrompt: prompts.webSearchResponsePrompt,
+ rerank: true,
+ rerankThreshold: 0.3,
+ searchWeb: true,
+ summarizer: true,
+ }),
+ academicSearch: new MetaSearchAgent({
+ activeEngines: ['arxiv', 'google scholar', 'pubmed'],
+ queryGeneratorPrompt: prompts.academicSearchRetrieverPrompt,
+ responsePrompt: prompts.academicSearchResponsePrompt,
+ rerank: true,
+ rerankThreshold: 0,
+ searchWeb: true,
+ summarizer: false,
+ }),
+ writingAssistant: new MetaSearchAgent({
+ activeEngines: [],
+ queryGeneratorPrompt: '',
+ responsePrompt: prompts.writingAssistantPrompt,
+ rerank: true,
+ rerankThreshold: 0,
+ searchWeb: false,
+ summarizer: false,
+ }),
+ wolframAlphaSearch: new MetaSearchAgent({
+ activeEngines: ['wolframalpha'],
+ queryGeneratorPrompt: prompts.wolframAlphaSearchRetrieverPrompt,
+ responsePrompt: prompts.wolframAlphaSearchResponsePrompt,
+ rerank: false,
+ rerankThreshold: 0,
+ searchWeb: true,
+ summarizer: false,
+ }),
+ youtubeSearch: new MetaSearchAgent({
+ activeEngines: ['youtube'],
+ queryGeneratorPrompt: prompts.youtubeSearchRetrieverPrompt,
+ responsePrompt: prompts.youtubeSearchResponsePrompt,
+ rerank: true,
+ rerankThreshold: 0.3,
+ searchWeb: true,
+ summarizer: false,
+ }),
+ redditSearch: new MetaSearchAgent({
+ activeEngines: ['reddit'],
+ queryGeneratorPrompt: prompts.redditSearchRetrieverPrompt,
+ responsePrompt: prompts.redditSearchResponsePrompt,
+ rerank: true,
+ rerankThreshold: 0.3,
+ searchWeb: true,
+ summarizer: false,
+ }),
+};
+
+type Message = {
+ messageId: string;
+ chatId: string;
+ content: string;
+};
+
+type ChatModel = {
+ provider: string;
+ name: string;
+};
+
+type EmbeddingModel = {
+ provider: string;
+ name: string;
+};
+
+type Body = {
+ message: Message;
+ optimizationMode: 'speed' | 'balanced' | 'quality';
+ focusMode: string;
+ history: Array<[string, string]>;
+ files: Array;
+ chatModel: ChatModel;
+ embeddingModel: EmbeddingModel;
+};
+
+const handleEmitterEvents = async (
+ stream: EventEmitter,
+ writer: WritableStreamDefaultWriter,
+ encoder: TextEncoder,
+ aiMessageId: string,
+ chatId: string,
+) => {
+ let recievedMessage = '';
+ let sources: any[] = [];
+
+ stream.on('data', (data) => {
+ const parsedData = JSON.parse(data);
+ if (parsedData.type === 'response') {
+ writer.write(
+ encoder.encode(
+ JSON.stringify({
+ type: 'message',
+ data: parsedData.data,
+ messageId: aiMessageId,
+ }) + '\n',
+ ),
+ );
+
+ recievedMessage += parsedData.data;
+ } else if (parsedData.type === 'sources') {
+ writer.write(
+ encoder.encode(
+ JSON.stringify({
+ type: 'sources',
+ data: parsedData.data,
+ messageId: aiMessageId,
+ }) + '\n',
+ ),
+ );
+
+ sources = parsedData.data;
+ }
+ });
+ stream.on('end', () => {
+ writer.write(
+ encoder.encode(
+ JSON.stringify({
+ type: 'messageEnd',
+ messageId: aiMessageId,
+ }) + '\n',
+ ),
+ );
+ writer.close();
+
+ db.insert(messagesSchema)
+ .values({
+ content: recievedMessage,
+ chatId: chatId,
+ messageId: aiMessageId,
+ role: 'assistant',
+ metadata: JSON.stringify({
+ createdAt: new Date(),
+ ...(sources && sources.length > 0 && { sources }),
+ }),
+ })
+ .execute();
+ });
+ stream.on('error', (data) => {
+ const parsedData = JSON.parse(data);
+ writer.write(
+ encoder.encode(
+ JSON.stringify({
+ type: 'error',
+ data: parsedData.data,
+ }),
+ ),
+ );
+ writer.close();
+ });
+};
+
+const handleHistorySave = async (
+ message: Message,
+ humanMessageId: string,
+ focusMode: string,
+ files: string[],
+) => {
+ const chat = await db.query.chats.findFirst({
+ where: eq(chats.id, message.chatId),
+ });
+
+ if (!chat) {
+ await db
+ .insert(chats)
+ .values({
+ id: message.chatId,
+ title: message.content,
+ createdAt: new Date().toString(),
+ focusMode: focusMode,
+ files: files.map(getFileDetails),
+ })
+ .execute();
+ }
+
+ const messageExists = await db.query.messages.findFirst({
+ where: eq(messagesSchema.messageId, humanMessageId),
+ });
+
+ if (!messageExists) {
+ await db
+ .insert(messagesSchema)
+ .values({
+ content: message.content,
+ chatId: message.chatId,
+ messageId: humanMessageId,
+ role: 'user',
+ metadata: JSON.stringify({
+ createdAt: new Date(),
+ }),
+ })
+ .execute();
+ } else {
+ await db
+ .delete(messagesSchema)
+ .where(
+ and(
+ gt(messagesSchema.id, messageExists.id),
+ eq(messagesSchema.chatId, message.chatId),
+ ),
+ )
+ .execute();
+ }
+};
+
+export const POST = async (req: Request) => {
+ try {
+ const body = (await req.json()) as Body;
+ const { message, chatModel, embeddingModel } = body;
+
+ if (message.content === '') {
+ return Response.json(
+ {
+ message: 'Please provide a message to process',
+ },
+ { status: 400 },
+ );
+ }
+
+ const getProviderChatModels = chatModelProviders[chatModel.provider];
+
+ if (!getProviderChatModels) {
+ return Response.json(
+ {
+ message: 'Invalid chat model provider',
+ },
+ { status: 400 },
+ );
+ }
+
+ const chatModels = await getProviderChatModels();
+
+ const llm = chatModels[chatModel.name].model;
+
+ if (!llm) {
+ return Response.json(
+ {
+ message: 'Invalid chat model',
+ },
+ { status: 400 },
+ );
+ }
+
+ const getProviderEmbeddingModels =
+ embeddingModelProviders[embeddingModel.provider];
+
+ if (!getProviderEmbeddingModels) {
+ return Response.json(
+ {
+ message: 'Invalid embedding model provider',
+ },
+ { status: 400 },
+ );
+ }
+
+ const embeddingModels = await getProviderEmbeddingModels();
+ const embedding = embeddingModels[embeddingModel.name].model;
+
+ if (!embedding) {
+ return Response.json(
+ {
+ message: 'Invalid embedding model',
+ },
+ { status: 400 },
+ );
+ }
+
+ const humanMessageId =
+ message.messageId ?? crypto.randomBytes(7).toString('hex');
+ const aiMessageId = crypto.randomBytes(7).toString('hex');
+
+ const history: BaseMessage[] = body.history.map((msg) => {
+ if (msg[0] === 'human') {
+ return new HumanMessage({
+ content: msg[1],
+ });
+ } else {
+ return new AIMessage({
+ content: msg[1],
+ });
+ }
+ });
+
+ const handler = searchHandlers[body.focusMode];
+
+ if (!handler) {
+ return Response.json(
+ {
+ message: 'Invalid focus mode',
+ },
+ { status: 400 },
+ );
+ }
+
+ const stream = await handler.searchAndAnswer(
+ message.content,
+ history,
+ llm,
+ embedding,
+ body.optimizationMode,
+ body.files,
+ );
+
+ const responseStream = new TransformStream();
+ const writer = responseStream.writable.getWriter();
+ const encoder = new TextEncoder();
+
+ handleEmitterEvents(stream, writer, encoder, aiMessageId, message.chatId);
+ handleHistorySave(message, humanMessageId, body.focusMode, body.files);
+
+ return new Response(responseStream.readable, {
+ headers: {
+ 'Content-Type': 'text/event-stream',
+ Connection: 'keep-alive',
+ 'Cache-Control': 'no-cache, no-transform',
+ },
+ });
+ } catch (err) {
+ console.error('An error ocurred while processing chat request:', err);
+ return Response.json(
+ { message: 'An error ocurred while processing chat request' },
+ { status: 500 },
+ );
+ }
+};
diff --git a/ui/app/api/models/route.ts b/ui/app/api/models/route.ts
new file mode 100644
index 0000000..a5e5b43
--- /dev/null
+++ b/ui/app/api/models/route.ts
@@ -0,0 +1,47 @@
+import {
+ getAvailableChatModelProviders,
+ getAvailableEmbeddingModelProviders,
+} from '@/lib/providers';
+
+export const GET = async (req: Request) => {
+ try {
+ const [chatModelProviders, embeddingModelProviders] = await Promise.all([
+ getAvailableChatModelProviders(),
+ getAvailableEmbeddingModelProviders(),
+ ]);
+
+ Object.keys(chatModelProviders).forEach((provider) => {
+ Object.keys(chatModelProviders[provider]).forEach((model) => {
+ delete (chatModelProviders[provider][model] as { model?: unknown })
+ .model;
+ });
+ });
+
+ Object.keys(embeddingModelProviders).forEach((provider) => {
+ Object.keys(embeddingModelProviders[provider]).forEach((model) => {
+ delete (embeddingModelProviders[provider][model] as { model?: unknown })
+ .model;
+ });
+ });
+
+ return Response.json(
+ {
+ chatModelProviders,
+ embeddingModelProviders,
+ },
+ {
+ status: 200,
+ },
+ );
+ } catch (err) {
+ console.error('An error ocurred while fetching models', err);
+ return Response.json(
+ {
+ message: 'An error has occurred.',
+ },
+ {
+ status: 500,
+ },
+ );
+ }
+};
diff --git a/ui/components/ChatWindow.tsx b/ui/components/ChatWindow.tsx
index 1940f42..f642525 100644
--- a/ui/components/ChatWindow.tsx
+++ b/ui/components/ChatWindow.tsx
@@ -29,29 +29,24 @@ export interface File {
fileId: string;
}
-const useSocket = (
- url: string,
- setIsWSReady: (ready: boolean) => void,
- setError: (error: boolean) => void,
+interface ChatModelProvider {
+ name: string;
+ provider: string;
+}
+
+interface EmbeddingModelProvider {
+ name: string;
+ provider: string;
+}
+
+const checkConfig = async (
+ setChatModelProvider: (provider: ChatModelProvider) => void,
+ setEmbeddingModelProvider: (provider: EmbeddingModelProvider) => void,
+ setIsConfigReady: (ready: boolean) => void,
+ setHasError: (hasError: boolean) => void,
) => {
- const wsRef = useRef(null);
- const reconnectTimeoutRef = useRef();
- const retryCountRef = useRef(0);
- const isCleaningUpRef = useRef(false);
- const MAX_RETRIES = 3;
- const INITIAL_BACKOFF = 1000; // 1 second
- const isConnectionErrorRef = useRef(false);
-
- const getBackoffDelay = (retryCount: number) => {
- return Math.min(INITIAL_BACKOFF * Math.pow(2, retryCount), 10000); // Cap at 10 seconds
- };
-
useEffect(() => {
- const connectWs = async () => {
- if (wsRef.current?.readyState === WebSocket.OPEN) {
- wsRef.current.close();
- }
-
+ const checkConfig = async () => {
try {
let chatModel = localStorage.getItem('chatModel');
let chatModelProvider = localStorage.getItem('chatModelProvider');
@@ -71,14 +66,11 @@ const useSocket = (
localStorage.setItem('autoVideoSearch', 'false');
}
- const providers = await fetch(
- `${process.env.NEXT_PUBLIC_API_URL}/models`,
- {
- headers: {
- 'Content-Type': 'application/json',
- },
+ const providers = await fetch(`/api/models`, {
+ headers: {
+ 'Content-Type': 'application/json',
},
- ).then(async (res) => {
+ }).then(async (res) => {
if (!res.ok)
throw new Error(
`Failed to fetch models: ${res.status} ${res.statusText}`,
@@ -182,127 +174,30 @@ const useSocket = (
}
}
- const wsURL = new URL(url);
- const searchParams = new URLSearchParams({});
-
- searchParams.append('chatModel', chatModel!);
- searchParams.append('chatModelProvider', chatModelProvider);
-
- if (chatModelProvider === 'custom_openai') {
- searchParams.append(
- 'openAIApiKey',
- localStorage.getItem('openAIApiKey')!,
- );
- searchParams.append(
- 'openAIBaseURL',
- localStorage.getItem('openAIBaseURL')!,
- );
- }
-
- searchParams.append('embeddingModel', embeddingModel!);
- searchParams.append('embeddingModelProvider', embeddingModelProvider);
-
- wsURL.search = searchParams.toString();
-
- const ws = new WebSocket(wsURL.toString());
- wsRef.current = ws;
-
- const timeoutId = setTimeout(() => {
- if (ws.readyState !== 1) {
- toast.error(
- 'Failed to connect to the server. Please try again later.',
- );
- }
- }, 10000);
-
- ws.addEventListener('message', (e) => {
- const data = JSON.parse(e.data);
- if (data.type === 'signal' && data.data === 'open') {
- const interval = setInterval(() => {
- if (ws.readyState === 1) {
- setIsWSReady(true);
- setError(false);
- if (retryCountRef.current > 0) {
- toast.success('Connection restored.');
- }
- retryCountRef.current = 0;
- clearInterval(interval);
- }
- }, 5);
- clearTimeout(timeoutId);
- console.debug(new Date(), 'ws:connected');
- }
- if (data.type === 'error') {
- isConnectionErrorRef.current = true;
- setError(true);
- toast.error(data.data);
- }
+ setChatModelProvider({
+ name: chatModel!,
+ provider: chatModelProvider,
});
- ws.onerror = () => {
- clearTimeout(timeoutId);
- setIsWSReady(false);
- toast.error('WebSocket connection error.');
- };
+ setEmbeddingModelProvider({
+ name: embeddingModel!,
+ provider: embeddingModelProvider,
+ });
- ws.onclose = () => {
- clearTimeout(timeoutId);
- setIsWSReady(false);
- console.debug(new Date(), 'ws:disconnected');
- if (!isCleaningUpRef.current && !isConnectionErrorRef.current) {
- toast.error('Connection lost. Attempting to reconnect...');
- attemptReconnect();
- }
- };
- } catch (error) {
- console.debug(new Date(), 'ws:error', error);
- setIsWSReady(false);
- attemptReconnect();
- }
- };
-
- const attemptReconnect = () => {
- retryCountRef.current += 1;
-
- if (retryCountRef.current > MAX_RETRIES) {
- console.debug(new Date(), 'ws:max_retries');
- setError(true);
- toast.error(
- 'Unable to connect to server after multiple attempts. Please refresh the page to try again.',
+ setIsConfigReady(true);
+ } catch (err) {
+ console.error(
+ 'An error occurred while checking the configuration:',
+ err,
);
- return;
- }
-
- const backoffDelay = getBackoffDelay(retryCountRef.current);
- console.debug(
- new Date(),
- `ws:retry attempt=${retryCountRef.current}/${MAX_RETRIES} delay=${backoffDelay}ms`,
- );
-
- if (reconnectTimeoutRef.current) {
- clearTimeout(reconnectTimeoutRef.current);
- }
-
- reconnectTimeoutRef.current = setTimeout(() => {
- connectWs();
- }, backoffDelay);
- };
-
- connectWs();
-
- return () => {
- if (reconnectTimeoutRef.current) {
- clearTimeout(reconnectTimeoutRef.current);
- }
- if (wsRef.current?.readyState === WebSocket.OPEN) {
- wsRef.current.close();
- isCleaningUpRef.current = true;
- console.debug(new Date(), 'ws:cleanup');
+ setIsConfigReady(false);
+ setHasError(true);
}
};
- }, [url, setIsWSReady, setError]);
- return wsRef.current;
+ checkConfig();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
};
const loadMessages = async (
@@ -315,15 +210,12 @@ const loadMessages = async (
setFiles: (files: File[]) => void,
setFileIds: (fileIds: string[]) => void,
) => {
- const res = await fetch(
- `${process.env.NEXT_PUBLIC_API_URL}/chats/${chatId}`,
- {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const res = await fetch(`/api/chats/${chatId}`, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (res.status === 404) {
setNotFound(true);
@@ -373,13 +265,27 @@ const ChatWindow = ({ id }: { id?: string }) => {
const [chatId, setChatId] = useState(id);
const [newChatCreated, setNewChatCreated] = useState(false);
+ const [chatModelProvider, setChatModelProvider] = useState(
+ {
+ name: '',
+ provider: '',
+ },
+ );
+
+ const [embeddingModelProvider, setEmbeddingModelProvider] =
+ useState({
+ name: '',
+ provider: '',
+ });
+
+ const [isConfigReady, setIsConfigReady] = useState(false);
const [hasError, setHasError] = useState(false);
const [isReady, setIsReady] = useState(false);
- const [isWSReady, setIsWSReady] = useState(false);
- const ws = useSocket(
- process.env.NEXT_PUBLIC_WS_URL!,
- setIsWSReady,
+ checkConfig(
+ setChatModelProvider,
+ setEmbeddingModelProvider,
+ setIsConfigReady,
setHasError,
);
@@ -399,8 +305,6 @@ const ChatWindow = ({ id }: { id?: string }) => {
const [notFound, setNotFound] = useState(false);
- const [isSettingsOpen, setIsSettingsOpen] = useState(false);
-
useEffect(() => {
if (
chatId &&
@@ -426,16 +330,6 @@ const ChatWindow = ({ id }: { id?: string }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
- useEffect(() => {
- return () => {
- if (ws?.readyState === 1) {
- ws.close();
- console.debug(new Date(), 'ws:cleanup');
- }
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
const messagesRef = useRef([]);
useEffect(() => {
@@ -443,18 +337,18 @@ const ChatWindow = ({ id }: { id?: string }) => {
}, [messages]);
useEffect(() => {
- if (isMessagesLoaded && isWSReady) {
+ if (isMessagesLoaded && isConfigReady) {
setIsReady(true);
console.debug(new Date(), 'app:ready');
} else {
setIsReady(false);
}
- }, [isMessagesLoaded, isWSReady]);
+ }, [isMessagesLoaded, isConfigReady]);
const sendMessage = async (message: string, messageId?: string) => {
if (loading) return;
- if (!ws || ws.readyState !== WebSocket.OPEN) {
- toast.error('Cannot send message while disconnected');
+ if (!isConfigReady) {
+ toast.error('Cannot send message before the configuration is ready');
return;
}
@@ -467,18 +361,27 @@ const ChatWindow = ({ id }: { id?: string }) => {
messageId = messageId ?? crypto.randomBytes(7).toString('hex');
- ws.send(
+ console.log(
JSON.stringify({
- type: 'message',
+ content: message,
message: {
messageId: messageId,
chatId: chatId!,
content: message,
},
+ chatId: chatId!,
files: fileIds,
focusMode: focusMode,
optimizationMode: optimizationMode,
- history: [...chatHistory, ['human', message]],
+ history: chatHistory,
+ chatModel: {
+ name: chatModelProvider.name,
+ provider: chatModelProvider.provider,
+ },
+ embeddingModel: {
+ name: embeddingModelProvider.name,
+ provider: embeddingModelProvider.provider,
+ },
}),
);
@@ -493,9 +396,7 @@ const ChatWindow = ({ id }: { id?: string }) => {
},
]);
- const messageHandler = async (e: MessageEvent) => {
- const data = JSON.parse(e.data);
-
+ const messageHandler = async (data: any) => {
if (data.type === 'error') {
toast.error(data.data);
setLoading(false);
@@ -558,7 +459,6 @@ const ChatWindow = ({ id }: { id?: string }) => {
['assistant', recievedMessage],
]);
- ws?.removeEventListener('message', messageHandler);
setLoading(false);
const lastMsg = messagesRef.current[messagesRef.current.length - 1];
@@ -584,16 +484,72 @@ const ChatWindow = ({ id }: { id?: string }) => {
const autoVideoSearch = localStorage.getItem('autoVideoSearch');
if (autoImageSearch === 'true') {
- document.getElementById('search-images')?.click();
+ document
+ .getElementById(`search-images-${lastMsg.messageId}`)
+ ?.click();
}
if (autoVideoSearch === 'true') {
- document.getElementById('search-videos')?.click();
+ document
+ .getElementById(`search-videos-${lastMsg.messageId}`)
+ ?.click();
}
}
};
- ws?.addEventListener('message', messageHandler);
+ const res = await fetch('/api/chat', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ content: message,
+ message: {
+ messageId: messageId,
+ chatId: chatId!,
+ content: message,
+ },
+ chatId: chatId!,
+ files: fileIds,
+ focusMode: focusMode,
+ optimizationMode: optimizationMode,
+ history: chatHistory,
+ chatModel: {
+ name: chatModelProvider.name,
+ provider: chatModelProvider.provider,
+ },
+ embeddingModel: {
+ name: embeddingModelProvider.name,
+ provider: embeddingModelProvider.provider,
+ },
+ }),
+ });
+
+ if (!res.body) throw new Error('No response body');
+
+ const reader = res.body?.getReader();
+ const decoder = new TextDecoder('utf-8');
+
+ let partialChunk = '';
+
+ while (true) {
+ const { value, done } = await reader.read();
+ if (done) break;
+
+ partialChunk += decoder.decode(value, { stream: true });
+
+ try {
+ const messages = partialChunk.split('\n');
+ for (const msg of messages) {
+ if (!msg.trim()) continue;
+ const json = JSON.parse(msg);
+ messageHandler(json);
+ }
+ partialChunk = '';
+ } catch (error) {
+ console.warn('Incomplete JSON, waiting for next chunk...');
+ }
+ }
};
const rewrite = (messageId: string) => {
@@ -614,11 +570,11 @@ const ChatWindow = ({ id }: { id?: string }) => {
};
useEffect(() => {
- if (isReady && initialMessage && ws?.readyState === 1) {
+ if (isReady && initialMessage && isConfigReady) {
sendMessage(initialMessage);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [ws?.readyState, isReady, initialMessage, isWSReady]);
+ }, [isConfigReady, isReady, initialMessage]);
if (hasError) {
return (
diff --git a/ui/lib/providers/index.ts b/ui/lib/providers/index.ts
index caa8074..e45c09d 100644
--- a/ui/lib/providers/index.ts
+++ b/ui/lib/providers/index.ts
@@ -22,7 +22,7 @@ export interface EmbeddingModel {
model: Embeddings;
}
-const chatModelProviders: Record<
+export const chatModelProviders: Record<
string,
() => Promise>
> = {
@@ -30,16 +30,16 @@ const chatModelProviders: Record<
ollama: loadOllamaChatModels,
groq: loadGroqChatModels,
anthropic: loadAnthropicChatModels,
- gemini: loadGeminiChatModels
+ gemini: loadGeminiChatModels,
};
-const embeddingModelProviders: Record<
+export const embeddingModelProviders: Record<
string,
() => Promise>
> = {
openai: loadOpenAIEmbeddingModels,
ollama: loadOllamaEmbeddingModels,
- gemini: loadGeminiEmbeddingModels
+ gemini: loadGeminiEmbeddingModels,
};
export const getAvailableChatModelProviders = async () => {
From bab5dba6e1800d6f54aa660a75861479111fabbc Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Wed, 19 Mar 2025 13:42:15 +0530
Subject: [PATCH 20/71] feat(app): port history saving features
---
ui/app/api/chats/[id]/route.ts | 69 ++++++++++++++++++++++++++++++++++
ui/app/api/chats/route.ts | 15 ++++++++
ui/app/c/[chatId]/page.tsx | 6 ++-
ui/app/library/page.tsx | 2 +-
ui/components/DeleteChat.tsx | 13 +++----
5 files changed, 94 insertions(+), 11 deletions(-)
create mode 100644 ui/app/api/chats/[id]/route.ts
create mode 100644 ui/app/api/chats/route.ts
diff --git a/ui/app/api/chats/[id]/route.ts b/ui/app/api/chats/[id]/route.ts
new file mode 100644
index 0000000..6891454
--- /dev/null
+++ b/ui/app/api/chats/[id]/route.ts
@@ -0,0 +1,69 @@
+import db from '@/lib/db';
+import { chats, messages } from '@/lib/db/schema';
+import { eq } from 'drizzle-orm';
+
+export const GET = async (
+ req: Request,
+ { params }: { params: Promise<{ id: string }> },
+) => {
+ try {
+ const { id } = await params;
+
+ const chatExists = await db.query.chats.findFirst({
+ where: eq(chats.id, id),
+ });
+
+ if (!chatExists) {
+ return Response.json({ message: 'Chat not found' }, { status: 404 });
+ }
+
+ const chatMessages = await db.query.messages.findMany({
+ where: eq(messages.chatId, id),
+ });
+
+ return Response.json(
+ {
+ chat: chatExists,
+ messages: chatMessages,
+ },
+ { status: 200 },
+ );
+ } catch (err) {
+ console.error('Error in getting chat by id: ', err);
+ return Response.json(
+ { message: 'An error has occurred.' },
+ { status: 500 },
+ );
+ }
+};
+
+export const DELETE = async (
+ req: Request,
+ { params }: { params: Promise<{ id: string }> },
+) => {
+ try {
+ const { id } = await params;
+
+ const chatExists = await db.query.chats.findFirst({
+ where: eq(chats.id, id),
+ });
+
+ if (!chatExists) {
+ return Response.json({ message: 'Chat not found' }, { status: 404 });
+ }
+
+ await db.delete(chats).where(eq(chats.id, id)).execute();
+ await db.delete(messages).where(eq(messages.chatId, id)).execute();
+
+ return Response.json(
+ { message: 'Chat deleted successfully' },
+ { status: 200 },
+ );
+ } catch (err) {
+ console.error('Error in deleting chat by id: ', err);
+ return Response.json(
+ { message: 'An error has occurred.' },
+ { status: 500 },
+ );
+ }
+};
diff --git a/ui/app/api/chats/route.ts b/ui/app/api/chats/route.ts
new file mode 100644
index 0000000..986a192
--- /dev/null
+++ b/ui/app/api/chats/route.ts
@@ -0,0 +1,15 @@
+import db from '@/lib/db';
+
+export const GET = async (req: Request) => {
+ try {
+ let chats = await db.query.chats.findMany();
+ chats = chats.reverse();
+ return Response.json({ chats: chats }, { status: 200 });
+ } catch (err) {
+ console.error('Error in getting chats: ', err);
+ return Response.json(
+ { message: 'An error has occurred.' },
+ { status: 500 },
+ );
+ }
+};
diff --git a/ui/app/c/[chatId]/page.tsx b/ui/app/c/[chatId]/page.tsx
index dc3c92a..aac125a 100644
--- a/ui/app/c/[chatId]/page.tsx
+++ b/ui/app/c/[chatId]/page.tsx
@@ -1,7 +1,9 @@
import ChatWindow from '@/components/ChatWindow';
+import React from 'react';
-const Page = ({ params }: { params: { chatId: string } }) => {
- return ;
+const Page = ({ params }: { params: Promise<{ chatId: string }> }) => {
+ const { chatId } = React.use(params);
+ return ;
};
export default Page;
diff --git a/ui/app/library/page.tsx b/ui/app/library/page.tsx
index 379596c..9c40b2b 100644
--- a/ui/app/library/page.tsx
+++ b/ui/app/library/page.tsx
@@ -21,7 +21,7 @@ const Page = () => {
const fetchChats = async () => {
setLoading(true);
- const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/chats`, {
+ const res = await fetch(`/api/chats`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
diff --git a/ui/components/DeleteChat.tsx b/ui/components/DeleteChat.tsx
index 2857fc8..3acc9fc 100644
--- a/ui/components/DeleteChat.tsx
+++ b/ui/components/DeleteChat.tsx
@@ -29,15 +29,12 @@ const DeleteChat = ({
const handleDelete = async () => {
setLoading(true);
try {
- const res = await fetch(
- `${process.env.NEXT_PUBLIC_API_URL}/chats/${chatId}`,
- {
- method: 'DELETE',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const res = await fetch(`/api/chats/${chatId}`, {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (res.status != 200) {
throw new Error('Failed to delete chat');
From 649c68f2920f34c5cd461fc7ab221dcc59f5ed0f Mon Sep 17 00:00:00 2001
From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com>
Date: Wed, 19 Mar 2025 13:42:28 +0530
Subject: [PATCH 21/71] feat(ui): fix type errors
---
ui/components/MessageBox.tsx | 2 ++
ui/components/MessageSources.tsx | 6 +++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/ui/components/MessageBox.tsx b/ui/components/MessageBox.tsx
index 61f4f05..499c3d6 100644
--- a/ui/components/MessageBox.tsx
+++ b/ui/components/MessageBox.tsx
@@ -193,10 +193,12 @@ const MessageBox = ({
diff --git a/ui/components/MessageSources.tsx b/ui/components/MessageSources.tsx
index c7ee945..fb2b5bb 100644
--- a/ui/components/MessageSources.tsx
+++ b/ui/components/MessageSources.tsx
@@ -69,11 +69,15 @@ const MessageSources = ({ sources }: { sources: Document[] }) => {