+from datetime import datetime
+from datetime import timedelta
+from datetime import timezone
+from typing import cast
+
+from langchain_core.messages import HumanMessage
+from langchain_core.runnables import RunnableConfig
+from langgraph.types import StreamWriter
+
+from onyx.agents.agent_search.dc_search_analysis.ops import extract_section
+from onyx.agents.agent_search.dc_search_analysis.ops import research
+from onyx.agents.agent_search.dc_search_analysis.states import ObjectSourceInput
+from onyx.agents.agent_search.dc_search_analysis.states import (
+ ObjectSourceResearchUpdate,
+)
+from onyx.agents.agent_search.models import GraphConfig
+from onyx.agents.agent_search.shared_graph_utils.agent_prompt_ops import (
+ trim_prompt_piece,
+)
+from onyx.prompts.agents.dc_prompts import DC_OBJECT_SOURCE_RESEARCH_PROMPT
+from onyx.utils.logger import setup_logger
+from onyx.utils.threadpool_concurrency import run_with_timeout
+
+logger = setup_logger()
+
+
+def research_object_source(
+ state: ObjectSourceInput,
+ config: RunnableConfig,
+ writer: StreamWriter = lambda _: None,
+) -> ObjectSourceResearchUpdate:
+ """
+ LangGraph node to start the agentic search process.
+ """
+ datetime.now()
+
+ graph_config = cast(GraphConfig, config["metadata"]["config"])
+ graph_config.inputs.search_request.query
+ search_tool = graph_config.tooling.search_tool
+ question = graph_config.inputs.search_request.query
+ object, document_source = state.object_source_combination
+
+ if search_tool is None or graph_config.inputs.search_request.persona is None:
+ raise ValueError("Search tool and persona must be provided for DivCon search")
+
+ try:
+ instructions = graph_config.inputs.search_request.persona.prompts[
+ 0
+ ].system_prompt
+
+ agent_2_instructions = extract_section(
+ instructions, "Agent Step 2:", "Agent Step 3:"
+ )
+ if agent_2_instructions is None:
+ raise ValueError("Agent 2 instructions not found")
+
+ agent_2_task = extract_section(
+ agent_2_instructions, "Task:", "Independent Research Sources:"
+ )
+ if agent_2_task is None:
+ raise ValueError("Agent 2 task not found")
+
+ agent_2_time_cutoff = extract_section(
+ agent_2_instructions, "Time Cutoff:", "Output Objective:"
+ )
+
+ agent_2_output_objective = extract_section(
+ agent_2_instructions, "Output Objective:"
+ )
+ if agent_2_output_objective is None:
+ raise ValueError("Agent 2 output objective not found")
+
+ except Exception:
+ raise ValueError(
+ "Agent 1 instructions not found or not formatted correctly: {e}"
+ )