File size: 18,106 Bytes
c04c236
 
 
 
 
 
9df681f
 
 
 
 
 
 
 
 
 
 
c04c236
 
 
 
 
 
 
 
 
 
 
 
9df681f
 
 
 
ce96cc1
 
 
 
 
 
 
 
4f14e84
ce96cc1
fcb6eb2
ce96cc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08c5adc
c04c236
fb1d69b
ce96cc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08c5adc
 
c04c236
 
ce96cc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08c5adc
fb1d69b
ce96cc1
 
 
 
 
 
 
 
 
 
08c5adc
fb1d69b
ce96cc1
 
 
 
 
 
 
 
 
08c5adc
c04c236
 
9df681f
c04c236
 
 
 
 
9df681f
 
c04c236
 
 
 
 
 
9df681f
c04c236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9df681f
c04c236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9df681f
c04c236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9df681f
c04c236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef909d9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c04c236
 
 
 
 
ef909d9
c04c236
 
 
9df681f
c04c236
 
 
9df681f
c04c236
 
 
 
 
9df681f
 
c04c236
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated, List
import operator
from langgraph.checkpoint.sqlite import SqliteSaver
from langchain_core.messages import AnyMessage, SystemMessage, HumanMessage, AIMessage, ChatMessage
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.pydantic_v1 import BaseModel
import  os
import gradio as gr
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
from langgraph.checkpoint.sqlite import SqliteSaver
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAI
from langchain_core.pydantic_v1 import BaseModel
from tavily import TavilyClient

memory = SqliteSaver.from_conn_string(":memory:")

class AgentState(TypedDict):
    task: str
    plan: str
    draft: str
    critique: str
    content: List[str]
    revision_number: int
    max_revisions: int

from langchain_openai import ChatOpenAI
try:
    model = ChatGoogleGenerativeAI(model="gemini-1.5-pro-latest", google_api_key="AIzaSyD8EQItv3a2p9PNpdgf4nK7vLStWuzwAcg", convert_system_message_to_human=True, temperature=0.6)
except Exception as e:
    print("Error",e)
PLAN_PROMPT = """You are an experienced writer tasked with drafting a highly detailed and comprehensive outline for a research report. Your goal is to create an exceptionally structured outline for the user's chosen topic, ensuring it encourages an in-depth examination of recent trends, specific advancements, technical details, and future research directions.
**Outline Requirements:**
1. **Executive Summary:**
   - Summarize key findings, significance, and implications.
   - Highlight main conclusions and recommendations.
2. **Introduction:**
   - Provide background on the topic.
   - State research questions or hypotheses.
   - Define the  scope and objectives of the report.
3. **Recent Trends and Advancements:**
    -give resposne according to users topic
4. **Integration of Technologies:**
   - Discuss how these technologies intersect and enhance each other.
   - Provide examples of synergistic effects and combined applications.
   - Address integration challenges and potential solutions.
5. **Privacy and Security Challenges:**
   - Identify key privacy and security issues.
   - Discuss mitigation strategies and best practices.
   - Explore ethical considerations related to these technologies.
6. **Case Studies:**
   - Include detailed case studies with specific examples.
   - Analyze real-world applications and their outcomes.
   - Discuss lessons learned and best practices from each case study.
7. **Future Research Directions:**
   - Propose areas for further investigation and development.
   - Highlight emerging trends and technologies.
   - Discuss potential impact and applications of future research.
8. **Conclusions:**
   - Summarize main findings and insights.
   - Reflect on the implications for researchers and practitioners.
   - Provide actionable recommendations and future outlook.
9. **References:**
   - Include a comprehensive list of recent research papers, articles, and other relevant sources.
   - Ensure accurate and complete citations to support the analysis.
**Additional Instructions:**
- Break down complex topics into clear sub-sections.
- Ensure each section transitions smoothly to the next.
- Use visual aids where applicable (e.g., charts, graphs, tables).
- Address privacy and security systematically throughout the report.
"""


