Spaces:
Paused
Paused
angry-meow
commited on
Commit
·
1cbf254
1
Parent(s):
a57d32e
start of some start of agents work
Browse files- agents.py +50 -0
- constants.py +12 -7
- graph.py +0 -0
- helper_functions.py +72 -1
- set_constants.py +0 -17
- tools.py +45 -0
agents.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from helper_functions import create_team_agent
|
2 |
+
import models
|
3 |
+
|
4 |
+
search_agent = create_team_agent(
|
5 |
+
models.gpt4o,
|
6 |
+
[tavily_tool],
|
7 |
+
"You are a research assistant who can search for up-to-date info using the tavily search engine.",
|
8 |
+
"Search",
|
9 |
+
["Search", "PaperInformationRetriever"]
|
10 |
+
)
|
11 |
+
|
12 |
+
research_agent = create_team_agent(
|
13 |
+
models.gpt4o,
|
14 |
+
[retrieve_information],
|
15 |
+
"You are a research assistant who can provide specific information on the provided paper: 'murthy-loneliness.pdf'. You must only respond with information about the paper related to the request.",
|
16 |
+
"PaperInformationRetriever",
|
17 |
+
["Search", "PaperInformationRetriever"]
|
18 |
+
)
|
19 |
+
|
20 |
+
doc_writer_agent = create_team_agent(
|
21 |
+
models.gpt4o,
|
22 |
+
[write_document, edit_document, read_document],
|
23 |
+
"You are an expert writing technical social media posts.",
|
24 |
+
"DocWriter",
|
25 |
+
["DocWriter", "NoteTaker", "CopyEditor", "VoiceEditor"]
|
26 |
+
)
|
27 |
+
|
28 |
+
note_taking_agent = create_team_agent(
|
29 |
+
models.gpt4o,
|
30 |
+
[create_outline, read_document],
|
31 |
+
"You are an expert senior researcher tasked with writing a social media post outline and taking notes to craft a social media post.",
|
32 |
+
"NoteTaker",
|
33 |
+
["DocWriter", "NoteTaker", "CopyEditor", "VoiceEditor"]
|
34 |
+
)
|
35 |
+
|
36 |
+
copy_editor_agent = create_team_agent(
|
37 |
+
models.gpt4o,
|
38 |
+
[write_document, edit_document, read_document],
|
39 |
+
"You are an expert copy editor who focuses on fixing grammar, spelling, and tone issues.",
|
40 |
+
"CopyEditor",
|
41 |
+
["DocWriter", "NoteTaker", "CopyEditor", "VoiceEditor"]
|
42 |
+
)
|
43 |
+
|
44 |
+
voice_editor_agent = create_team_agent(
|
45 |
+
models.gpt4o,
|
46 |
+
[write_document, edit_document, read_document],
|
47 |
+
"You are an expert in crafting and refining the voice and tone of social media posts. You edit the document to ensure it has a consistent, professional, and engaging voice appropriate for social media platforms.",
|
48 |
+
"VoiceEditor",
|
49 |
+
["DocWriter", "NoteTaker", "CopyEditor", "VoiceEditor"]
|
50 |
+
)
|
constants.py
CHANGED
@@ -1,7 +1,12 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from dotenv import load_dotenv, find_dotenv
|
3 |
+
|
4 |
+
load_dotenv(find_dotenv())
|
5 |
+
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
|
6 |
+
ANTRHOPIC_API_KEY = os.environ.get("ANTRHOPIC_API_KEY")
|
7 |
+
LANGCHAIN_API_KEY = os.environ.get("LANGCHAIN_API_KEY")
|
8 |
+
LANGCHAIN_TRACING_V2=True
|
9 |
+
LANGCHAIN_ENDPOINT='https://api.smith.langchain.com'
|
10 |
+
QDRANT_API_KEY = os.environ.get("QDRANT_API_KEY")
|
11 |
+
QDRANT_ENDPOINT = os.environ.get("QDRANT_ENDPOINT")
|
12 |
+
TAVILY_API_KEY = os.environ.get("TAVILY_API_KEY")
|
graph.py
ADDED
File without changes
|
helper_functions.py
CHANGED
@@ -1,6 +1,12 @@
|
|
|
|
1 |
from langchain_community.document_loaders import PyMuPDFLoader, TextLoader, WebBaseLoader
|
|
|
2 |
from langchain_community.vectorstores import Qdrant
|
|
|
|
|
|
|
3 |
import os
|
|
|
4 |
|
5 |
def process_file(file_or_url):
|
6 |
if isinstance(file_or_url, str) and file_or_url.startswith(('http://', 'https://')):
|
@@ -33,4 +39,69 @@ def add_to_qdrant(documents, embeddings, qdrant_client, collection_name):
|
|
33 |
url=qdrant_client.url,
|
34 |
prefer_grpc=True,
|
35 |
collection_name=collection_name,
|
36 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import List
|
2 |
from langchain_community.document_loaders import PyMuPDFLoader, TextLoader, WebBaseLoader
|
3 |
+
from langchain.agents import AgentExecutor, create_openai_functions_agent
|
4 |
from langchain_community.vectorstores import Qdrant
|
5 |
+
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
|
6 |
+
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
7 |
+
from langchain_core.language_models import BaseLanguageModel
|
8 |
import os
|
9 |
+
import functools
|
10 |
|
11 |
def process_file(file_or_url):
|
12 |
if isinstance(file_or_url, str) and file_or_url.startswith(('http://', 'https://')):
|
|
|
39 |
url=qdrant_client.url,
|
40 |
prefer_grpc=True,
|
41 |
collection_name=collection_name,
|
42 |
+
)
|
43 |
+
|
44 |
+
def agent_node(state, agent, name):
|
45 |
+
result = agent.invoke(state)
|
46 |
+
return {"messages": [HumanMessage(content=result["output"], name=name)]}
|
47 |
+
|
48 |
+
def create_team_agent(llm, tools, system_prompt, agent_name, team_members):
|
49 |
+
return create_agent(
|
50 |
+
llm,
|
51 |
+
tools,
|
52 |
+
f"{system_prompt}\nBelow are files currently in your directory:\n{{current_files}}",
|
53 |
+
team_members
|
54 |
+
)
|
55 |
+
|
56 |
+
def create_agent_node(agent, name):
|
57 |
+
return functools.partial(agent_node, agent=agent, name=name)
|
58 |
+
|
59 |
+
def add_agent_to_graph(graph, agent_name, agent_node):
|
60 |
+
graph.add_node(agent_name, agent_node)
|
61 |
+
graph.add_edge(agent_name, "supervisor")
|
62 |
+
|
63 |
+
def create_team_supervisor(llm, team_description, team_members):
|
64 |
+
return create_team_supervisor(
|
65 |
+
llm,
|
66 |
+
f"You are a supervisor tasked with managing a conversation between the"
|
67 |
+
f" following workers: {', '.join(team_members)}. {team_description}"
|
68 |
+
f" When all workers are finished, you must respond with FINISH.",
|
69 |
+
team_members
|
70 |
+
)
|
71 |
+
|
72 |
+
def enter_chain(message: str, members: List[str]):
|
73 |
+
results = {
|
74 |
+
"messages": [HumanMessage(content=message)],
|
75 |
+
"team_members": ", ".join(members),
|
76 |
+
}
|
77 |
+
return results
|
78 |
+
|
79 |
+
def create_team_chain(graph, team_members):
|
80 |
+
return (
|
81 |
+
functools.partial(enter_chain, members=team_members)
|
82 |
+
| graph.compile()
|
83 |
+
)
|
84 |
+
|
85 |
+
def create_agent(
|
86 |
+
llm: BaseLanguageModel,
|
87 |
+
tools: list,
|
88 |
+
system_prompt: str,
|
89 |
+
) -> str:
|
90 |
+
"""Create a function-calling agent and add it to the graph."""
|
91 |
+
system_prompt += ("\nWork autonomously according to your specialty, using the tools available to you."
|
92 |
+
" Do not ask for clarification."
|
93 |
+
" Your other team members (and other teams) will collaborate with you with their own specialties."
|
94 |
+
" You are chosen for a reason! You are one of the following team members: {{team_members}}.")
|
95 |
+
prompt = ChatPromptTemplate.from_messages(
|
96 |
+
[
|
97 |
+
(
|
98 |
+
"system",
|
99 |
+
system_prompt,
|
100 |
+
),
|
101 |
+
MessagesPlaceholder(variable_name="messages"),
|
102 |
+
MessagesPlaceholder(variable_name="agent_scratchpad"),
|
103 |
+
]
|
104 |
+
)
|
105 |
+
agent = create_openai_functions_agent(llm, tools, prompt)
|
106 |
+
executor = AgentExecutor(agent=agent, tools=tools)
|
107 |
+
return executor
|
set_constants.py
DELETED
@@ -1,17 +0,0 @@
|
|
1 |
-
import constants
|
2 |
-
import os
|
3 |
-
from dotenv import load_dotenv, find_dotenv
|
4 |
-
|
5 |
-
load_dotenv(find_dotenv())
|
6 |
-
|
7 |
-
current_directory = os.path.dirname(os.path.abspath(__file__))
|
8 |
-
file_path = os.path.join(current_directory, 'constants.py')
|
9 |
-
constantsFile = open(file_path, "w")
|
10 |
-
constantsFile.write("OPENAI_API_KEY='" + os.getenv("OPENAI_API_KEY") + "';\n");
|
11 |
-
constantsFile.write("ANTRHOPIC_API_KEY='" + os.getenv("ANTRHOPIC_API_KEY") + "';\n");
|
12 |
-
constantsFile.write("LANGCHAIN_API_KEY='" + os.getenv("LANGCHAIN_API_KEY") + "';\n");
|
13 |
-
constantsFile.write("LANGCHAIN_TRACING_V2=True;\n");
|
14 |
-
constantsFile.write("LANGCHAIN_ENDPOINT='https://api.smith.langchain.com';\n");
|
15 |
-
constantsFile.write("QDRANT_API_KEY='" + os.getenv("QDRANT_API_KEY") + "';\n");
|
16 |
-
constantsFile.write("QDRANT_ENDPOINT='" + os.getenv("QDRANT_ENDPOINT") + "';\n");
|
17 |
-
constantsFile.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tools.py
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langchain_community.tools.tavily_search import TavilySearchResults
|
2 |
+
from langchain_core.tools import tool
|
3 |
+
|
4 |
+
tavily_tool = TavilySearchResults(max_results=5)
|
5 |
+
|
6 |
+
@tool
|
7 |
+
def create_outline(points: List[str], file_name: str) -> str:
|
8 |
+
"""Create and save an outline."""
|
9 |
+
with (WORKING_DIRECTORY / file_name).open("w") as file:
|
10 |
+
for i, point in enumerate(points):
|
11 |
+
file.write(f"{i + 1}. {point}\n")
|
12 |
+
return f"Outline saved to {file_name}"
|
13 |
+
|
14 |
+
@tool
|
15 |
+
def read_document(file_name: str, start: Optional[int] = None, end: Optional[int] = None) -> str:
|
16 |
+
"""Read the specified document."""
|
17 |
+
with (WORKING_DIRECTORY / file_name).open("r") as file:
|
18 |
+
lines = file.readlines()
|
19 |
+
if start is not None:
|
20 |
+
start = 0
|
21 |
+
return "\n".join(lines[start:end])
|
22 |
+
|
23 |
+
@tool
|
24 |
+
def write_document(content: str, file_name: str) -> str:
|
25 |
+
"""Create and save a text document."""
|
26 |
+
with (WORKING_DIRECTORY / file_name).open("w") as file:
|
27 |
+
file.write(content)
|
28 |
+
return f"Document saved to {file_name}"
|
29 |
+
|
30 |
+
@tool
|
31 |
+
def edit_document(file_name: str, inserts: Dict[int, str] = {}) -> str:
|
32 |
+
"""Edit a document by inserting text at specific line numbers."""
|
33 |
+
with (WORKING_DIRECTORY / file_name).open("r") as file:
|
34 |
+
lines = file.readlines()
|
35 |
+
|
36 |
+
sorted_inserts = sorted(inserts.items())
|
37 |
+
for line_number, text in sorted_inserts:
|
38 |
+
if 1 <= line_number <= len(lines) + 1:
|
39 |
+
lines.insert(line_number - 1, text + "\n")
|
40 |
+
else:
|
41 |
+
return f"Error: Line number {line_number} is out of range."
|
42 |
+
|
43 |
+
with (WORKING_DIRECTORY / file_name).open("w") as file:
|
44 |
+
file.writelines(lines)
|
45 |
+
return f"Document edited and saved to {file_name}"
|