@librechat/agents 2.4.30 → 2.4.311
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/common/enum.cjs +1 -0
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/main.cjs +2 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/tools/search/firecrawl.cjs +149 -0
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -0
- package/dist/cjs/tools/search/format.cjs +116 -0
- package/dist/cjs/tools/search/format.cjs.map +1 -0
- package/dist/cjs/tools/search/highlights.cjs +194 -0
- package/dist/cjs/tools/search/highlights.cjs.map +1 -0
- package/dist/cjs/tools/search/rerankers.cjs +187 -0
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -0
- package/dist/cjs/tools/search/search.cjs +410 -0
- package/dist/cjs/tools/search/search.cjs.map +1 -0
- package/dist/cjs/tools/search/tool.cjs +103 -0
- package/dist/cjs/tools/search/tool.cjs.map +1 -0
- package/dist/esm/common/enum.mjs +1 -0
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/main.mjs +1 -0
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/tools/search/firecrawl.mjs +145 -0
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -0
- package/dist/esm/tools/search/format.mjs +114 -0
- package/dist/esm/tools/search/format.mjs.map +1 -0
- package/dist/esm/tools/search/highlights.mjs +192 -0
- package/dist/esm/tools/search/highlights.mjs.map +1 -0
- package/dist/esm/tools/search/rerankers.mjs +181 -0
- package/dist/esm/tools/search/rerankers.mjs.map +1 -0
- package/dist/esm/tools/search/search.mjs +407 -0
- package/dist/esm/tools/search/search.mjs.map +1 -0
- package/dist/esm/tools/search/tool.mjs +101 -0
- package/dist/esm/tools/search/tool.mjs.map +1 -0
- package/dist/types/common/enum.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/scripts/search.d.ts +1 -0
- package/dist/types/tools/search/firecrawl.d.ts +117 -0
- package/dist/types/tools/search/format.d.ts +2 -0
- package/dist/types/tools/search/highlights.d.ts +13 -0
- package/dist/types/tools/search/index.d.ts +2 -0
- package/dist/types/tools/search/rerankers.d.ts +32 -0
- package/dist/types/tools/search/search.d.ts +9 -0
- package/dist/types/tools/search/tool.d.ts +12 -0
- package/dist/types/tools/search/types.d.ts +150 -0
- package/package.json +2 -1
- package/src/common/enum.ts +1 -0
- package/src/index.ts +1 -0
- package/src/scripts/search.ts +141 -0
- package/src/tools/search/firecrawl.ts +270 -0
- package/src/tools/search/format.ts +121 -0
- package/src/tools/search/highlights.ts +238 -0
- package/src/tools/search/index.ts +2 -0
- package/src/tools/search/rerankers.ts +248 -0
- package/src/tools/search/search.ts +567 -0
- package/src/tools/search/tool.ts +151 -0
- package/src/tools/search/types.ts +179 -0
package/dist/cjs/common/enum.cjs
CHANGED
|
@@ -144,6 +144,7 @@ exports.Constants = void 0;
|
|
|
144
144
|
(function (Constants) {
|
|
145
145
|
Constants["OFFICIAL_CODE_BASEURL"] = "https://api.librechat.ai/v1";
|
|
146
146
|
Constants["EXECUTE_CODE"] = "execute_code";
|
|
147
|
+
Constants["WEB_SEARCH"] = "web_search";
|
|
147
148
|
Constants["CONTENT_AND_ARTIFACT"] = "content_and_artifact";
|
|
148
149
|
})(exports.Constants || (exports.Constants = {}));
|
|
149
150
|
exports.EnvVar = void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enum.cjs","sources":["../../../src/common/enum.ts"],"sourcesContent":["/**\n * Enum representing the various event types emitted during the execution of runnables.\n * These events provide real-time information about the progress and state of different components.\n *\n * @enum {string}\n */\nexport enum GraphEvents {\n /* Custom Events */\n\n /** [Custom] Agent update event in multi-agent graph/workflow */\n ON_AGENT_UPDATE = 'on_agent_update',\n /** [Custom] Delta event for run steps (message creation and tool calls) */\n ON_RUN_STEP = 'on_run_step',\n /** [Custom] Delta event for run steps (tool calls) */\n ON_RUN_STEP_DELTA = 'on_run_step_delta',\n /** [Custom] Completed event for run steps (tool calls) */\n ON_RUN_STEP_COMPLETED = 'on_run_step_completed',\n /** [Custom] Delta events for messages */\n ON_MESSAGE_DELTA = 'on_message_delta',\n /** [Custom] Reasoning Delta events for messages */\n ON_REASONING_DELTA = 'on_reasoning_delta',\n\n /* Official Events */\n\n /** Custom event, emitted by system */\n ON_CUSTOM_EVENT = 'on_custom_event',\n /** Emitted when a chat model starts processing. */\n CHAT_MODEL_START = 'on_chat_model_start',\n\n /** Emitted when a chat model streams a chunk of its response. */\n CHAT_MODEL_STREAM = 'on_chat_model_stream',\n\n /** Emitted when a chat model completes its processing. */\n CHAT_MODEL_END = 'on_chat_model_end',\n\n /** Emitted when a language model starts processing. */\n LLM_START = 'on_llm_start',\n\n /** Emitted when a language model streams a chunk of its response. */\n LLM_STREAM = 'on_llm_stream',\n\n /** Emitted when a language model completes its processing. */\n LLM_END = 'on_llm_end',\n\n /** Emitted when a chain starts processing. */\n CHAIN_START = 'on_chain_start',\n\n /** Emitted when a chain streams a chunk of its output. */\n CHAIN_STREAM = 'on_chain_stream',\n\n /** Emitted when a chain completes its processing. */\n CHAIN_END = 'on_chain_end',\n\n /** Emitted when a tool starts its operation. */\n TOOL_START = 'on_tool_start',\n\n /** Emitted when a tool completes its operation. */\n TOOL_END = 'on_tool_end',\n\n /** Emitted when a retriever starts its operation. */\n RETRIEVER_START = 'on_retriever_start',\n\n /** Emitted when a retriever completes its operation. */\n RETRIEVER_END = 'on_retriever_end',\n\n /** Emitted when a prompt starts processing. */\n PROMPT_START = 'on_prompt_start',\n\n /** Emitted when a prompt completes its processing. */\n PROMPT_END = 'on_prompt_end',\n}\n\nexport enum Providers {\n OPENAI = 'openAI',\n BEDROCK_LEGACY = 'bedrock_legacy',\n VERTEXAI = 'vertexai',\n BEDROCK = 'bedrock',\n ANTHROPIC = 'anthropic',\n MISTRALAI = 'mistralai',\n MISTRAL = 'mistral',\n OLLAMA = 'ollama',\n GOOGLE = 'google',\n AZURE = 'azureOpenAI',\n DEEPSEEK = 'deepseek',\n OPENROUTER = 'openrouter',\n XAI = 'xai',\n}\n\nexport enum GraphNodeKeys {\n TOOLS = 'tools',\n AGENT = 'agent',\n PRE_TOOLS = 'pre_tools',\n POST_TOOLS = 'post_tools',\n}\n\nexport enum GraphNodeActions {\n TOOL_NODE = 'tool_node',\n CALL_MODEL = 'call_model',\n ROUTE_MESSAGE = 'route_message',\n}\n\nexport enum CommonEvents {\n LANGGRAPH = 'LangGraph',\n}\n\nexport enum StepTypes {\n TOOL_CALLS = 'tool_calls',\n MESSAGE_CREATION = 'message_creation',\n}\n\nexport enum ContentTypes {\n TEXT = 'text',\n ERROR = 'error',\n THINK = 'think',\n TOOL_CALL = 'tool_call',\n IMAGE_URL = 'image_url',\n IMAGE_FILE = 'image_file',\n /** Anthropic */\n THINKING = 'thinking',\n /** Bedrock */\n REASONING_CONTENT = 'reasoning_content',\n /** Multi-Agent Switch */\n AGENT_UPDATE = 'agent_update',\n}\n\nexport enum ToolCallTypes {\n FUNCTION = 'function',\n RETRIEVAL = 'retrieval',\n FILE_SEARCH = 'file_search',\n CODE_INTERPRETER = 'code_interpreter',\n /* Agents Tool Call */\n TOOL_CALL = 'tool_call',\n}\n\nexport enum Callback {\n TOOL_ERROR = 'handleToolError',\n TOOL_START = 'handleToolStart',\n TOOL_END = 'handleToolEnd',\n /*\n LLM_START = 'handleLLMStart',\n LLM_NEW_TOKEN = 'handleLLMNewToken',\n LLM_ERROR = 'handleLLMError',\n LLM_END = 'handleLLMEnd',\n CHAT_MODEL_START = 'handleChatModelStart',\n CHAIN_START = 'handleChainStart',\n CHAIN_ERROR = 'handleChainError',\n CHAIN_END = 'handleChainEnd',\n TEXT = 'handleText',\n AGENT_ACTION = 'handleAgentAction',\n AGENT_END = 'handleAgentEnd',\n RETRIEVER_START = 'handleRetrieverStart',\n RETRIEVER_END = 'handleRetrieverEnd',\n RETRIEVER_ERROR = 'handleRetrieverError',\n CUSTOM_EVENT = 'handleCustomEvent'\n */\n}\n\nexport enum Constants {\n OFFICIAL_CODE_BASEURL = 'https://api.librechat.ai/v1',\n EXECUTE_CODE = 'execute_code',\n CONTENT_AND_ARTIFACT = 'content_and_artifact',\n}\n\nexport enum EnvVar {\n CODE_API_KEY = 'LIBRECHAT_CODE_API_KEY',\n CODE_BASEURL = 'LIBRECHAT_CODE_BASEURL',\n}\n"],"names":["GraphEvents","Providers","GraphNodeKeys","GraphNodeActions","CommonEvents","StepTypes","ContentTypes","ToolCallTypes","Callback","Constants","EnvVar"],"mappings":";;AAAA;;;;;AAKG;AACSA;AAAZ,CAAA,UAAY,WAAW,EAAA;;;AAIrB,IAAA,WAAA,CAAA,iBAAA,CAAA,GAAA,iBAAmC;;AAEnC,IAAA,WAAA,CAAA,aAAA,CAAA,GAAA,aAA2B;;AAE3B,IAAA,WAAA,CAAA,mBAAA,CAAA,GAAA,mBAAuC;;AAEvC,IAAA,WAAA,CAAA,uBAAA,CAAA,GAAA,uBAA+C;;AAE/C,IAAA,WAAA,CAAA,kBAAA,CAAA,GAAA,kBAAqC;;AAErC,IAAA,WAAA,CAAA,oBAAA,CAAA,GAAA,oBAAyC;;;AAKzC,IAAA,WAAA,CAAA,iBAAA,CAAA,GAAA,iBAAmC;;AAEnC,IAAA,WAAA,CAAA,kBAAA,CAAA,GAAA,qBAAwC;;AAGxC,IAAA,WAAA,CAAA,mBAAA,CAAA,GAAA,sBAA0C;;AAG1C,IAAA,WAAA,CAAA,gBAAA,CAAA,GAAA,mBAAoC;;AAGpC,IAAA,WAAA,CAAA,WAAA,CAAA,GAAA,cAA0B;;AAG1B,IAAA,WAAA,CAAA,YAAA,CAAA,GAAA,eAA4B;;AAG5B,IAAA,WAAA,CAAA,SAAA,CAAA,GAAA,YAAsB;;AAGtB,IAAA,WAAA,CAAA,aAAA,CAAA,GAAA,gBAA8B;;AAG9B,IAAA,WAAA,CAAA,cAAA,CAAA,GAAA,iBAAgC;;AAGhC,IAAA,WAAA,CAAA,WAAA,CAAA,GAAA,cAA0B;;AAG1B,IAAA,WAAA,CAAA,YAAA,CAAA,GAAA,eAA4B;;AAG5B,IAAA,WAAA,CAAA,UAAA,CAAA,GAAA,aAAwB;;AAGxB,IAAA,WAAA,CAAA,iBAAA,CAAA,GAAA,oBAAsC;;AAGtC,IAAA,WAAA,CAAA,eAAA,CAAA,GAAA,kBAAkC;;AAGlC,IAAA,WAAA,CAAA,cAAA,CAAA,GAAA,iBAAgC;;AAGhC,IAAA,WAAA,CAAA,YAAA,CAAA,GAAA,eAA4B;AAC9B,CAAC,EAhEWA,mBAAW,KAAXA,mBAAW,GAgEtB,EAAA,CAAA,CAAA;AAEWC;AAAZ,CAAA,UAAY,SAAS,EAAA;AACnB,IAAA,SAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,SAAA,CAAA,gBAAA,CAAA,GAAA,gBAAiC;AACjC,IAAA,SAAA,CAAA,UAAA,CAAA,GAAA,UAAqB;AACrB,IAAA,SAAA,CAAA,SAAA,CAAA,GAAA,SAAmB;AACnB,IAAA,SAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,SAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,SAAA,CAAA,SAAA,CAAA,GAAA,SAAmB;AACnB,IAAA,SAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,SAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,SAAA,CAAA,OAAA,CAAA,GAAA,aAAqB;AACrB,IAAA,SAAA,CAAA,UAAA,CAAA,GAAA,UAAqB;AACrB,IAAA,SAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AACzB,IAAA,SAAA,CAAA,KAAA,CAAA,GAAA,KAAW;AACb,CAAC,EAdWA,iBAAS,KAATA,iBAAS,GAcpB,EAAA,CAAA,CAAA;AAEWC;AAAZ,CAAA,UAAY,aAAa,EAAA;AACvB,IAAA,aAAA,CAAA,OAAA,CAAA,GAAA,OAAe;AACf,IAAA,aAAA,CAAA,OAAA,CAAA,GAAA,OAAe;AACf,IAAA,aAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,aAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AAC3B,CAAC,EALWA,qBAAa,KAAbA,qBAAa,GAKxB,EAAA,CAAA,CAAA;AAEWC;AAAZ,CAAA,UAAY,gBAAgB,EAAA;AAC1B,IAAA,gBAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,gBAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AACzB,IAAA,gBAAA,CAAA,eAAA,CAAA,GAAA,eAA+B;AACjC,CAAC,EAJWA,wBAAgB,KAAhBA,wBAAgB,GAI3B,EAAA,CAAA,CAAA;AAEWC;AAAZ,CAAA,UAAY,YAAY,EAAA;AACtB,IAAA,YAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACzB,CAAC,EAFWA,oBAAY,KAAZA,oBAAY,GAEvB,EAAA,CAAA,CAAA;AAEWC;AAAZ,CAAA,UAAY,SAAS,EAAA;AACnB,IAAA,SAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AACzB,IAAA,SAAA,CAAA,kBAAA,CAAA,GAAA,kBAAqC;AACvC,CAAC,EAHWA,iBAAS,KAATA,iBAAS,GAGpB,EAAA,CAAA,CAAA;AAEWC;AAAZ,CAAA,UAAY,YAAY,EAAA;AACtB,IAAA,YAAA,CAAA,MAAA,CAAA,GAAA,MAAa;AACb,IAAA,YAAA,CAAA,OAAA,CAAA,GAAA,OAAe;AACf,IAAA,YAAA,CAAA,OAAA,CAAA,GAAA,OAAe;AACf,IAAA,YAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,YAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,YAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;;AAEzB,IAAA,YAAA,CAAA,UAAA,CAAA,GAAA,UAAqB;;AAErB,IAAA,YAAA,CAAA,mBAAA,CAAA,GAAA,mBAAuC;;AAEvC,IAAA,YAAA,CAAA,cAAA,CAAA,GAAA,cAA6B;AAC/B,CAAC,EAbWA,oBAAY,KAAZA,oBAAY,GAavB,EAAA,CAAA,CAAA;AAEWC;AAAZ,CAAA,UAAY,aAAa,EAAA;AACvB,IAAA,aAAA,CAAA,UAAA,CAAA,GAAA,UAAqB;AACrB,IAAA,aAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACvB,IAAA,aAAA,CAAA,aAAA,CAAA,GAAA,aAA2B;AAC3B,IAAA,aAAA,CAAA,kBAAA,CAAA,GAAA,kBAAqC;;AAErC,IAAA,aAAA,CAAA,WAAA,CAAA,GAAA,WAAuB;AACzB,CAAC,EAPWA,qBAAa,KAAbA,qBAAa,GAOxB,EAAA,CAAA,CAAA;AAEWC;AAAZ,CAAA,UAAY,QAAQ,EAAA;AAClB,IAAA,QAAA,CAAA,YAAA,CAAA,GAAA,iBAA8B;AAC9B,IAAA,QAAA,CAAA,YAAA,CAAA,GAAA,iBAA8B;AAC9B,IAAA,QAAA,CAAA,UAAA,CAAA,GAAA,eAA0B;AAC1B;;;;;;;;;;;;;;;;AAgBE;AACJ,CAAC,EArBWA,gBAAQ,KAARA,gBAAQ,GAqBnB,EAAA,CAAA,CAAA;AAEWC;AAAZ,CAAA,UAAY,SAAS,EAAA;AACnB,IAAA,SAAA,CAAA,uBAAA,CAAA,GAAA,6BAAqD;AACrD,IAAA,SAAA,CAAA,cAAA,CAAA,GAAA,cAA6B;AAC7B,IAAA,SAAA,CAAA,sBAAA,CAAA,GAAA,sBAA6C;AAC/C,CAAC,
|
|
1
|
+
{"version":3,"file":"enum.cjs","sources":["../../../src/common/enum.ts"],"sourcesContent":["/**\n * Enum representing the various event types emitted during the execution of runnables.\n * These events provide real-time information about the progress and state of different components.\n *\n * @enum {string}\n */\nexport enum GraphEvents {\n /* Custom Events */\n\n /** [Custom] Agent update event in multi-agent graph/workflow */\n ON_AGENT_UPDATE = 'on_agent_update',\n /** [Custom] Delta event for run steps (message creation and tool calls) */\n ON_RUN_STEP = 'on_run_step',\n /** [Custom] Delta event for run steps (tool calls) */\n ON_RUN_STEP_DELTA = 'on_run_step_delta',\n /** [Custom] Completed event for run steps (tool calls) */\n ON_RUN_STEP_COMPLETED = 'on_run_step_completed',\n /** [Custom] Delta events for messages */\n ON_MESSAGE_DELTA = 'on_message_delta',\n /** [Custom] Reasoning Delta events for messages */\n ON_REASONING_DELTA = 'on_reasoning_delta',\n\n /* Official Events */\n\n /** Custom event, emitted by system */\n ON_CUSTOM_EVENT = 'on_custom_event',\n /** Emitted when a chat model starts processing. */\n CHAT_MODEL_START = 'on_chat_model_start',\n\n /** Emitted when a chat model streams a chunk of its response. */\n CHAT_MODEL_STREAM = 'on_chat_model_stream',\n\n /** Emitted when a chat model completes its processing. */\n CHAT_MODEL_END = 'on_chat_model_end',\n\n /** Emitted when a language model starts processing. */\n LLM_START = 'on_llm_start',\n\n /** Emitted when a language model streams a chunk of its response. */\n LLM_STREAM = 'on_llm_stream',\n\n /** Emitted when a language model completes its processing. */\n LLM_END = 'on_llm_end',\n\n /** Emitted when a chain starts processing. */\n CHAIN_START = 'on_chain_start',\n\n /** Emitted when a chain streams a chunk of its output. */\n CHAIN_STREAM = 'on_chain_stream',\n\n /** Emitted when a chain completes its processing. */\n CHAIN_END = 'on_chain_end',\n\n /** Emitted when a tool starts its operation. */\n TOOL_START = 'on_tool_start',\n\n /** Emitted when a tool completes its operation. */\n TOOL_END = 'on_tool_end',\n\n /** Emitted when a retriever starts its operation. */\n RETRIEVER_START = 'on_retriever_start',\n\n /** Emitted when a retriever completes its operation. */\n RETRIEVER_END = 'on_retriever_end',\n\n /** Emitted when a prompt starts processing. */\n PROMPT_START = 'on_prompt_start',\n\n /** Emitted when a prompt completes its processing. */\n PROMPT_END = 'on_prompt_end',\n}\n\nexport enum Providers {\n OPENAI = 'openAI',\n BEDROCK_LEGACY = 'bedrock_legacy',\n VERTEXAI = 'vertexai',\n BEDROCK = 'bedrock',\n ANTHROPIC = 'anthropic',\n MISTRALAI = 'mistralai',\n MISTRAL = 'mistral',\n OLLAMA = 'ollama',\n GOOGLE = 'google',\n AZURE = 'azureOpenAI',\n DEEPSEEK = 'deepseek',\n OPENROUTER = 'openrouter',\n XAI = 'xai',\n}\n\nexport enum GraphNodeKeys {\n TOOLS = 'tools',\n AGENT = 'agent',\n PRE_TOOLS = 'pre_tools',\n POST_TOOLS = 'post_tools',\n}\n\nexport enum GraphNodeActions {\n TOOL_NODE = 'tool_node',\n CALL_MODEL = 'call_model',\n ROUTE_MESSAGE = 'route_message',\n}\n\nexport enum CommonEvents {\n LANGGRAPH = 'LangGraph',\n}\n\nexport enum StepTypes {\n TOOL_CALLS = 'tool_calls',\n MESSAGE_CREATION = 'message_creation',\n}\n\nexport enum ContentTypes {\n TEXT = 'text',\n ERROR = 'error',\n THINK = 'think',\n TOOL_CALL = 'tool_call',\n IMAGE_URL = 'image_url',\n IMAGE_FILE = 'image_file',\n /** Anthropic */\n THINKING = 'thinking',\n /** Bedrock */\n REASONING_CONTENT = 'reasoning_content',\n /** Multi-Agent Switch */\n AGENT_UPDATE = 'agent_update',\n}\n\nexport enum ToolCallTypes {\n FUNCTION = 'function',\n RETRIEVAL = 'retrieval',\n FILE_SEARCH = 'file_search',\n CODE_INTERPRETER = 'code_interpreter',\n /* Agents Tool Call */\n TOOL_CALL = 'tool_call',\n}\n\nexport enum Callback {\n TOOL_ERROR = 'handleToolError',\n TOOL_START = 'handleToolStart',\n TOOL_END = 'handleToolEnd',\n /*\n LLM_START = 'handleLLMStart',\n LLM_NEW_TOKEN = 'handleLLMNewToken',\n LLM_ERROR = 'handleLLMError',\n LLM_END = 'handleLLMEnd',\n CHAT_MODEL_START = 'handleChatModelStart',\n CHAIN_START = 'handleChainStart',\n CHAIN_ERROR = 'handleChainError',\n CHAIN_END = 'handleChainEnd',\n TEXT = 'handleText',\n AGENT_ACTION = 'handleAgentAction',\n AGENT_END = 'handleAgentEnd',\n RETRIEVER_START = 'handleRetrieverStart',\n RETRIEVER_END = 'handleRetrieverEnd',\n RETRIEVER_ERROR = 'handleRetrieverError',\n CUSTOM_EVENT = 'handleCustomEvent'\n */\n}\n\nexport enum Constants {\n OFFICIAL_CODE_BASEURL = 'https://api.librechat.ai/v1',\n EXECUTE_CODE = 'execute_code',\n WEB_SEARCH = 'web_search',\n CONTENT_AND_ARTIFACT = 'content_and_artifact',\n}\n\nexport enum EnvVar {\n CODE_API_KEY = 'LIBRECHAT_CODE_API_KEY',\n CODE_BASEURL = 'LIBRECHAT_CODE_BASEURL',\n}\n"],"names":["GraphEvents","Providers","GraphNodeKeys","GraphNodeActions","CommonEvents","StepTypes","ContentTypes","ToolCallTypes","Callback","Constants","EnvVar"],"mappings":"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"}
|
package/dist/cjs/main.cjs
CHANGED
|
@@ -9,6 +9,7 @@ var prune = require('./messages/prune.cjs');
|
|
|
9
9
|
var format = require('./messages/format.cjs');
|
|
10
10
|
var Graph = require('./graphs/Graph.cjs');
|
|
11
11
|
var CodeExecutor = require('./tools/CodeExecutor.cjs');
|
|
12
|
+
var tool = require('./tools/search/tool.cjs');
|
|
12
13
|
var _enum = require('./common/enum.cjs');
|
|
13
14
|
var graph = require('./utils/graph.cjs');
|
|
14
15
|
var llm = require('./utils/llm.cjs');
|
|
@@ -56,6 +57,7 @@ exports.StandardGraph = Graph.StandardGraph;
|
|
|
56
57
|
exports.createCodeExecutionTool = CodeExecutor.createCodeExecutionTool;
|
|
57
58
|
exports.getCodeBaseURL = CodeExecutor.getCodeBaseURL;
|
|
58
59
|
exports.imageExtRegex = CodeExecutor.imageExtRegex;
|
|
60
|
+
exports.createSearchTool = tool.createSearchTool;
|
|
59
61
|
Object.defineProperty(exports, "Callback", {
|
|
60
62
|
enumerable: true,
|
|
61
63
|
get: function () { return _enum.Callback; }
|
package/dist/cjs/main.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var axios = require('axios');
|
|
4
|
+
|
|
5
|
+
/* eslint-disable no-console */
|
|
6
|
+
const getDomainName = (link, metadata) => {
|
|
7
|
+
try {
|
|
8
|
+
const url = metadata?.sourceURL ?? metadata?.url ?? (link || '');
|
|
9
|
+
const domain = new URL(url).hostname.replace(/^www\./, '');
|
|
10
|
+
if (domain) {
|
|
11
|
+
return domain;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
// URL parsing failed
|
|
16
|
+
console.error('Error parsing URL:', e);
|
|
17
|
+
}
|
|
18
|
+
return;
|
|
19
|
+
};
|
|
20
|
+
function getAttribution(link, metadata) {
|
|
21
|
+
if (!metadata)
|
|
22
|
+
return getDomainName(link, metadata);
|
|
23
|
+
const possibleAttributions = [
|
|
24
|
+
metadata.ogSiteName,
|
|
25
|
+
metadata['og:site_name'],
|
|
26
|
+
metadata.title?.split('|').pop()?.trim(),
|
|
27
|
+
metadata['twitter:site']?.replace(/^@/, ''),
|
|
28
|
+
];
|
|
29
|
+
const attribution = possibleAttributions.find((attr) => attr != null && typeof attr === 'string' && attr.trim() !== '');
|
|
30
|
+
if (attribution != null) {
|
|
31
|
+
return attribution;
|
|
32
|
+
}
|
|
33
|
+
return getDomainName(link, metadata);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Firecrawl scraper implementation
|
|
37
|
+
* Uses the Firecrawl API to scrape web pages
|
|
38
|
+
*/
|
|
39
|
+
class FirecrawlScraper {
|
|
40
|
+
apiKey;
|
|
41
|
+
apiUrl;
|
|
42
|
+
defaultFormats;
|
|
43
|
+
timeout;
|
|
44
|
+
constructor(config = {}) {
|
|
45
|
+
this.apiKey = config.apiKey ?? process.env.FIRECRAWL_API_KEY ?? '';
|
|
46
|
+
const baseUrl = config.apiUrl ??
|
|
47
|
+
process.env.FIRECRAWL_BASE_URL ??
|
|
48
|
+
'https://api.firecrawl.dev';
|
|
49
|
+
this.apiUrl = `${baseUrl.replace(/\/+$/, '')}/v1/scrape`;
|
|
50
|
+
this.defaultFormats = config.formats ?? ['markdown', 'html'];
|
|
51
|
+
this.timeout = config.timeout ?? 15000;
|
|
52
|
+
if (!this.apiKey) {
|
|
53
|
+
console.warn('FIRECRAWL_API_KEY is not set. Scraping will not work.');
|
|
54
|
+
}
|
|
55
|
+
console.log(`Firecrawl scraper initialized with API URL: ${this.apiUrl}`);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Scrape a single URL
|
|
59
|
+
* @param url URL to scrape
|
|
60
|
+
* @param options Scrape options
|
|
61
|
+
* @returns Scrape response
|
|
62
|
+
*/
|
|
63
|
+
async scrapeUrl(url, options = {}) {
|
|
64
|
+
if (!this.apiKey) {
|
|
65
|
+
return [
|
|
66
|
+
url,
|
|
67
|
+
{
|
|
68
|
+
success: false,
|
|
69
|
+
error: 'FIRECRAWL_API_KEY is not set',
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const response = await axios.post(this.apiUrl, {
|
|
75
|
+
url,
|
|
76
|
+
formats: options.formats || this.defaultFormats,
|
|
77
|
+
includeTags: options.includeTags,
|
|
78
|
+
excludeTags: options.excludeTags,
|
|
79
|
+
headers: options.headers,
|
|
80
|
+
waitFor: options.waitFor,
|
|
81
|
+
timeout: options.timeout ?? this.timeout,
|
|
82
|
+
}, {
|
|
83
|
+
headers: {
|
|
84
|
+
'Content-Type': 'application/json',
|
|
85
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
86
|
+
},
|
|
87
|
+
timeout: this.timeout,
|
|
88
|
+
});
|
|
89
|
+
return [url, response.data];
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
93
|
+
return [
|
|
94
|
+
url,
|
|
95
|
+
{
|
|
96
|
+
success: false,
|
|
97
|
+
error: `Firecrawl API request failed: ${errorMessage}`,
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Extract content from scrape response
|
|
104
|
+
* @param response Scrape response
|
|
105
|
+
* @returns Extracted content or empty string if not available
|
|
106
|
+
*/
|
|
107
|
+
extractContent(response) {
|
|
108
|
+
if (!response.success || !response.data) {
|
|
109
|
+
return '';
|
|
110
|
+
}
|
|
111
|
+
// Prefer markdown content if available
|
|
112
|
+
if (response.data.markdown != null) {
|
|
113
|
+
return response.data.markdown;
|
|
114
|
+
}
|
|
115
|
+
// Fall back to HTML content
|
|
116
|
+
if (response.data.html != null) {
|
|
117
|
+
return response.data.html;
|
|
118
|
+
}
|
|
119
|
+
// Fall back to raw HTML content
|
|
120
|
+
if (response.data.rawHtml != null) {
|
|
121
|
+
return response.data.rawHtml;
|
|
122
|
+
}
|
|
123
|
+
return '';
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Extract metadata from scrape response
|
|
127
|
+
* @param response Scrape response
|
|
128
|
+
* @returns Metadata object
|
|
129
|
+
*/
|
|
130
|
+
extractMetadata(response) {
|
|
131
|
+
if (!response.success || !response.data || !response.data.metadata) {
|
|
132
|
+
return {};
|
|
133
|
+
}
|
|
134
|
+
return response.data.metadata;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Create a Firecrawl scraper instance
|
|
139
|
+
* @param config Scraper configuration
|
|
140
|
+
* @returns Firecrawl scraper instance
|
|
141
|
+
*/
|
|
142
|
+
const createFirecrawlScraper = (config = {}) => {
|
|
143
|
+
return new FirecrawlScraper(config);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
exports.FirecrawlScraper = FirecrawlScraper;
|
|
147
|
+
exports.createFirecrawlScraper = createFirecrawlScraper;
|
|
148
|
+
exports.getAttribution = getAttribution;
|
|
149
|
+
//# sourceMappingURL=firecrawl.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firecrawl.cjs","sources":["../../../../src/tools/search/firecrawl.ts"],"sourcesContent":["/* eslint-disable no-console */\nimport axios from 'axios';\n\nexport interface FirecrawlScrapeOptions {\n formats?: string[];\n includeTags?: string[];\n excludeTags?: string[];\n headers?: Record<string, string>;\n waitFor?: number;\n timeout?: number;\n}\n\ninterface ScrapeMetadata {\n // Core source information\n sourceURL?: string;\n url?: string;\n scrapeId?: string;\n statusCode?: number;\n // Basic metadata\n title?: string;\n description?: string;\n language?: string;\n favicon?: string;\n viewport?: string;\n robots?: string;\n 'theme-color'?: string;\n // Open Graph metadata\n 'og:url'?: string;\n 'og:title'?: string;\n 'og:description'?: string;\n 'og:type'?: string;\n 'og:image'?: string;\n 'og:image:width'?: string;\n 'og:image:height'?: string;\n 'og:site_name'?: string;\n ogUrl?: string;\n ogTitle?: string;\n ogDescription?: string;\n ogImage?: string;\n ogSiteName?: string;\n // Article metadata\n 'article:author'?: string;\n 'article:published_time'?: string;\n 'article:modified_time'?: string;\n 'article:section'?: string;\n 'article:tag'?: string;\n 'article:publisher'?: string;\n publishedTime?: string;\n modifiedTime?: string;\n // Twitter metadata\n 'twitter:site'?: string;\n 'twitter:creator'?: string;\n 'twitter:card'?: string;\n 'twitter:image'?: string;\n 'twitter:dnt'?: string;\n 'twitter:app:name:iphone'?: string;\n 'twitter:app:id:iphone'?: string;\n 'twitter:app:url:iphone'?: string;\n 'twitter:app:name:ipad'?: string;\n 'twitter:app:id:ipad'?: string;\n 'twitter:app:url:ipad'?: string;\n 'twitter:app:name:googleplay'?: string;\n 'twitter:app:id:googleplay'?: string;\n 'twitter:app:url:googleplay'?: string;\n // Facebook metadata\n 'fb:app_id'?: string;\n // App links\n 'al:ios:url'?: string;\n 'al:ios:app_name'?: string;\n 'al:ios:app_store_id'?: string;\n // Allow for additional properties that might be present\n [key: string]: string | number | boolean | null | undefined;\n}\n\nexport interface FirecrawlScrapeResponse {\n success: boolean;\n data?: {\n markdown?: string;\n html?: string;\n rawHtml?: string;\n screenshot?: string;\n links?: string[];\n metadata?: ScrapeMetadata;\n };\n error?: string;\n}\n\nexport interface FirecrawlScraperConfig {\n apiKey?: string;\n apiUrl?: string;\n formats?: string[];\n timeout?: number;\n}\nconst getDomainName = (\n link: string,\n metadata?: ScrapeMetadata\n): string | undefined => {\n try {\n const url = metadata?.sourceURL ?? metadata?.url ?? (link || '');\n const domain = new URL(url).hostname.replace(/^www\\./, '');\n if (domain) {\n return domain;\n }\n } catch (e) {\n // URL parsing failed\n console.error('Error parsing URL:', e);\n }\n\n return;\n};\n\nexport function getAttribution(\n link: string,\n metadata?: ScrapeMetadata\n): string | undefined {\n if (!metadata) return getDomainName(link, metadata);\n\n const possibleAttributions = [\n metadata.ogSiteName,\n metadata['og:site_name'],\n metadata.title?.split('|').pop()?.trim(),\n metadata['twitter:site']?.replace(/^@/, ''),\n ];\n\n const attribution = possibleAttributions.find(\n (attr) => attr != null && typeof attr === 'string' && attr.trim() !== ''\n );\n if (attribution != null) {\n return attribution;\n }\n\n return getDomainName(link, metadata);\n}\n\n/**\n * Firecrawl scraper implementation\n * Uses the Firecrawl API to scrape web pages\n */\nexport class FirecrawlScraper {\n private apiKey: string;\n private apiUrl: string;\n private defaultFormats: string[];\n private timeout: number;\n\n constructor(config: FirecrawlScraperConfig = {}) {\n this.apiKey = config.apiKey ?? process.env.FIRECRAWL_API_KEY ?? '';\n\n const baseUrl =\n config.apiUrl ??\n process.env.FIRECRAWL_BASE_URL ??\n 'https://api.firecrawl.dev';\n this.apiUrl = `${baseUrl.replace(/\\/+$/, '')}/v1/scrape`;\n\n this.defaultFormats = config.formats ?? ['markdown', 'html'];\n this.timeout = config.timeout ?? 15000;\n\n if (!this.apiKey) {\n console.warn('FIRECRAWL_API_KEY is not set. Scraping will not work.');\n }\n\n console.log(`Firecrawl scraper initialized with API URL: ${this.apiUrl}`);\n }\n\n /**\n * Scrape a single URL\n * @param url URL to scrape\n * @param options Scrape options\n * @returns Scrape response\n */\n async scrapeUrl(\n url: string,\n options: FirecrawlScrapeOptions = {}\n ): Promise<[string, FirecrawlScrapeResponse]> {\n if (!this.apiKey) {\n return [\n url,\n {\n success: false,\n error: 'FIRECRAWL_API_KEY is not set',\n },\n ];\n }\n\n try {\n const response = await axios.post(\n this.apiUrl,\n {\n url,\n formats: options.formats || this.defaultFormats,\n includeTags: options.includeTags,\n excludeTags: options.excludeTags,\n headers: options.headers,\n waitFor: options.waitFor,\n timeout: options.timeout ?? this.timeout,\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n timeout: this.timeout,\n }\n );\n\n return [url, response.data];\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n return [\n url,\n {\n success: false,\n error: `Firecrawl API request failed: ${errorMessage}`,\n },\n ];\n }\n }\n\n /**\n * Extract content from scrape response\n * @param response Scrape response\n * @returns Extracted content or empty string if not available\n */\n extractContent(response: FirecrawlScrapeResponse): string {\n if (!response.success || !response.data) {\n return '';\n }\n\n // Prefer markdown content if available\n if (response.data.markdown != null) {\n return response.data.markdown;\n }\n\n // Fall back to HTML content\n if (response.data.html != null) {\n return response.data.html;\n }\n\n // Fall back to raw HTML content\n if (response.data.rawHtml != null) {\n return response.data.rawHtml;\n }\n\n return '';\n }\n\n /**\n * Extract metadata from scrape response\n * @param response Scrape response\n * @returns Metadata object\n */\n extractMetadata(response: FirecrawlScrapeResponse): ScrapeMetadata {\n if (!response.success || !response.data || !response.data.metadata) {\n return {};\n }\n\n return response.data.metadata;\n }\n}\n\n/**\n * Create a Firecrawl scraper instance\n * @param config Scraper configuration\n * @returns Firecrawl scraper instance\n */\nexport const createFirecrawlScraper = (\n config: FirecrawlScraperConfig = {}\n): FirecrawlScraper => {\n return new FirecrawlScraper(config);\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function formatResultsForLLM(results) {
|
|
4
|
+
let output = '';
|
|
5
|
+
const addSection = (title) => {
|
|
6
|
+
output += `\n=== ${title} ===\n`;
|
|
7
|
+
};
|
|
8
|
+
// Organic (web) results
|
|
9
|
+
const organic = results.organic ?? [];
|
|
10
|
+
if (organic.length) {
|
|
11
|
+
addSection('Web Results');
|
|
12
|
+
organic.forEach((r, i) => {
|
|
13
|
+
output += [
|
|
14
|
+
`Source ${i}: ${r.title ?? '(no title)'}`,
|
|
15
|
+
`Citation Anchor: \\ue202turn0search${i}`,
|
|
16
|
+
`URL: ${r.link}`,
|
|
17
|
+
r.snippet != null ? `Summary: ${r.snippet}` : '',
|
|
18
|
+
r.date != null ? `Date: ${r.date}` : '',
|
|
19
|
+
r.attribution != null ? `Source: ${r.attribution}` : '',
|
|
20
|
+
'',
|
|
21
|
+
'--- Content Highlights ---',
|
|
22
|
+
...(r.highlights ?? [])
|
|
23
|
+
.filter((h) => h.text.trim().length > 0)
|
|
24
|
+
.map((h) => `[Relevance: ${h.score.toFixed(2)}]\n${h.text.trim()}`),
|
|
25
|
+
'',
|
|
26
|
+
]
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.join('\n');
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// Ignoring these sections for now
|
|
32
|
+
// // Top stories (news)
|
|
33
|
+
// const topStores = results.topStories ?? [];
|
|
34
|
+
// if (topStores.length) {
|
|
35
|
+
// addSection('News Results');
|
|
36
|
+
// topStores.forEach((r, i) => {
|
|
37
|
+
// output += [
|
|
38
|
+
// `Anchor: \ue202turn0news${i}`,
|
|
39
|
+
// `Title: ${r.title ?? '(no title)'}`,
|
|
40
|
+
// `URL: ${r.link}`,
|
|
41
|
+
// r.snippet != null ? `Snippet: ${r.snippet}` : '',
|
|
42
|
+
// r.date != null ? `Date: ${r.date}` : '',
|
|
43
|
+
// r.attribution != null ? `Source: ${r.attribution}` : '',
|
|
44
|
+
// ''
|
|
45
|
+
// ].filter(Boolean).join('\n');
|
|
46
|
+
// });
|
|
47
|
+
// }
|
|
48
|
+
// // Images
|
|
49
|
+
// const images = results.images ?? [];
|
|
50
|
+
// if (images.length) {
|
|
51
|
+
// addSection('Image Results');
|
|
52
|
+
// images.forEach((img, i) => {
|
|
53
|
+
// output += [
|
|
54
|
+
// `Anchor: \ue202turn0image${i}`,
|
|
55
|
+
// `Title: ${img.title ?? '(no title)'}`,
|
|
56
|
+
// `Image URL: ${img.imageUrl}`,
|
|
57
|
+
// ''
|
|
58
|
+
// ].join('\n');
|
|
59
|
+
// });
|
|
60
|
+
// }
|
|
61
|
+
// Knowledge Graph
|
|
62
|
+
if (results.knowledgeGraph != null) {
|
|
63
|
+
addSection('Knowledge Graph');
|
|
64
|
+
output += [
|
|
65
|
+
`Title: ${results.knowledgeGraph.title ?? '(no title)'}`,
|
|
66
|
+
results.knowledgeGraph.description != null
|
|
67
|
+
? `Description: ${results.knowledgeGraph.description}`
|
|
68
|
+
: '',
|
|
69
|
+
results.knowledgeGraph.type != null
|
|
70
|
+
? `Type: ${results.knowledgeGraph.type}`
|
|
71
|
+
: '',
|
|
72
|
+
results.knowledgeGraph.imageUrl != null
|
|
73
|
+
? `Image URL: ${results.knowledgeGraph.imageUrl}`
|
|
74
|
+
: '',
|
|
75
|
+
results.knowledgeGraph.attributes != null
|
|
76
|
+
? `Attributes: ${JSON.stringify(results.knowledgeGraph.attributes, null, 2)}`
|
|
77
|
+
: '',
|
|
78
|
+
'',
|
|
79
|
+
]
|
|
80
|
+
.filter(Boolean)
|
|
81
|
+
.join('\n');
|
|
82
|
+
}
|
|
83
|
+
// Answer Box
|
|
84
|
+
if (results.answerBox != null) {
|
|
85
|
+
addSection('Answer Box');
|
|
86
|
+
output += [
|
|
87
|
+
results.answerBox.title != null
|
|
88
|
+
? `Title: ${results.answerBox.title}`
|
|
89
|
+
: '',
|
|
90
|
+
results.answerBox.answer != null
|
|
91
|
+
? `Answer: ${results.answerBox.answer}`
|
|
92
|
+
: '',
|
|
93
|
+
results.answerBox.snippet != null
|
|
94
|
+
? `Snippet: ${results.answerBox.snippet}`
|
|
95
|
+
: '',
|
|
96
|
+
results.answerBox.date != null ? `Date: ${results.answerBox.date}` : '',
|
|
97
|
+
'',
|
|
98
|
+
]
|
|
99
|
+
.filter(Boolean)
|
|
100
|
+
.join('\n');
|
|
101
|
+
}
|
|
102
|
+
// People also ask
|
|
103
|
+
const peopleAlsoAsk = results.peopleAlsoAsk ?? [];
|
|
104
|
+
if (peopleAlsoAsk.length) {
|
|
105
|
+
addSection('People Also Ask');
|
|
106
|
+
peopleAlsoAsk.forEach((p, _i) => {
|
|
107
|
+
output += [`Q: ${p.question}`, `A: ${p.answer}`, '']
|
|
108
|
+
.filter(Boolean)
|
|
109
|
+
.join('\n');
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return output.trim();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
exports.formatResultsForLLM = formatResultsForLLM;
|
|
116
|
+
//# sourceMappingURL=format.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.cjs","sources":["../../../../src/tools/search/format.ts"],"sourcesContent":["import type * as t from './types';\n\nexport function formatResultsForLLM(results: t.SearchResultData): string {\n let output = '';\n\n const addSection = (title: string): void => {\n output += `\\n=== ${title} ===\\n`;\n };\n\n // Organic (web) results\n const organic = results.organic ?? [];\n if (organic.length) {\n addSection('Web Results');\n organic.forEach((r, i) => {\n output += [\n `Source ${i}: ${r.title ?? '(no title)'}`,\n `Citation Anchor: \\\\ue202turn0search${i}`,\n `URL: ${r.link}`,\n r.snippet != null ? `Summary: ${r.snippet}` : '',\n r.date != null ? `Date: ${r.date}` : '',\n r.attribution != null ? `Source: ${r.attribution}` : '',\n '',\n '--- Content Highlights ---',\n ...(r.highlights ?? [])\n .filter((h) => h.text.trim().length > 0)\n .map((h) => `[Relevance: ${h.score.toFixed(2)}]\\n${h.text.trim()}`),\n '',\n ]\n .filter(Boolean)\n .join('\\n');\n });\n }\n\n // Ignoring these sections for now\n // // Top stories (news)\n // const topStores = results.topStories ?? [];\n // if (topStores.length) {\n // addSection('News Results');\n // topStores.forEach((r, i) => {\n // output += [\n // `Anchor: \\ue202turn0news${i}`,\n // `Title: ${r.title ?? '(no title)'}`,\n // `URL: ${r.link}`,\n // r.snippet != null ? `Snippet: ${r.snippet}` : '',\n // r.date != null ? `Date: ${r.date}` : '',\n // r.attribution != null ? `Source: ${r.attribution}` : '',\n // ''\n // ].filter(Boolean).join('\\n');\n // });\n // }\n\n // // Images\n // const images = results.images ?? [];\n // if (images.length) {\n // addSection('Image Results');\n // images.forEach((img, i) => {\n // output += [\n // `Anchor: \\ue202turn0image${i}`,\n // `Title: ${img.title ?? '(no title)'}`,\n // `Image URL: ${img.imageUrl}`,\n // ''\n // ].join('\\n');\n // });\n // }\n\n // Knowledge Graph\n if (results.knowledgeGraph != null) {\n addSection('Knowledge Graph');\n output += [\n `Title: ${results.knowledgeGraph.title ?? '(no title)'}`,\n results.knowledgeGraph.description != null\n ? `Description: ${results.knowledgeGraph.description}`\n : '',\n results.knowledgeGraph.type != null\n ? `Type: ${results.knowledgeGraph.type}`\n : '',\n results.knowledgeGraph.imageUrl != null\n ? `Image URL: ${results.knowledgeGraph.imageUrl}`\n : '',\n results.knowledgeGraph.attributes != null\n ? `Attributes: ${JSON.stringify(results.knowledgeGraph.attributes, null, 2)}`\n : '',\n '',\n ]\n .filter(Boolean)\n .join('\\n');\n }\n\n // Answer Box\n if (results.answerBox != null) {\n addSection('Answer Box');\n output += [\n results.answerBox.title != null\n ? `Title: ${results.answerBox.title}`\n : '',\n results.answerBox.answer != null\n ? `Answer: ${results.answerBox.answer}`\n : '',\n results.answerBox.snippet != null\n ? `Snippet: ${results.answerBox.snippet}`\n : '',\n results.answerBox.date != null ? `Date: ${results.answerBox.date}` : '',\n '',\n ]\n .filter(Boolean)\n .join('\\n');\n }\n\n // People also ask\n const peopleAlsoAsk = results.peopleAlsoAsk ?? [];\n if (peopleAlsoAsk.length) {\n addSection('People Also Ask');\n peopleAlsoAsk.forEach((p, _i) => {\n output += [`Q: ${p.question}`, `A: ${p.answer}`, '']\n .filter(Boolean)\n .join('\\n');\n });\n }\n\n return output.trim();\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// 2. Pre-compile all regular expressions (only do this once)
|
|
4
|
+
// Group patterns by priority for early returns
|
|
5
|
+
const priorityPatterns = [
|
|
6
|
+
// High priority patterns (structural)
|
|
7
|
+
[
|
|
8
|
+
{ regex: /\n\n/g }, // Double newline (paragraph break)
|
|
9
|
+
{ regex: /\n/g }, // Single newline
|
|
10
|
+
{ regex: /={3,}\s*\n|-{3,}\s*\n/g }, // Section separators
|
|
11
|
+
],
|
|
12
|
+
// Medium priority (semantic)
|
|
13
|
+
[
|
|
14
|
+
{ regex: /[.!?][")\]]?\s/g }, // End of sentence
|
|
15
|
+
{ regex: /;\s/g }, // Semicolon
|
|
16
|
+
{ regex: /:\s/g }, // Colon
|
|
17
|
+
],
|
|
18
|
+
// Low priority (any breaks)
|
|
19
|
+
[
|
|
20
|
+
{ regex: /,\s/g }, // Comma
|
|
21
|
+
{ regex: /\s-\s/g }, // Dash surrounded by spaces
|
|
22
|
+
{ regex: /\s/g }, // Any space
|
|
23
|
+
],
|
|
24
|
+
];
|
|
25
|
+
function findFirstMatch(text, regex) {
|
|
26
|
+
// Reset regex
|
|
27
|
+
regex.lastIndex = 0;
|
|
28
|
+
// For very long texts, try chunking
|
|
29
|
+
if (text.length > 10000) {
|
|
30
|
+
const chunkSize = 2000;
|
|
31
|
+
let position = 0;
|
|
32
|
+
while (position < text.length) {
|
|
33
|
+
const chunk = text.substring(position, position + chunkSize);
|
|
34
|
+
regex.lastIndex = 0;
|
|
35
|
+
const match = regex.exec(chunk);
|
|
36
|
+
if (match) {
|
|
37
|
+
return position + match.index;
|
|
38
|
+
}
|
|
39
|
+
// Move to next chunk with some overlap
|
|
40
|
+
position += chunkSize - 100;
|
|
41
|
+
if (position >= text.length)
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
return -1;
|
|
45
|
+
}
|
|
46
|
+
// For shorter texts, normal regex search
|
|
47
|
+
const match = regex.exec(text);
|
|
48
|
+
return match ? match.index : -1;
|
|
49
|
+
}
|
|
50
|
+
// 3. Optimized boundary finding functions
|
|
51
|
+
function findLastMatch(text, regex) {
|
|
52
|
+
// Reset regex state
|
|
53
|
+
regex.lastIndex = 0;
|
|
54
|
+
let lastIndex = -1;
|
|
55
|
+
let lastLength = 0;
|
|
56
|
+
let match;
|
|
57
|
+
// For very long texts, use a different approach to avoid regex engine slowdowns
|
|
58
|
+
if (text.length > 10000) {
|
|
59
|
+
// Try dividing the text into chunks for faster processing
|
|
60
|
+
const chunkSize = 2000;
|
|
61
|
+
let startPosition = Math.max(0, text.length - chunkSize);
|
|
62
|
+
while (startPosition >= 0) {
|
|
63
|
+
const chunk = text.substring(startPosition, startPosition + chunkSize);
|
|
64
|
+
regex.lastIndex = 0;
|
|
65
|
+
let chunkLastIndex = -1;
|
|
66
|
+
let chunkLastLength = 0;
|
|
67
|
+
while ((match = regex.exec(chunk)) !== null) {
|
|
68
|
+
chunkLastIndex = match.index;
|
|
69
|
+
chunkLastLength = match[0].length;
|
|
70
|
+
}
|
|
71
|
+
if (chunkLastIndex !== -1) {
|
|
72
|
+
return startPosition + chunkLastIndex + chunkLastLength;
|
|
73
|
+
}
|
|
74
|
+
// Move to previous chunk with some overlap
|
|
75
|
+
startPosition = Math.max(0, startPosition - chunkSize + 100) - 1;
|
|
76
|
+
if (startPosition <= 0)
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
return -1;
|
|
80
|
+
}
|
|
81
|
+
// For shorter texts, normal regex search
|
|
82
|
+
while ((match = regex.exec(text)) !== null) {
|
|
83
|
+
lastIndex = match.index;
|
|
84
|
+
lastLength = match[0].length;
|
|
85
|
+
}
|
|
86
|
+
return lastIndex === -1 ? -1 : lastIndex + lastLength;
|
|
87
|
+
}
|
|
88
|
+
// 4. Find the best boundary with priority groups
|
|
89
|
+
function findBestBoundary(text, direction = 'backward') {
|
|
90
|
+
if (!text || text.length === 0)
|
|
91
|
+
return 0;
|
|
92
|
+
// Try each priority group
|
|
93
|
+
for (const patternGroup of priorityPatterns) {
|
|
94
|
+
for (const pattern of patternGroup) {
|
|
95
|
+
const position = direction === 'backward'
|
|
96
|
+
? findLastMatch(text, pattern.regex)
|
|
97
|
+
: findFirstMatch(text, pattern.regex);
|
|
98
|
+
if (position !== -1) {
|
|
99
|
+
return position;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// No match found, use character boundary
|
|
104
|
+
return direction === 'backward' ? text.length : 0;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Expand highlights in search results using smart boundary detection.
|
|
108
|
+
*
|
|
109
|
+
* This implementation finds natural text boundaries like paragraphs, sentences,
|
|
110
|
+
* and phrases to provide context while maintaining readability.
|
|
111
|
+
*
|
|
112
|
+
* @param searchResults - Search results object
|
|
113
|
+
* @param mainExpandBy - Primary expansion size on each side (default: 300)
|
|
114
|
+
* @param separatorExpandBy - Additional range to look for separators (default: 150)
|
|
115
|
+
* @returns Copy of search results with expanded highlights
|
|
116
|
+
*/
|
|
117
|
+
function expandHighlights(searchResults, mainExpandBy = 300, separatorExpandBy = 150) {
|
|
118
|
+
// 1. Avoid full deep copy - only copy what we modify
|
|
119
|
+
const resultCopy = { ...searchResults };
|
|
120
|
+
// Only deep copy the relevant arrays
|
|
121
|
+
if (resultCopy.organic) {
|
|
122
|
+
resultCopy.organic = [...resultCopy.organic];
|
|
123
|
+
}
|
|
124
|
+
if (resultCopy.topStories) {
|
|
125
|
+
resultCopy.topStories = [...resultCopy.topStories];
|
|
126
|
+
}
|
|
127
|
+
// 5. Process the results efficiently
|
|
128
|
+
const processResultTypes = ['organic', 'topStories'];
|
|
129
|
+
for (const resultType of processResultTypes) {
|
|
130
|
+
if (!resultCopy[resultType])
|
|
131
|
+
continue;
|
|
132
|
+
// Map results to new array with modified highlights
|
|
133
|
+
resultCopy[resultType] = resultCopy[resultType]?.map((result) => {
|
|
134
|
+
if (result.content == null ||
|
|
135
|
+
result.content === '' ||
|
|
136
|
+
!result.highlights ||
|
|
137
|
+
result.highlights.length === 0) {
|
|
138
|
+
return result; // No modification needed
|
|
139
|
+
}
|
|
140
|
+
// Create a shallow copy with expanded highlights
|
|
141
|
+
const resultCopy = { ...result };
|
|
142
|
+
const content = result.content;
|
|
143
|
+
const highlights = [];
|
|
144
|
+
// Process each highlight
|
|
145
|
+
for (const highlight of result.highlights) {
|
|
146
|
+
const highlightText = highlight.text;
|
|
147
|
+
let startPos = content.indexOf(highlightText);
|
|
148
|
+
let highlightLen = highlightText.length;
|
|
149
|
+
if (startPos === -1) {
|
|
150
|
+
// Try with stripped whitespace
|
|
151
|
+
const strippedHighlight = highlightText.trim();
|
|
152
|
+
startPos = content.indexOf(strippedHighlight);
|
|
153
|
+
if (startPos === -1) {
|
|
154
|
+
highlights.push({
|
|
155
|
+
text: highlight.text,
|
|
156
|
+
score: highlight.score,
|
|
157
|
+
});
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
highlightLen = strippedHighlight.length;
|
|
161
|
+
}
|
|
162
|
+
// Calculate boundaries
|
|
163
|
+
const mainStart = Math.max(0, startPos - mainExpandBy);
|
|
164
|
+
const mainEnd = Math.min(content.length, startPos + highlightLen + mainExpandBy);
|
|
165
|
+
const separatorStart = Math.max(0, mainStart - separatorExpandBy);
|
|
166
|
+
const separatorEnd = Math.min(content.length, mainEnd + separatorExpandBy);
|
|
167
|
+
// Extract text segments
|
|
168
|
+
const headText = content.substring(separatorStart, mainStart);
|
|
169
|
+
const tailText = content.substring(mainEnd, separatorEnd);
|
|
170
|
+
// Find natural boundaries
|
|
171
|
+
const bestHeadBoundary = findBestBoundary(headText, 'backward');
|
|
172
|
+
const bestTailBoundary = findBestBoundary(tailText, 'forward');
|
|
173
|
+
// Calculate final positions
|
|
174
|
+
const finalStart = separatorStart + bestHeadBoundary;
|
|
175
|
+
const finalEnd = mainEnd + bestTailBoundary;
|
|
176
|
+
// Extract the expanded highlight
|
|
177
|
+
const expandedHighlightText = content
|
|
178
|
+
.substring(finalStart, finalEnd)
|
|
179
|
+
.trim();
|
|
180
|
+
highlights.push({
|
|
181
|
+
text: expandedHighlightText,
|
|
182
|
+
score: highlight.score,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
delete resultCopy.content;
|
|
186
|
+
resultCopy.highlights = highlights;
|
|
187
|
+
return resultCopy;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
return resultCopy;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
exports.expandHighlights = expandHighlights;
|
|
194
|
+
//# sourceMappingURL=highlights.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlights.cjs","sources":["../../../../src/tools/search/highlights.ts"],"sourcesContent":["import type * as t from './types';\n\n// 2. Pre-compile all regular expressions (only do this once)\n// Group patterns by priority for early returns\nconst priorityPatterns = [\n // High priority patterns (structural)\n [\n { regex: /\\n\\n/g }, // Double newline (paragraph break)\n { regex: /\\n/g }, // Single newline\n { regex: /={3,}\\s*\\n|-{3,}\\s*\\n/g }, // Section separators\n ],\n // Medium priority (semantic)\n [\n { regex: /[.!?][\")\\]]?\\s/g }, // End of sentence\n { regex: /;\\s/g }, // Semicolon\n { regex: /:\\s/g }, // Colon\n ],\n // Low priority (any breaks)\n [\n { regex: /,\\s/g }, // Comma\n { regex: /\\s-\\s/g }, // Dash surrounded by spaces\n { regex: /\\s/g }, // Any space\n ],\n];\n\nfunction findFirstMatch(text: string, regex: RegExp): number {\n // Reset regex\n regex.lastIndex = 0;\n\n // For very long texts, try chunking\n if (text.length > 10000) {\n const chunkSize = 2000;\n let position = 0;\n\n while (position < text.length) {\n const chunk = text.substring(position, position + chunkSize);\n regex.lastIndex = 0;\n\n const match = regex.exec(chunk);\n if (match) {\n return position + match.index;\n }\n\n // Move to next chunk with some overlap\n position += chunkSize - 100;\n if (position >= text.length) break;\n }\n return -1;\n }\n\n // For shorter texts, normal regex search\n const match = regex.exec(text);\n return match ? match.index : -1;\n}\n\n// 3. Optimized boundary finding functions\nfunction findLastMatch(text: string, regex: RegExp): number {\n // Reset regex state\n regex.lastIndex = 0;\n\n let lastIndex = -1;\n let lastLength = 0;\n let match;\n\n // For very long texts, use a different approach to avoid regex engine slowdowns\n if (text.length > 10000) {\n // Try dividing the text into chunks for faster processing\n const chunkSize = 2000;\n let startPosition = Math.max(0, text.length - chunkSize);\n\n while (startPosition >= 0) {\n const chunk = text.substring(startPosition, startPosition + chunkSize);\n regex.lastIndex = 0;\n\n let chunkLastIndex = -1;\n let chunkLastLength = 0;\n\n while ((match = regex.exec(chunk)) !== null) {\n chunkLastIndex = match.index;\n chunkLastLength = match[0].length;\n }\n\n if (chunkLastIndex !== -1) {\n return startPosition + chunkLastIndex + chunkLastLength;\n }\n\n // Move to previous chunk with some overlap\n startPosition = Math.max(0, startPosition - chunkSize + 100) - 1;\n if (startPosition <= 0) break;\n }\n return -1;\n }\n\n // For shorter texts, normal regex search\n while ((match = regex.exec(text)) !== null) {\n lastIndex = match.index;\n lastLength = match[0].length;\n }\n\n return lastIndex === -1 ? -1 : lastIndex + lastLength;\n}\n\n// 4. Find the best boundary with priority groups\nfunction findBestBoundary(text: string, direction = 'backward'): number {\n if (!text || text.length === 0) return 0;\n\n // Try each priority group\n for (const patternGroup of priorityPatterns) {\n for (const pattern of patternGroup) {\n const position =\n direction === 'backward'\n ? findLastMatch(text, pattern.regex)\n : findFirstMatch(text, pattern.regex);\n\n if (position !== -1) {\n return position;\n }\n }\n }\n\n // No match found, use character boundary\n return direction === 'backward' ? text.length : 0;\n}\n\n/**\n * Expand highlights in search results using smart boundary detection.\n *\n * This implementation finds natural text boundaries like paragraphs, sentences,\n * and phrases to provide context while maintaining readability.\n *\n * @param searchResults - Search results object\n * @param mainExpandBy - Primary expansion size on each side (default: 300)\n * @param separatorExpandBy - Additional range to look for separators (default: 150)\n * @returns Copy of search results with expanded highlights\n */\nexport function expandHighlights(\n searchResults: t.SearchResultData,\n mainExpandBy = 300,\n separatorExpandBy = 150\n): t.SearchResultData {\n // 1. Avoid full deep copy - only copy what we modify\n const resultCopy = { ...searchResults };\n\n // Only deep copy the relevant arrays\n if (resultCopy.organic) {\n resultCopy.organic = [...resultCopy.organic];\n }\n if (resultCopy.topStories) {\n resultCopy.topStories = [...resultCopy.topStories];\n }\n\n // 5. Process the results efficiently\n const processResultTypes = ['organic', 'topStories'] as const;\n\n for (const resultType of processResultTypes) {\n if (!resultCopy[resultType as 'organic' | 'topStories']) continue;\n\n // Map results to new array with modified highlights\n resultCopy[resultType] = resultCopy[resultType]?.map((result) => {\n if (\n result.content == null ||\n result.content === '' ||\n !result.highlights ||\n result.highlights.length === 0\n ) {\n return result; // No modification needed\n }\n\n // Create a shallow copy with expanded highlights\n const resultCopy = { ...result };\n const content = result.content;\n const highlights = [];\n\n // Process each highlight\n for (const highlight of result.highlights) {\n const highlightText = highlight.text;\n\n let startPos = content.indexOf(highlightText);\n let highlightLen = highlightText.length;\n\n if (startPos === -1) {\n // Try with stripped whitespace\n const strippedHighlight = highlightText.trim();\n startPos = content.indexOf(strippedHighlight);\n\n if (startPos === -1) {\n highlights.push({\n text: highlight.text,\n score: highlight.score,\n });\n continue;\n }\n highlightLen = strippedHighlight.length;\n }\n\n // Calculate boundaries\n const mainStart = Math.max(0, startPos - mainExpandBy);\n const mainEnd = Math.min(\n content.length,\n startPos + highlightLen + mainExpandBy\n );\n\n const separatorStart = Math.max(0, mainStart - separatorExpandBy);\n const separatorEnd = Math.min(\n content.length,\n mainEnd + separatorExpandBy\n );\n\n // Extract text segments\n const headText = content.substring(separatorStart, mainStart);\n const tailText = content.substring(mainEnd, separatorEnd);\n\n // Find natural boundaries\n const bestHeadBoundary = findBestBoundary(headText, 'backward');\n const bestTailBoundary = findBestBoundary(tailText, 'forward');\n\n // Calculate final positions\n const finalStart = separatorStart + bestHeadBoundary;\n const finalEnd = mainEnd + bestTailBoundary;\n\n // Extract the expanded highlight\n const expandedHighlightText = content\n .substring(finalStart, finalEnd)\n .trim();\n highlights.push({\n text: expandedHighlightText,\n score: highlight.score,\n });\n }\n\n delete resultCopy.content;\n resultCopy.highlights = highlights;\n return resultCopy;\n });\n }\n\n return resultCopy;\n}\n"],"names":[],"mappings":"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"}
|