WRITER_PROMPT = """You are an essay assistant specializing in research reports. Produce a comprehensive research report based on the provided outline and user's requirements. Your report should cover recent trends, specific advancements, technical details, and future research directions in depth.
**Report Requirements:**
1. **Executive Summary:**
   - Summarize key findings, significance, and implications.
   - Ensure clarity and brevity while covering essential points.
2. **Introduction:**
   - Provide detailed background and context.
   - State and elaborate on research questions or hypotheses.
3. **Recent Trends and Advancements:**
   - Present detailed and up-to-date information on each technology.
   - Use concrete examples and recent data to support your analysis.
4. **Integration of Technologies:**
   - Discuss how technologies intersect and enhance each other.
   - Include specific examples of successful integration and its benefits.
5. **Privacy and Security Challenges:**
   - Thoroughly address potential privacy and security issues.
   - Provide a balanced view of potential solutions and ongoing research.
6. **Case Studies:**
   - Include detailed, well-researched case studies.
   - Provide concrete examples and analyze outcomes and lessons learned.
7. **Future Research Directions:**
   - Propose and justify areas for further investigation.
   - Discuss potential future applications and their significance.
8. **Conclusions:**
   - Summarize key insights and recommendations clearly.
   - Ensure the conclusions reflect the report’s findings and implications.
9. **References:**
   - Accurately cite recent research papers and relevant sources.
   - Ensure all references are credible and support the report’s content.
**Additional Instructions:**
- Maintain a clear and logical flow throughout the report.
- Use visual aids to present data effectively.
- Ensure smooth transitions between sections for readability.
- Provide a critical analysis of various perspectives.
{content}
"""


REFLECTION_PROMPT = """You are a seasoned educator evaluating an essay submission. Provide constructive feedback on the user's research report, focusing on depth, comprehensiveness, and clarity.
**Evaluation Criteria:**
1. **Coverage of Recent Trends and Advancements:**
   - Assess how well the report addresses recent trends and specific advancements.
   - Check for detailed and accurate information on each technology.
2. **Integration and Synergies:**
   - Evaluate how effectively the report discusses the integration of technologies and their synergies.
   - Look for examples and explanations of how these technologies enhance each other.
3. **Privacy and Security Challenges:**
   - Assess the depth of discussion on privacy and security challenges.
   - Evaluate the effectiveness of proposed solutions and mitigation strategies.
4. **Case Studies and Real-World Applications:**
   - Review the inclusion and analysis of case studies.
   - Check for relevance, detail, and real-world applicability of examples.
5. **Future Research Directions:**
   - Evaluate the clarity and feasibility of proposed future research directions.
   - Assess the potential impact and significance of these directions.
6. **References and Citations:**
   - Ensure that the report includes accurate and comprehensive citations.
   - Review the relevance and credibility of referenced sources.
**Recommendations:**
- Provide specific suggestions for improving depth and clarity.
- Highlight any gaps or areas needing further development.
- Suggest ways to enhance readability and logical flow.
"""

RESEARCH_PLAN_PROMPT = """As a researcher, your task is to generate effective search queries to gather comprehensive information for the upcoming research report. Provide up to 4 targeted queries to obtain the most relevant and recent data.
**Search Queries:**
1. **Latest Developments in [Technology]:** Focus on recent advancements and breakthroughs in the technology related to your report.
2. **Technical Details and Innovations:** Seek detailed technical information and innovations for the technology in question.
3. **Case Studies and Real-World Applications:** Find concrete examples and case studies that demonstrate the application of the technology.
4. **Integration and Privacy/Security Challenges:** Explore how different technologies integrate, their potential synergies, and address privacy/security challenges.
**Instructions:**
- Use credible sources and evaluate the relevance of the information.
- Ensure queries are specific to the technology and research focus.
- Gather information that supports a thorough and comprehensive analysis.
"""

RESEARCH_CRITIQUE_PROMPT = """You are tasked with gathering updated information to assist in revising the research report. Generate up to 3 focused search queries to find the most relevant and recent data.
**Search Queries:**
1. **Recent Trends in [Technology]:** Identify the latest trends and advancements in the technology relevant to the report.
2. **Detailed Technical Insights:** Obtain detailed technical information and recent innovations for a thorough understanding.
3. **Privacy and Security Challenges:** Find updated discussions on privacy and security challenges related to integrating the technologies.
**Instructions:**
- Ensure the queries target high-quality and credible sources.
- Focus on obtaining comprehensive and relevant data.
- Evaluate the information for its relevance and contribution to the report.
"""




