kamaleswar Mohanta commited on
Commit
f056e53
·
1 Parent(s): 006ec78

basic blog generation & code review added

Browse files
src/langgraphagenticai/graph/__pycache__/graph_builder.cpython-312.pyc CHANGED
Binary files a/src/langgraphagenticai/graph/__pycache__/graph_builder.cpython-312.pyc and b/src/langgraphagenticai/graph/__pycache__/graph_builder.cpython-312.pyc differ
 
src/langgraphagenticai/graph/graph_builder.py CHANGED
@@ -5,6 +5,8 @@ from src.langgraphagenticai.state.state import State
5
  from src.langgraphagenticai.nodes.basic_chatbot_node import BasicChatbotNode
6
  from src.langgraphagenticai.nodes.chatbot_with_Tool_node import ChatbotWithToolNode
7
  from src.langgraphagenticai.tools.search_tool import get_tools, create_tool_nodes
 
 
8
 
9
  class GraphBuilder:
10
 
@@ -52,6 +54,41 @@ class GraphBuilder:
52
  self.graph_builder.add_edge(START,"chatbot")
53
  self.graph_builder.add_conditional_edges("chatbot", tools_condition)
54
  self.graph_builder.add_edge("tools","chatbot")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  def setup_graph(self,usecase: str):
57
  """
@@ -61,4 +98,10 @@ class GraphBuilder:
61
  self.basic_chatbot_build_graph()
62
  elif usecase == "Chatbot with Tool":
63
  self.chatbot_with_tools_build_graph()
 
 
 
 
 
 
64
  return self.graph_builder.compile()
 
5
  from src.langgraphagenticai.nodes.basic_chatbot_node import BasicChatbotNode
6
  from src.langgraphagenticai.nodes.chatbot_with_Tool_node import ChatbotWithToolNode
7
  from src.langgraphagenticai.tools.search_tool import get_tools, create_tool_nodes
8
+ from src.langgraphagenticai.nodes.blog_generation_node import BlogGenerationNode
9
+ from src.langgraphagenticai.nodes.code_peer_review_node import CodeReviewerNode
10
 
11
  class GraphBuilder:
12
 
 
54
  self.graph_builder.add_edge(START,"chatbot")
55
  self.graph_builder.add_conditional_edges("chatbot", tools_condition)
56
  self.graph_builder.add_edge("tools","chatbot")
57
+ def blog_generation_build_graph(self):
58
+ """
59
+ Builds a blog generation graph.
60
+ Includes orchestrator, worker (llm_call), and synthesizer nodes.
61
+ """
62
+ blog_node = BlogGenerationNode(self.llm)
63
+
64
+ # Add nodes
65
+ self.graph_builder.add_node("orchestrator", blog_node.orchestrator)
66
+ self.graph_builder.add_node("llm_call", blog_node.llm_call)
67
+ self.graph_builder.add_node("synthesizer", blog_node.synthesizer)
68
+
69
+ # Define edges
70
+ self.graph_builder.add_edge(START, "orchestrator")
71
+ self.graph_builder.add_conditional_edges(
72
+ "orchestrator",
73
+ blog_node.assign_workers,
74
+ {
75
+ "llm_call": "llm_call" # Maps to the worker node
76
+ }
77
+ )
78
+ self.graph_builder.add_edge("llm_call", "synthesizer")
79
+ self.graph_builder.add_edge("synthesizer", END)
80
+
81
+ def code_reviewer_build_graph(self):
82
+ """
83
+ Builds a code reviewer graph.
84
+ Includes a single node to review code and output feedback.
85
+ """
86
+ code_reviewer_node = CodeReviewerNode(self.llm)
87
+ self.graph_builder.add_node("reviewer", code_reviewer_node.review_code)
88
+ self.graph_builder.add_edge(START, "reviewer")
89
+ self.graph_builder.add_edge("reviewer", END)
90
+
91
+
92
 
93
  def setup_graph(self,usecase: str):
94
  """
 
98
  self.basic_chatbot_build_graph()
99
  elif usecase == "Chatbot with Tool":
100
  self.chatbot_with_tools_build_graph()
101
+ elif usecase == "Blog Generation":
102
+ self.blog_generation_build_graph()
103
+ elif usecase == "Coding Peer Review":
104
+ self.code_reviewer_build_graph()
105
+ else:
106
+ raise ValueError(f"Unknown use case: {usecase}")
107
  return self.graph_builder.compile()
src/langgraphagenticai/nodes/__pycache__/blog_generation_node.cpython-312.pyc ADDED
Binary file (3.54 kB). View file
 
src/langgraphagenticai/nodes/__pycache__/code_peer_review_node.cpython-312.pyc ADDED
Binary file (1.36 kB). View file
 
