content: from app.modules.intelligence.agents.chat_agents.agent_config import (
      AgentConfig,
      TaskConfig,
  )
  from app.modules.intelligence.agents.chat_agents.pydantic_agent import PydanticRagAgent
  from app.modules.intelligence.agents.chat_agents.pydantic_multi_agent import (
      PydanticMultiAgent,
      AgentType as MultiAgentType,
  )
  from app.modules.intelligence.agents.multi_agent_config import MultiAgentConfig
  from app.modules.intelligence.prompts.prompt_service import PromptService
  from app.modules.intelligence.provider.provider_service import ProviderService
  from app.modules.intelligence.tools.tool_service import ToolService
  from ...chat_agent import ChatAgent, ChatAgentResponse, ChatContext
  from typing import AsyncGenerator
  from app.modules.utils.logger import setup_logger
  
  logger = setup_logger(__name__)
  
  
  class LowLevelDesignAgent(ChatAgent):
      def __init__(
          self,
          llm_provider: ProviderService,
          tools_provider: ToolService,
          prompt_provider: PromptService,
      ):
          self.llm_provider = llm_provider
          self.tools_provider = tools_provider
          self.prompt_provider = prompt_provider
  
      def _build_agent(self) -> ChatAgent:
          agent_config = AgentConfig(
              role="Design Planner",
              goal="Create a detailed low-level design plan for implementing new features",
              backstory="""
                      You are a senior software architect specializing in creating detailed,
                      actionable design plans. Your expertise lies in breaking down complex features into
                      manageable steps and providing clear guidance for implementation.
                  """,
              tasks=[
                  TaskConfig(
                      description=lld_task_prompt,
                      expected_output="Low-level design plan for implementing the new feature",
                  )
              ],
          )
          tools = self.tools_provider.get_tools(
              [
                  "get_code_from_multiple_node_ids",
                  "get_node_neighbours_from_node_id",
                  "get_code_from_probable_node_name",
                  "ask_knowledge_graph_queries",
                  "get_nodes_from_tags",
                  "webpage_extractor",
                  "web_search_tool",
                  "github_tool",
                  "think",
                  "get_linear_issue",
                  "get_jira_issue",
                  "search_jira_issues",
                  "create_jira_issue",
                  "update_jira_issue",
                  "add_jira_comment",
                  "transition_jira_issue",
                  "get_jira_projects",
                  "get_jira_project_details",
                  "link_jira_issues",
                  "get_jira_project_users",
                  "get_confluence_spaces",
                  "get_confluence_page",
                  "search_confluence_pages",
                  "get_confluence_space_pages",
                  "create_confluence_page",
                  "update_confluence_page",
                  "add_confluence_comment",
                  "fetch_file",
                  "analyze_code_structure",
                  "bash_command",
              ]
          )
  
          supports_pydantic = self.llm_provider.supports_pydantic("chat")
          should_use_multi = MultiAgentConfig.should_use_multi_agent("LLD_agent")
  
          logger.info(
              f"LowLevelDesignAgent: supports_pydantic={supports_pydantic}, should_use_multi_agent={should_use_multi}"
          )
          logger.info(f"Current model: {self.llm_provider.chat_config.model}")
          logger.info(f"Model capabilities: {self.llm_provider.chat_config.capabilities}")
  
          if supports_pydantic:
              if should_use_multi:
                  logger.info("✅ Using PydanticMultiAgent (multi-agent system)")
                  # Create specialized delegate agents for low-level design
                  delegate_agents = {
                      MultiAgentType.THINK_EXECUTE: AgentConfig(
                          role="Design Planning Specialist",
                          goal="Create comprehensive low-level design plans based on analysis",
                          backstory="You are a senior architect who excels at creating detailed, actionable design plans that follow best practices.",
                          tasks=[
                              TaskConfig(
                                  description="Create detailed low-level design plans with clear implementation steps and architectural decisions",
                                  expected_output="Comprehensive low-level design document with implementation roadmap",
                              )
                          ],
                          max_iter=20,
                      ),
                  }
                  return PydanticMultiAgent(
                      self.llm_provider, agent_config, tools, None, delegate_agents
                  )
              else:
                  logger.info("❌ Multi-agent disabled by config, using PydanticRagAgent")
                  return PydanticRagAgent(self.llm_provider, agent_config, tools)
          else:
              logger.error(
                  f"❌ Model '{self.llm_provider.chat_config.model}' does not support Pydantic - using fallback PydanticRagAgent"
              )
              return PydanticRagAgent(self.llm_provider, agent_config, tools)
  
      async def _enriched_context(self, ctx: ChatContext) -> ChatContext:
          if ctx.node_ids and len(ctx.node_ids) > 0:
              code_results = await self.tools_provider.get_code_from_multiple_node_ids_tool.run_multiple(
                  ctx.project_id, ctx.node_ids
              )
              ctx.additional_context += (
                  f"Code Graph context of the node_ids in query:\n {code_results}"
              )
  
          file_structure = (
              await self.tools_provider.file_structure_tool.fetch_repo_structure(
                  ctx.project_id
              )
          )
          ctx.additional_context += f"File Structure of the project:\n {file_structure}"
  
          return ctx
  
      async def run(self, ctx: ChatContext) -> ChatAgentResponse:
          return await self._build_agent().run(await self._enriched_context(ctx))
  
      async def run_stream(
          self, ctx: ChatContext
      ) -> AsyncGenerator[ChatAgentResponse, None]:
          ctx = await self._enriched_context(ctx)
          async for chunk in self._build_agent().run_stream(ctx):
              yield chunk
  
  
  lld_task_prompt = """
  
      IMPORTANT: Use the following guide to accomplish tasks within the current context of execution
      HOW TO GUIDE:
  
      IMPORATANT: steps on HOW TO traverse the codebase:
      1. You can use websearch, docstrings, readme to understand current feature/code you are working with better. Understand how to use current feature in context of codebase
      2. Use AskKnowledgeGraphQueries tool to understand where perticular feature or functionality resides or to fetch specific code related to some keywords. Fetch file structure to understand the codebase better, Use FetchFile tool to fetch code from a file
      3. Use GetcodefromProbableNodeIDs tool to fetch code for perticular class or function in a file, Use analyze_code_structure to get all the class/function/nodes in a file
      4. Use GetcodeFromMultipleNodeIDs to fetch code for nodeIDs fetched from tools before
      5. Use GetNodeNeighboursFromNodeIDs to fetch all the code referencing current code or code referenced in the current node (code snippet)
      6. Above tools and steps can help you figure out full context about the current code in question
      7. Figure out how all the code ties together to implement current functionality
      8. Fetch Dir structure of the repo and use fetch file tool to fetch entire files, if file is too big the tool will throw error, then use code analysis tool to target proper line numbers (feel free to use set startline and endline such that few extra context lines are also fetched, tool won't throw out of bounds exception and return lines if they exist)
      9. Use above mentioned tools to fetch imported code, referenced code, helper functions, classes etc to understand the control flow
  
      Create a detailed low-level design plan for implementing the new feature. Your plan should include:
      1. A high-level overview of the implementation approach.
      2. Detailed steps for implementing the feature, including:
          - Specific files that need to be modified or created.
          - Proposed code changes or additions for each file.
          - Any new classes, methods, or functions that need to be implemented.
      3. Potential challenges or considerations for the implementation.
      4. Any suggestions for maintaining code consistency with the existing codebase.
  
      Use the provided tools to query the knowledge graph and retrieve or propose code snippets as needed.
      You can use the probable node name tool to get the code for a node by providing a partial file or function name.
  """
  