class Queries(BaseModel):
    queries: List[str]



client = TavilyClient(api_key="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")
def plan_node(state: AgentState):
    print("reached planner node")
    messages = [
        SystemMessage(content=PLAN_PROMPT),
        HumanMessage(content=state['task'])
    ]

    response = model.invoke(messages)

    return {"plan": response.content}

def research_plan_node(state: AgentState):
    print("reached research_plan_node")

    # Send messages to the model without structured output
    messages = [
        SystemMessage(content=RESEARCH_PLAN_PROMPT),
        HumanMessage(content=state['task'])
    ]

    try:
        response = model.invoke(messages)

        # Extract the text content from the response
        response_text = response.content if hasattr(response, 'content') else str(response)

        # Parse the queries from the text content
        queries_list = parse_queries_from_content(response_text)
        print("parsed queries list", queries_list)

        # Perform search based on extracted queries
        content = state['content'] or []
        for q in queries_list:
            response = client.search(query=q, max_results=2)
            for r in response['results']:
                content.append(r['content'])

        return {"content": content}

    except Exception as e:
        print(f"An error occurred: {e}")
        return {"content": state['content']}

def parse_queries_from_content(content: str):
    # Split the content by newlines
    lines = content.split('\n')

    # Filter out empty lines and extract queries
    queries = [line.strip() for line in lines if line.strip()]

    # Remove numbering and quotes if needed
    queries = [q.split('. ', 1)[-1].strip('"') for q in queries]

    return queries
def generation_node(state: AgentState):
    print("reached generation_node")
    content = "\n\n".join(state['content'] or [])
    user_message = HumanMessage(
        content=f"{state['task']}\n\nHere is my plan:\n\n{state['plan']}")
    messages = [
        SystemMessage(
            content=WRITER_PROMPT.format(content=content)
        ),
        user_message
        ]
    response = model.invoke(messages)
    return {
        "draft": response.content,
        "revision_number": state.get("revision_number", 1) + 1
    }
def reflection_node(state: AgentState):
    print("reached reflection_node")
    messages = [
        SystemMessage(content=REFLECTION_PROMPT),
        HumanMessage(content=state['draft'])
    ]
    response = model.invoke(messages)
    return {"critique": response.content}

def research_critique_node(state: AgentState):
    print("reached research_critique_node")

    # Send messages to the model without structured output
    messages = [
        SystemMessage(content=RESEARCH_CRITIQUE_PROMPT),
        HumanMessage(content=state['critique'])
    ]
    print("passed 1")

    try:
        response = model.invoke(messages)
        print("passed 2")

        # Extract content from the response
        response_content = response.content if hasattr(response, 'content') else str(response)
        print("queries are", response_content)

        # Parse queries from the response content
        queries_list = parse_queries_from_text(response_content)
        print("queries_list", queries_list)

        # Perform search based on extracted queries
        content = state['content'] or []
        for q in queries_list:
            response = client.search(query=q, max_results=2)
            for r in response['results']:
                content.append(r['content'])

        return {"content": content}

    except Exception as e:
        print(f"An error occurred: {e}")
        return {"content": state['content']}

def parse_queries_from_text(text):
    print(text)
    # Assuming the queries are separated by new lines and potentially prefixed by numbers or bullet points
    lines = text.split('\n')

    # Clean up and filter out empty lines
    queries = [line.strip() for line in lines if line.strip()]

    # If needed, remove numbering or bullet points
    queries = [q.split('. ', 1)[-1].strip('"') for q in queries]

    return queries

def should_continue(state):
    if state["revision_number"] > state["max_revisions"]:
        return END
    return "reflect"

builder = StateGraph(AgentState)

builder.add_node("planner", plan_node)
builder.add_node("generate", generation_node)
builder.add_node("reflect", reflection_node)
builder.add_node("research_plan", research_plan_node)
builder.add_node("research_critique", research_critique_node)

builder.set_entry_point("planner")