src/langgraphagenticai/nodes/blog_generation_node.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # blog_generation_node.py
2
+ from src.langgraphagenticai.state.state import State, WorkerState, Section
3
+ from pydantic import BaseModel, Field
4
+ from typing import List
5
+ from langgraph.constants import Send
6
+ from langchain_core.messages import HumanMessage, SystemMessage
7
+
8
+ class Sections(BaseModel):
9
+ sections: List[Section] = Field(description="Sections of the report.")
10
+
11
+ class BlogGenerationNode:
12
+ def __init__(self, model):
13
+ # Planner uses structured output for sections
14
+ self.planner = model.with_structured_output(Sections)
15
+ # LLM for content generation does not use structured output
16
+ self.llm = model # Raw LLM for generating text
17
+
18
+ def orchestrator(self, state: State) -> dict:
19
+ """Orchestrator that generates a plan for the report"""
20
+ report_sections = self.planner.invoke(
21
+ [
22
+ SystemMessage(content="Generate a plan for the report."),
23
+ HumanMessage(content=f"Here is the report topic: {state['topic']}"),
24
+ ]
25
+ )
26
+ print("Report Sections:", report_sections)
27
+ return {"sections": report_sections.sections}
28
+
29
+ def llm_call(self, state: WorkerState) -> dict:
30
+ """Worker writes a section of the report"""
31
+ section_content = self.llm.invoke(
32
+ [
33
+ SystemMessage(
34
+ content="Write a report section following the provided name and description. Include no preamble for each section. Use markdown formatting."
35
+ ),
36
+ HumanMessage(
37
+ content=f"Here is the section name: {state['section'].name} and description: {state['section'].description}"
38
+ ),
39
+ ]
40
+ )
41
+ # Ensure we get the content as a string
42
+ content = section_content.content if hasattr(section_content, "content") else str(section_content)
43
+ return {"completed_sections": [content]}
44
+
45
+ def synthesizer(self, state: State) -> dict:
46
+ """Synthesize full report from sections"""
47
+ completed_sections = state["completed_sections"]
48
+ completed_report_sections = "\n\n---\n\n".join(completed_sections)
49
+ return {"final_report": completed_report_sections}
50
+
51
+ def assign_workers(self, state: State) -> List[Send]:
52
+ """Assign a worker to each section in the plan"""
53
+ return [Send("llm_call", {"section": s}) for s in state["sections"]]
src/langgraphagenticai/nodes/code_peer_review_node.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # code_reviewer_node.py
2
+ from src.langgraphagenticai.state.state import State
3
+ from langchain_core.messages import HumanMessage, SystemMessage
4
+
5
+ class CodeReviewerNode:
6
+ def __init__(self, model):
7
+ self.llm = model
8
+
9
+ def review_code(self, state: State) -> dict:
10
+ """Review the provided code and return feedback"""
11
+ code = state["code_input"]
12
+ review = self.llm.invoke(
13
+ [
14
+ SystemMessage(content="Review the following code and provide feedback in markdown format."),
15
+ HumanMessage(content=code),
16
+ ]
17
+ )
18
+ return {
19
+ "messages": [SystemMessage(content="Code review completed")],
20
+ "review_output": review.content
21
+ }
src/langgraphagenticai/state/__pycache__/state.cpython-312.pyc CHANGED
Binary files a/src/langgraphagenticai/state/__pycache__/state.cpython-312.pyc and b/src/langgraphagenticai/state/__pycache__/state.cpython-312.pyc differ
 
src/langgraphagenticai/state/state.py CHANGED
@@ -1,10 +1,45 @@
1
- from typing import Annotated, Literal, Optional, List
 
 
 
 
 
 
 
 
 
 
 
 
2
  from typing_extensions import TypedDict
3
  from langgraph.graph.message import add_messages
4
- from langchain_core.messages import HumanMessage, AIMessage
 
5
 
6
- class State(TypedDict):
 
 
 
 
 
 
7
  """
8
- Represents the structure of the state used in the graph.
 
 
 
 
9
  """
10
- messages: Annotated[list,add_messages]
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # from typing import Annotated, Literal, Optional, List
2
+ # from typing_extensions import TypedDict
3
+ # from langgraph.graph.message import add_messages
4
+ # from langchain_core.messages import HumanMessage, AIMessage
5
+
6
+ # class State(TypedDict):
7
+ # """
8
+ # Represents the structure of the state used in the graph.
9
+ # """
10
+ # messages: Annotated[list,add_messages]
11
+
12
+ # state.py
13
+ from typing import Annotated, List, Optional
14
  from typing_extensions import TypedDict
