{"version":3,"sources":["../src/index.ts","../src/graph.ts","../src/schema.ts","../src/state.ts","../src/configuration.ts","../src/prompts.ts","../src/utils.ts"],"sourcesContent":["export * from './graph.js';\nexport * from './types.js';\nexport type { Configuration } from './configuration.js';\nexport { HumanMessage, AIMessage, SystemMessage, BaseMessage } from 'langchain';","import { Send, START, END, StateGraph } from '@langchain/langgraph';\nimport { RunnableConfig } from '@langchain/core/runnables';\nimport { ChatOpenAI, type ClientOptions } from '@langchain/openai';\nimport { AnthropicInput, ChatAnthropic } from '@langchain/anthropic';\nimport { ChatGoogleGenerativeAI } from '@langchain/google-genai';\nimport { ChatVertexAI } from '@langchain/google-vertexai';\nimport { AIMessage, createAgent, HumanMessage, toolStrategy } from 'langchain';\nimport { ReflectionSchema, SearchQueryListSchema } from './schema.js';\nimport {\n  OverallAnnotation,\n  OutputAnnotation,\n  ResearchState,\n} from './state.js';\nimport {\n  Configuration,\n  ConfigurationSchema,\n  getConfigurationFromRunnableConfig,\n} from './configuration.js';\nimport {\n  answerInstructions,\n  queryWriterInstructions,\n  reflectionInstructions,\n  searcherInstructions,\n} from './prompts.js';\nimport { SearcherFunction, SearchResultItem } from './types.js';\nimport { getCitations, getCurrentDate, getResearchTopic, replaceVariable } from './utils.js';\n\nexport enum NodeEnum {\n  GenerateQuery = 'generate_query',\n  Research = 'research',\n  Reflection = 'reflection',\n  FinalizeAnswer = 'finalize_answer',\n}\n\nexport enum EventStreamEnum {\n  ChatModelStart = 'on_chat_model_start',\n  ChatModelStream = 'on_chat_model_stream',\n  ChatModelEnd = 'on_chat_model_end',\n}\n\nexport interface DeepResearchOptions extends ClientOptions {\n  type?: 'openai' | 'anthropic' | 'gemini' | 'vertexai';\n  systemPrompt?: string;\n  temperature?: number;\n  /**\n   * Enable URL format in citations (default: true)\n   * - true: output format is <sup>[[id](url)]</sup>\n   * - false: output format is [[citation:id]]\n   */\n  enableCitationUrl?: boolean;\n}\n\nexport class DeepResearch {\n  private readonly options?: DeepResearchOptions;\n  private readonly searcher: SearcherFunction;\n\n  /**\n   * @param searcher - The function to use for searching\n   * @param options - The options for the Runnable, including LLM provider settings\n   */\n  constructor({\n    searcher,\n    options,\n  }: {\n    searcher: SearcherFunction;\n    options?: DeepResearchOptions;\n  }) {\n    this.searcher = searcher;\n    this.options = options;\n  }\n\n  async compile() {\n    const workflow = new StateGraph(OverallAnnotation, ConfigurationSchema);\n\n    workflow.addNode(NodeEnum.GenerateQuery, this.generateQuery.bind(this));\n    workflow.addNode(NodeEnum.Research, this.research.bind(this), {\n      input: ResearchState,\n    });\n    workflow.addNode(NodeEnum.Reflection, this.reflection.bind(this));\n    workflow.addNode(NodeEnum.FinalizeAnswer, this.finalizeAnswer.bind(this));\n\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore\n    workflow.addEdge(START, NodeEnum.GenerateQuery);\n\n    workflow.addConditionalEdges(\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore\n      NodeEnum.GenerateQuery,\n      this.continueToSearch.bind(this),\n      [NodeEnum.Research]\n    );\n\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore\n    workflow.addEdge(NodeEnum.Research, NodeEnum.Reflection);\n\n    workflow.addConditionalEdges(\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore\n      NodeEnum.Reflection,\n      this.evaluateResearch.bind(this),\n      [NodeEnum.Research, NodeEnum.FinalizeAnswer]\n    );\n\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore\n    workflow.addEdge(NodeEnum.FinalizeAnswer, END);\n\n    return workflow.compile({ name: 'DeepResearch' });\n  }\n\n  /**\n   * LangGraph node that generates a search queries based on the User's question.\n   * Create an optimized search query for research based on the User's question.\n   * @param state - Overall graph state\n   * @param config - Configuration for the Runnable\n   */\n  private async generateQuery(\n    state: typeof OverallAnnotation.State,\n    config: RunnableConfig<Configuration>\n  ): Promise<Partial<typeof OverallAnnotation.State>> {\n    const configuration = getConfigurationFromRunnableConfig(config);\n    const { numberOfInitialQueries, queryGeneratorModel } = configuration;\n    const { systemPrompt = 'You are a helpful research assistant.', temperature = 0.1 } = this.options || {};\n\n    const topic = getResearchTopic(state.messages);\n    const currentDate = getCurrentDate();\n\n    const client = this.createClient(queryGeneratorModel, temperature);\n    const agent = createAgent({\n      model: client,\n      tools: [],\n      systemPrompt,\n      responseFormat: toolStrategy(SearchQueryListSchema, {\n        toolMessageContent: `I will generate ${numberOfInitialQueries} search queries based on your input.`,\n      }),\n    });\n\n    const prompt = replaceVariable(\n      queryWriterInstructions,\n      {\n        number_queries: numberOfInitialQueries,\n        current_date: currentDate,\n        research_topic: topic,\n      }\n    );\n\n    try {\n      const result = await agent.invoke({\n        messages: [\n          new HumanMessage(prompt),\n        ]\n      }, {\n        tags: [NodeEnum.GenerateQuery]\n      });\n\n      // Ensure a valid query list is returned\n      const queryList = result.structuredResponse?.query || [];\n      if (queryList.length === 0) {\n        console.warn(\n          'LLM returned empty query list, using original topic as fallback'\n        );\n        return { generatedQueries: [topic] };\n      }\n\n      return { generatedQueries: queryList, rationale: result.structuredResponse?.rationale };\n    } catch (error) {\n      console.error('Failed to generate search queries:', error);\n      console.warn('Using original topic as fallback due to LLM failure');\n      return { generatedQueries: [topic] };\n    }\n  }\n\n  /**\n   * LangGraph routing function that sends search queries to research nodes.\n   * This is used to spawn n number of research nodes, one for each search query.\n   * @param state - Overall graph state\n   */\n  private async continueToSearch(state: typeof OverallAnnotation.State) {\n    const queryList = state.generatedQueries || [];\n\n    if (queryList.length === 0) {\n      const topic = getResearchTopic(state.messages);\n      return [new Send(NodeEnum.Research, { query: topic, id: '0' })];\n    }\n\n    return queryList.map(\n      (query, idx) => new Send(NodeEnum.Research, { query, id: idx.toString(), loopIndex: 1 })\n    );\n  }\n\n  /**\n   * LangGraph node that performs research based on the search query.\n   * @param state - Research graph state\n   * @param config - Configuration for the Runnable\n   */\n  private async research(\n    state: typeof ResearchState.State,\n    config: RunnableConfig<Configuration>\n  ): Promise<Partial<typeof OverallAnnotation.State>> {\n    const configuration = getConfigurationFromRunnableConfig(config);\n    const { queryGeneratorModel } = configuration;\n    const { temperature = 0.1, enableCitationUrl = true } = this.options || {};\n\n    const searchResults = await this.searcher(state);\n    const formattedSearchResults = searchResults\n      .map(\n        ({ title, content, date, score }, index) =>\n          `[[${index + 1}]]. Title: ${title}\\nContent: ${content}\\nDate: ${\n            date ?? 'N/A'\n          }\\nConfidence Score: ${score ?? 'N/A'}`\n      )\n      .join('\\n\\n');\n\n    const client = this.createClient(queryGeneratorModel, temperature);\n    const agent = createAgent({\n      model: client,\n      tools: [],\n    });\n\n    const prompt = replaceVariable(\n      searcherInstructions,\n      {\n        current_date: getCurrentDate(),\n        research_topic: state.query,\n        search_results: formattedSearchResults,\n      }\n    );\n\n    const result = await agent.invoke({\n      messages: [\n        new HumanMessage(prompt),\n      ]\n    }, {\n      tags: [NodeEnum.Research]\n    });\n\n    // Extract the AI message content from the agent result\n    const lastMessage = result.messages[result.messages.length - 1];\n\n    // Return content and referenced indexes, content contains citation marks with URL\n    const { content, segmentIndexes } = getCitations(lastMessage, searchResults, enableCitationUrl);\n\n    const usedSources = searchResults.filter((_, index) =>\n      segmentIndexes.includes(`${index + 1}`)\n    );\n\n    return {\n      sourcesGathered: usedSources,\n      searchedQueries: [state.query],\n      researchResult: [content],\n      researchLoopCount: state.loopIndex,\n    };\n  }\n\n  /**\n   * LangGraph node that identifies knowledge gaps and generates potential follow-up queries.\n   * Analyzes the current summary to identify areas for further research and generates\n   * potential follow-up queries. Uses structured output to extract\n   * the follow-up query in JSON format.\n   */\n  private async reflection(\n    state: typeof OverallAnnotation.State,\n    config: RunnableConfig<Configuration>\n  ): Promise<Partial<typeof OverallAnnotation.State>> {\n    const configuration = getConfigurationFromRunnableConfig(config);\n    const { reflectionModel, numberOfInitialQueries } = configuration;\n    const { temperature = 0.1 } = this.options || {};\n\n    // const researchLoopCount = (state.researchLoopCount ?? 0) + 1;\n\n    const researchTopic = getResearchTopic(state.messages);\n    const summaries = state.researchResult.join('\\n\\n');\n\n    const client = this.createClient(reflectionModel, temperature);\n    const agent = createAgent({\n      model: client,\n      tools: [],\n      responseFormat: toolStrategy(ReflectionSchema, {\n        toolMessageContent: 'I will analyze the research summaries and determine if more information is needed.',\n      }),\n    });\n\n    const prompt = replaceVariable(\n      reflectionInstructions,\n      {\n        research_topic: researchTopic,\n        summaries,\n        number_queries: numberOfInitialQueries,\n      }\n    );\n\n    try {\n      const result = await agent.invoke({\n        messages: [\n          new HumanMessage(prompt),\n        ]\n      }, {\n        tags: [NodeEnum.Reflection]\n      });\n\n      const structuredResponse = result.structuredResponse;\n\n      return {\n        // researchLoopCount,\n        reflectionState: {\n          isSufficient: structuredResponse?.isSufficient ?? true,\n          knowledgeGap: structuredResponse?.knowledgeGap ?? '',\n          followUpQueries: structuredResponse?.followUpQueries || [],\n          numberOfRanQueries: state.searchedQueries.length,\n        }\n      };\n    } catch (error) {\n      console.error('Failed to generate reflection:', error);\n      // if reflection fails, return default value\n      return {\n        // researchLoopCount,\n        reflectionState: {\n          isSufficient: true, // assume the research is sufficient\n          knowledgeGap: 'Unable to analyze knowledge gaps',\n          followUpQueries: [], // empty array, avoid subsequent errors\n          numberOfRanQueries: state.searchedQueries.length,\n        }\n      };\n    }\n  }\n\n  /**\n   * LangGraph routing function that determines the next step in the research flow.\n   * Controls the research loop by deciding whether to continue gathering information\n   * or to finalize the summary based on the configured maximum number of research loops.\n   */\n  private async evaluateResearch(\n    state: typeof OverallAnnotation.State,\n    config: RunnableConfig<Configuration>\n  ) {\n    const { reflectionState, researchLoopCount } = state;\n    const configuration = getConfigurationFromRunnableConfig(config);\n\n    const maxResearchLoops = configuration.maxResearchLoops;\n\n    const { followUpQueries = [], isSufficient, numberOfRanQueries } = reflectionState;\n\n    if (researchLoopCount >= maxResearchLoops || isSufficient) {\n      return NodeEnum.FinalizeAnswer;\n    }\n\n    // check followUpQueries is empty\n    if (!followUpQueries || followUpQueries.length === 0) {\n      console.warn(\n        'No follow-up queries generated, proceeding to finalize answer'\n      );\n      return NodeEnum.FinalizeAnswer;\n    }\n\n    return followUpQueries.map(\n      (query, index) =>\n        new Send(NodeEnum.Research, {\n          query,\n          id: (numberOfRanQueries + index).toString(),\n          loopIndex: researchLoopCount + 1,\n        })\n    );\n  }\n\n  /**\n   * LangGraph node that finalizes the answer based on the provided summaries.\n   * @param state - Overall graph state\n   * @param config - Configuration for the Runnable\n   */\n  private async finalizeAnswer(\n    state: typeof OverallAnnotation.State,\n    config: RunnableConfig<Configuration>\n  ): Promise<typeof OutputAnnotation.State> {\n    const configuration = getConfigurationFromRunnableConfig(config);\n    const { reflectionModel } = configuration;\n    const { systemPrompt = 'You are a helpful research assistant.', temperature = 0.1, enableCitationUrl = true } = this.options || {};\n\n    const model = reflectionModel;\n    const currentDate = getCurrentDate();\n    const researchTopic = getResearchTopic(state.messages);\n    const summaries = state.researchResult.join('\\n\\n');\n\n    if (!summaries.trim()) {\n      return {\n        messages: [\n          new AIMessage(\n            'Sorry, no useful information was retrieved. Please try again later or ask a different question.'\n          ),\n        ],\n        sourcesGathered: [],\n      };\n    }\n\n    const client = this.createClient(model, temperature);\n    const agent = createAgent({\n      model: client,\n      tools: [],\n      systemPrompt,\n    });\n\n    const prompt = replaceVariable(\n      answerInstructions,\n      {\n        research_topic: researchTopic,\n        summaries,\n        current_date: currentDate,\n      }\n    );\n\n    const result = await agent.invoke({\n      messages: [\n        new HumanMessage(prompt),\n      ],\n    }, {\n      tags: [NodeEnum.FinalizeAnswer],\n    });\n\n    // Extract the AI message content from the agent result\n    const lastMessage = result.messages[result.messages.length - 1];\n    const messageContent = typeof lastMessage.content === 'string' \n      ? lastMessage.content \n      : JSON.stringify(lastMessage.content);\n\n    const sourcesGathered: SearchResultItem[] = [];\n    for (const source of state.sourcesGathered) {\n      let isIncluded = false;\n\n      if (enableCitationUrl) {\n        // Check for URL citation formats when enableCitationUrl is true\n        const citationWithUrl = `<sup>[[${source.id}](${source.url})]</sup>`;\n        const citationWithoutUrl = `<sup>[[${source.id}]]</sup>`;\n        isIncluded = messageContent.includes(citationWithUrl) || messageContent.includes(citationWithoutUrl);\n      } else {\n        // Check for simple citation format when enableCitationUrl is false\n        const simpleCitation = `[[citation:${source.id}]]`;\n        isIncluded = messageContent.includes(simpleCitation);\n      }\n\n      if (isIncluded) {\n        sourcesGathered.push(source);\n      }\n    }\n\n    return {\n      messages: [new AIMessage(messageContent)],\n      sourcesGathered,\n    };\n  }\n\n  private createClient(model: string, temperature = 0.1) {\n    const { apiKey, type = 'openai', baseURL, ...rest } = this.options || {};\n    switch (type) {\n      case 'anthropic': {\n        const options: AnthropicInput = {\n          model: model,\n          anthropicApiKey: apiKey as string,\n          temperature,\n          ...rest,\n        };\n        if (baseURL) {\n          options.anthropicApiUrl = baseURL;\n        }\n        return new ChatAnthropic(options);\n      }\n      case 'gemini':\n        return new ChatGoogleGenerativeAI({\n          model: model,\n          apiKey: apiKey as string,\n          baseUrl: baseURL || undefined,\n          temperature,\n          ...rest,\n        });\n      case 'vertexai':\n        return new ChatVertexAI({\n          model: model,\n          apiKey: apiKey as string,\n          temperature,\n          ...rest,\n        });\n      case 'openai':\n      default:\n        return new ChatOpenAI({\n          model: model,\n          openAIApiKey: apiKey,\n          temperature,\n          configuration: {\n            apiKey,\n            baseURL,\n            ...rest,\n          }\n        });\n    }\n  }\n}\n","import { z } from 'zod';\n\n// 搜索查询列表 Schema\nexport const SearchQueryListSchema = z.object({\n  query: z\n    .array(z.string())\n    .describe('A list of search queries to be used for research.'),\n  rationale: z\n    .string()\n    .describe(\n      'A brief explanation of why these queries are relevant to the research topic.'\n    ),\n});\n\n// 反思 Schema\nexport const ReflectionSchema = z.object({\n  isSufficient: z\n    .boolean()\n    .describe(\n      'Whether the provided summaries are sufficient to answer the user\\'s question.'\n    ),\n  knowledgeGap: z\n    .string()\n    .describe(\n      'A description of what information is missing or needs clarification.'\n    ),\n  followUpQueries: z\n    .array(z.string())\n    .describe('A list of follow-up queries to address the knowledge gap.'),\n});\n\nexport type SearchQueryList = z.infer<typeof SearchQueryListSchema>;\nexport type Reflection = z.infer<typeof ReflectionSchema>;\n","import { addMessages, Annotation } from '@langchain/langgraph';\nimport type { AIMessage } from 'langchain';\nimport type { BaseMessageLike } from '@langchain/core/messages';\nimport { SearchResultItem } from './types.js';\n\n// Global State\nexport const OverallAnnotation = Annotation.Root({\n  messages: Annotation<BaseMessageLike[]>({\n    reducer: addMessages,\n    default: () => [],\n  }),\n  rationale: Annotation<string>,\n  generatedQueries: Annotation<string[]>,\n  searchedQueries: Annotation<string[]>({\n    reducer: (current, update) => current.concat(update),\n    default: () => [],\n  }),\n  researchResult: Annotation<string[]>({\n    reducer: (current, update) => current.concat(update),\n    default: () => [],\n  }),\n  sourcesGathered: Annotation<SearchResultItem[]>({\n    reducer: (current, update) => current.concat(update),\n    default: () => [],\n  }),\n  researchLoopCount: Annotation<number>({\n    reducer: (current, update) => Math.max(current, update ?? 0),\n    default: () => 0,\n  }),\n  // reflection state\n  reflectionState: Annotation<typeof ReflectionState.State>,\n});\n\n// Output state\nexport const OutputAnnotation = Annotation.Root({\n  sourcesGathered: Annotation<SearchResultItem[]>,\n  messages: Annotation<AIMessage[]>,\n});\n\n// Reflection state\nexport const ReflectionState = Annotation.Root({\n  isSufficient: Annotation<boolean>,\n  knowledgeGap: Annotation<string>,\n  followUpQueries: Annotation<string[]>,\n  numberOfRanQueries: Annotation<number>,\n});\n\n// research state\nexport const ResearchState = Annotation.Root({\n  query: Annotation<string>,\n  id: Annotation<string>,\n  loopIndex: Annotation<number>,\n});\n","import { RunnableConfig } from '@langchain/core/runnables';\nimport { z } from 'zod';\n\nexport const ConfigurationSchema = z.object({\n  queryGeneratorModel: z\n    .string()\n    .describe(\n      'The name of the language model to use for the agent\\'s query generation.'\n    ),\n  reflectionModel: z\n    .string()\n    .describe(\n      'The name of the language model to use for the agent\\'s reflection.'\n    ),\n  answerModel: z\n    .string()\n    .describe('The name of the language model to use for the agent\\'s answer.'),\n  numberOfInitialQueries: z\n    .number()\n    .describe('The number of initial search queries to generate.'),\n  maxResearchLoops: z\n    .number()\n    .describe('The maximum number of research loops to perform.'),\n});\n\nexport type Configuration = z.infer<typeof ConfigurationSchema>;\n\nconst DEFAULT_CONFIG: Omit<\n  Configuration,\n  'queryGeneratorModel' | 'reflectionModel' | 'answerModel'\n> = {\n  numberOfInitialQueries: 3,\n  maxResearchLoops: 3,\n};\n\n/**\n * Create a Configuration object from a RunnableConfig.\n */\nexport function getConfigurationFromRunnableConfig(\n  config?: RunnableConfig<Partial<Configuration>>\n): Configuration {\n  const configurable = config?.configurable ?? {};\n\n  if (\n    !configurable.answerModel ||\n    !configurable.queryGeneratorModel ||\n    !configurable.reflectionModel\n  ) {\n    throw new Error(\n      'Missing required model configuration: answerModel, queryGeneratorModel, and reflectionModel must be provided'\n    );\n  }\n\n  const rawValues: Configuration = {\n    queryGeneratorModel: configurable.queryGeneratorModel,\n    reflectionModel: configurable.reflectionModel,\n    answerModel: configurable.answerModel,\n    numberOfInitialQueries:\n      configurable.numberOfInitialQueries ??\n      DEFAULT_CONFIG.numberOfInitialQueries,\n    maxResearchLoops:\n      configurable.maxResearchLoops ?? DEFAULT_CONFIG.maxResearchLoops,\n  };\n\n  // Filter out undefined values and convert string numbers to numbers\n  Object.entries(rawValues).forEach(([key, value]) => {\n    if (value !== undefined) {\n      if (key === 'numberOfInitialQueries' || key === 'maxResearchLoops') {\n        const numValue =\n          typeof value === 'string' ? parseInt(value, 10) : value;\n        (rawValues as Record<string, unknown>)[key] = numValue;\n      }\n    }\n  });\n\n  return rawValues;\n}\n","export const queryWriterInstructions = `Your goal is to generate sophisticated and diverse search queries. These queries are intended for an advanced automated research tool capable of analyzing complex results, following links, and synthesizing information.\n\nInstructions:\n- Always prefer a single search query, only add another query if the original question requests multiple aspects or elements and one query is not enough.\n- Each query should focus on one specific aspect of the original question.\n- Don't produce more than {number_queries} queries.\n- Queries should be diverse, if the topic is broad, generate more than 1 query.\n- Don't generate multiple similar queries, 1 is enough.\n- Query should ensure that the most current information is gathered. The current date is {current_date}.\n- Use specific keywords and technical terms rather than long descriptive sentences.\n- Focus on core concepts, product names, versions, or specific features for better search results.\n- **Language Constraint**: Always respond in the same language as the user's input. If the user asks in Chinese, respond in Chinese; if in English, respond in English, etc.\n\nContext: {research_topic}`;\n\nexport const searcherInstructions = `Conduct targeted searches to gather the most recent, credible information on \"{research_topic}\" and synthesize it into a verifiable text artifact.\n\nInstructions:\n- Query should ensure that the most current information is gathered. The current date is {current_date}.\n- Conduct multiple, diverse searches to gather comprehensive information.\n- Consolidate key findings while meticulously tracking the source(s) for each specific piece of information.\n- The output should be a well-written summary or report based on your search findings.\n- Only include the information found in the search results, don't make up any information.\n- For each key finding, use numbered citations in the format [[citation:1]], [[citation:2]], etc., referring to the search result numbers below.\n- **Language Constraint**: Always respond in the same language as the user's input. If the user asks in Chinese, respond in Chinese; if in English, respond in English, etc.\n\nCitation Format:\n- Use [[citation:1]], [[citation:2]], [[citation:3]] etc. to cite specific search results\n- Each important claim or data point must include a citation\n- Multiple sources can be cited as [[citation:1]][[citation:2]]\n\nExample output format:\n\"According to recent studies, XYZ technology has shown significant improvements [[citation:1]]. Market adoption rates have increased by 25% in 2024 [[citation:2]][[citation:3]].\"\n\nSearch Results:\n{search_results}\n\nResearch Topic:\n{research_topic}\n`;\n\nexport const reflectionInstructions = `You are an expert research assistant analyzing summaries about \"{research_topic}\".\n\nInstructions:\n- Identify knowledge gaps or areas that need deeper exploration and generate a follow-up query. (1 or multiple).\n- If provided summaries are sufficient to answer the user's question, don't generate a follow-up query.\n- If there is a knowledge gap, generate a follow-up query that would help expand your understanding.\n- Don't produce more than {number_queries} follow-up queries.\n- Focus on technical details, implementation specifics, or emerging trends that weren't fully covered.\n- **Language Constraint**: Always respond in the same language as the user's input. If the user asks in Chinese, respond in Chinese; if in English, respond in English, etc.\n\nQuery Optimization Requirements:\n- Ensure the follow-up query is self-contained and includes necessary context for search.\n- Use specific keywords and technical terms rather than long descriptive sentences.\n- Focus on core concepts, product names, versions, or specific features.\n- Avoid overly complex or verbose phrasing that may reduce search effectiveness.\n- **Language Constraint**: Always respond in the same language as the user's input. If the user asks in Chinese, respond in Chinese; if in English, respond in English, etc.\n\nReflect carefully on the Summaries to identify knowledge gaps and produce a follow-up query.\n\nSummaries:\n{summaries}\n`;\n\nexport const answerInstructions = `Generate a high-quality answer to the user's question based on the provided summaries.\n\nInstructions:\n- The current date is {current_date}.\n- You are the final step of a multi-step research process, don't mention that you are the final step.\n- You have access to all the information gathered from the previous steps.\n- You have access to the user's question.\n- Generate a high-quality answer to the user's question based on the provided summaries and the user's question.\n- you MUST include all the citations from the summaries in the answer correctly in the format [[citation:number]].\n- **Language Constraint**: Always respond in the same language as the user's input. If the user asks in Chinese, respond in Chinese; if in English, respond in English, etc.\n\nUser Context:\n- {research_topic}\n\nSummaries:\n{summaries}`;\n","import {\n  HumanMessage,\n  AIMessage,\n  AIMessageChunk,\n  BaseMessageLike,\n} from '@langchain/core/messages';\nimport { SearchResultItem } from './types.js';\n\n/**\n * Get the research topic from the messages.\n */\nexport function getResearchTopic(messages: BaseMessageLike[]) {\n  // check if request has a history and combine the messages into a single string\n  if (messages.length === 1) {\n    const msg = messages[messages.length - 1];\n    if (typeof msg === 'string') {\n      return msg;\n    }\n    if ('content' in msg) {\n      if (typeof msg.content === 'string') {\n        return msg.content;\n      }\n      if (Array.isArray(msg.content)) {\n        return msg.content\n          .map(item => item.type === 'text' ? item.text : '')\n          .join('\\n');\n      }\n    }\n    return JSON.stringify(msg);\n  } else {\n    let researchTopic = '';\n    for (const message of messages) {\n      if (message instanceof HumanMessage) {\n        researchTopic += `User: ${message.content}\\n`;\n      } else if (message instanceof AIMessage) {\n        researchTopic += `Assistant: ${message.content}\\n`;\n      }\n    }\n    return researchTopic;\n  }\n}\n\n/**\n * Extracts and formats citation information from a model's response.\n * Original Citation Format:\n * - [[1]], [[2]], [[3]] or [[citation:1]], [[citation:2]] etc. to cite specific search results\n * - Multiple sources can be cited as [[1]][[2]] or [[citation:1]][[citation:2]]\n * Formatted Citation Format:\n * - If enableUrl is true: `<sup>[[id](url)]</sup>` if URL exists, `<sup>[[id]]</sup>` if no URL\n * - If enableUrl is false: `[[citation:id]]`\n */\nexport function getCitations(\n  response: AIMessageChunk | { content: string | unknown },\n  sources: SearchResultItem[],\n  enableUrl = true\n) {\n  const text = typeof response.content === 'string'\n    ? response.content\n    : JSON.stringify(response.content);\n\n  const replaceCitationMark = (text: string): string => {\n    return (\n      text\n        // Convert [[citation:number]] to [citation](number)\n        .replace(/\\[\\[citation:(\\d+)]]/g, '[citation]($1)')\n        // Convert [[number]] to [citation](number)\n        .replace(/\\[\\[(\\d+)]]/g, '[citation]($1)')\n        // Convert [number] to [citation](number)\n        .replace(/(?<!\\[)\\[(\\d+)](?!])/g, '[citation]($1)')\n    );\n  };\n\n  // Get numbers from the application content\n  const getCitationNumber = (text: string): string[] => {\n    const regex = /\\[citation\\]\\((\\d+)\\)/g;\n    const numbers: string[] = [];\n    let match;\n    while ((match = regex.exec(text)) !== null) {\n      numbers.push(match[1]);\n    }\n    return numbers;\n  };\n\n  const formattedText = replaceCitationMark(text);\n\n  // insert citations with URL or keep simple format\n  const citationRegex = /\\[citation\\]\\((\\d+)\\)/g;\n  const citationNumbers = getCitationNumber(formattedText);\n\n  const insertedText = formattedText.replace(citationRegex, str => {\n    const index = parseInt(str.match(/\\((\\d+)\\)/)?.[1] ?? '0', 10);\n    const source = sources[index - 1];\n    if (!source) {\n      return str;\n    }\n\n    // If enableUrl is false, return simple citation format\n    if (!enableUrl) {\n      return `[[citation:${source.id}]]`;\n    }\n\n    // If enableUrl is true, return URL format\n    if (source.url) {\n      return `<sup>[[${source.id}](${source.url})]</sup>`;\n    }\n    return `<sup>[[${source.id}]]</sup>`;\n  });\n\n  return {\n    content: insertedText,\n    segmentIndexes: citationNumbers,\n  };\n}\n\nexport const getCurrentDate = () => new Date().toISOString();\n\n/**\n * replace the variable in the string with the value\n * e.g replaceVariable(`abc{query}, efg.`, { query: '456' })\n */\nexport function replaceVariable(\n  text: string,\n  obj: Record<string, string | number>\n): string {\n  if (!(typeof text === 'string')) return text;\n\n  for (const key in obj) {\n    const val = obj[key];\n    if (!['string', 'number'].includes(typeof val)) continue;\n\n    text = text.replace(new RegExp(`{(${key})}`, 'g'), String(val));\n  }\n  return text || '';\n}"],"mappings":"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","names":["index_exports","__export","DeepResearch","EventStreamEnum","NodeEnum","__toCommonJS","import_langgraph","import_openai","import_anthropic","import_google_genai","import_google_vertexai","import_langchain","import_zod","SearchQueryListSchema","ReflectionSchema","import_langgraph","OverallAnnotation","current","update","OutputAnnotation","ReflectionState","ResearchState","import_zod","ConfigurationSchema","DEFAULT_CONFIG","getConfigurationFromRunnableConfig","config","configurable","rawValues","key","value","numValue","queryWriterInstructions","searcherInstructions","reflectionInstructions","answerInstructions","import_messages","getResearchTopic","messages","msg","item","researchTopic","message","getCitations","response","sources","enableUrl","text","replaceCitationMark","getCitationNumber","regex","numbers","match","formattedText","citationRegex","citationNumbers","str","index","source","getCurrentDate","replaceVariable","obj","key","val","NodeEnum","EventStreamEnum","DeepResearch","searcher","options","workflow","OverallAnnotation","ConfigurationSchema","ResearchState","state","config","configuration","getConfigurationFromRunnableConfig","numberOfInitialQueries","queryGeneratorModel","systemPrompt","temperature","topic","getResearchTopic","currentDate","getCurrentDate","client","agent","SearchQueryListSchema","prompt","replaceVariable","queryWriterInstructions","result","queryList","error","query","idx","enableCitationUrl","searchResults","formattedSearchResults","title","content","date","score","index","searcherInstructions","lastMessage","segmentIndexes","getCitations","_","reflectionModel","researchTopic","summaries","ReflectionSchema","reflectionInstructions","structuredResponse","reflectionState","researchLoopCount","maxResearchLoops","followUpQueries","isSufficient","numberOfRanQueries","model","answerInstructions","messageContent","sourcesGathered","source","isIncluded","citationWithUrl","citationWithoutUrl","simpleCitation","apiKey","type","baseURL","rest","import_langchain"]}