builder.add_conditional_edges(
    "generate",
    should_continue,
    {END: END, "reflect": "reflect"}
)

builder.add_edge("planner", "research_plan")
builder.add_edge("research_plan", "generate")
builder.add_edge("reflect", "research_critique")
builder.add_edge("research_critique", "generate")


graph = builder.compile(checkpointer=memory)



# (Include all the existing code for AgentState, prompts, and node functions here)

# ... (keep all the existing code up to the graph compilation)

graph = builder.compile(checkpointer=memory)

def process_essay(task, max_revisions):
    thread = {"configurable": {"thread_id": "1"}}
    results = []
    for s in graph.stream({
        'task': task,
        "max_revisions": max_revisions,
        "revision_number": 1,
    }, thread):
        results.append(s)
    return results

def extract_agent_outputs(results):
    plan_output = ""
    research_output = ""
    generation_output = ""
    reflection_output = ""
    final_essay = ""

    for step in results:
        if 'planner' in step:
            plan_output += f"Plan:\n{step['planner']['plan']}\n\n"
        if 'research_plan' in step or 'research_critique' in step:
            research_key = 'research_plan' if 'research_plan' in step else 'research_critique'
            research_output += f"Research Queries:\n{step[research_key]['content']}\n\n"
        if 'generate' in step:
            generation_output += f"Draft (Revision {step['generate']['revision_number']}):\n{step['generate']['draft']}\n\n"
            final_essay = step['generate']['draft']  # Update final essay
        if 'reflect' in step:
            reflection_output += f"Critique:\n{step['reflect']['critique']}\n\n"

    return plan_output, research_output, generation_output, reflection_output, final_essay

graph = builder.compile(checkpointer=SqliteSaver.from_conn_string(":memory:"))

# Define functions for Gradio
def process_essay(task, max_revisions):
    thread = {"configurable": {"thread_id": "1"}}
    results = []
    for s in graph.stream({
        'task': task,
        "max_revisions": max_revisions,
        "revision_number": 1,
    }, thread):
        results.append(s)
    return results

def extract_agent_outputs(results):
    plan_output = ""
    research_output = ""
    generation_output = ""
    reflection_output = ""
    final_essay = ""

    for step in results:
        print("Processing step:", step)  # Debug line
        if 'planner' in step:
            plan_output += f"Plan:\n{step['planner']['plan']}\n\n"
        if 'research_plan' in step or 'research_critique' in step:
            research_key = 'research_plan' if 'research_plan' in step else 'research_critique'
            if step[research_key]:
                research_output += f"Research Queries:\n{step[research_key]['content']}\n\n"
            else:
                research_output += f"Research Queries:\nNo content found.\n\n"
        if 'generate' in step:
            generation_output += f"Draft (Revision {step['generate']['revision_number']}):\n{step['generate']['draft']}\n\n"
            final_essay = step['generate']['draft']  # Update final essay
        if 'reflect' in step:
            if step['reflect']:
                reflection_output += f"Critique:\n{step['reflect']['critique']}\n\n"
            else:
                reflection_output += f"Critique:\nNo critique found.\n\n"

    return plan_output, research_output, generation_output, reflection_output, final_essay

def gradio_interface(task, max_revisions):
    results = process_essay(task, max_revisions)
    plan, research, generation, reflection, final_essay = extract_agent_outputs(results)
    return final_essay, plan, research, generation, reflection

# Create and launch Gradio interface
iface = gr.Interface(
    fn=gradio_interface,
    inputs=[
        gr.Textbox(label="Report Topic", placeholder="Enter the report  topic or task here"),
        gr.Slider(minimum=1, maximum=5, step=1, label="Max Revisions", value=2)
    ],
    outputs=[
        gr.Textbox(label="Final Report"),
        gr.Textbox(label="Planning Output", lines=10),
        gr.Textbox(label="Research Output", lines=10),
        gr.Textbox(label="Generation Output", lines=10),
        gr.Textbox(label="Reflection Output", lines=10)
    ],
    title="Multi-Agent Report  Writing System",
    description="This system uses multiple AI agents to plan, research, write, and revise an research report  on the given topic."
)

iface.launch()