15
  from langgraph.graph.message import add_messages
16
+ import operator
17
+ from pydantic import BaseModel, Field
18
 
19
+ # Schema for Blog Generation sections
20
+ class Section(BaseModel):
21
+ name: str = Field(description="Name for this section of the report.")
22
+ description: str = Field(description="Brief overview of the main topics and concepts to be covered in this section.")
23
+
24
+ # Unified State for all use cases
25
+ class State(TypedDict, total=False): # total=False makes all fields optional
26
  """
27
+ Represents the structure of the state used in the graph for multiple use cases:
28
+ - Chat Bot: messages
29
+ - Bot with Tool: messages, tool_output
30
+ - Blog Generation: messages, topic, sections, completed_sections, final_report
31
+ - Code Reviewer: messages, code_input, review_output
32
  """
33
+ messages: Annotated[List, add_messages] # Common to all: Chat history
34
+ topic: str # Blog Generation: Report topic
35
+ sections: List[Section] # Blog Generation: List of report sections
36
+ completed_sections: Annotated[List[str], operator.add] # Blog Generation: Completed sections
37
+ final_report: str # Blog Generation: Final report
38
+ tool_output: str # Bot with Tool: Output from tool execution
39
+ code_input: str # Code Reviewer: Input code to review
40
+ review_output: str # Code Reviewer: Review results
41
+
42
+ # Worker State for Blog Generation
43
+ class WorkerState(TypedDict):
44
+ section: Section
45
+ completed_sections: Annotated[List[str], operator.add]
src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-312.pyc CHANGED
Binary files a/src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-312.pyc and b/src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-312.pyc differ
 
src/langgraphagenticai/ui/streamlitui/display_result.py CHANGED
@@ -37,4 +37,36 @@ class DisplayResultStreamlit:
37
  st.write("Tool Call End")
38
  elif type(message)==AIMessage and message.content:
39
  with st.chat_message("assistant"):
40
- st.write(message.content)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  st.write("Tool Call End")
38
  elif type(message)==AIMessage and message.content:
39
  with st.chat_message("assistant"):
40
+ st.write(message.content)
41
+ elif usecase == "Blog Generation":
42
+ # Prepare state and invoke the graph for blog generation
43
+ initial_state = {
44
+ "messages": [HumanMessage(content=user_message)],
45
+ "topic": user_message, # Assume user_message is the topic
46
+ "sections": [],
47
+ "completed_sections": [],
48
+ "final_report": ""
49
+ }
50
+ res = graph.invoke(initial_state)
51
+ with st.chat_message("user"):
52
+ st.write(f"Blog topic: {user_message}")
53
+ with st.chat_message("assistant"):
54
+ st.markdown("### Generated Blog")
55
+ st.markdown(res["final_report"]) # Display the final report in markdown
56
+
57
+ elif usecase == "Coding Peer Review":
58
+ # Prepare state and invoke the graph for code review
59
+ initial_state = {
60
+ "messages": [HumanMessage(content="Review this code")],
61
+ "code_input": user_message, # Assume user_message is the code
62
+ "review_output": ""
63
+ }
64
+ res = graph.invoke(initial_state)
65
+ with st.chat_message("user"):
66
+ st.code(user_message, language="python") # Display code in a code block
67
+ with st.chat_message("assistant"):
68
+ st.markdown("### Code Review Feedback")
69
+ st.markdown(res["review_output"]) # Display review in markdown
70
+
71
+ else:
72
+ st.error(f"Unknown use case: {usecase}")
src/langgraphagenticai/ui/uiconfigfile.ini CHANGED
@@ -1,5 +1,5 @@
1
  [DEFAULT]
2
- PAGE_TITLE = LangGraph: Build Stateful Agentic AI graph
3
  LLM_OPTIONS = Groq
4
- USECASE_OPTIONS = Basic Chatbot, Chatbot with Tool
5
  GROQ_MODEL_OPTIONS = mixtral-8x7b-32768, llama3-8b-8192, llama3-70b-8192, gemma-7b-i, gemma2-9b-it, qwen2.5-32b, qwen-2.5-coder-32b
 
1
  [DEFAULT]
2
+ PAGE_TITLE = Dynamic Multi-Agent Workflows with LangGraph: Scalable, Modular, and Intelligent
3
  LLM_OPTIONS = Groq
4
+ USECASE_OPTIONS = Basic Chatbot, Chatbot with Tool, Blog Generation, Coding Peer Review
5
  GROQ_MODEL_OPTIONS = mixtral-8x7b-32768, llama3-8b-8192, llama3-70b-8192, gemma-7b-i, gemma2-9b-it, qwen2.5-32b, qwen-2.5-coder-32b