├── README.md
├── app.py
├── crewai
├── __init__.py
├── agent.py
├── agents
│ ├── __init__.py
│ ├── cache
│ │ ├── __init__.py
│ │ ├── cache_handler.py
│ │ └── cache_hit.py
│ ├── exceptions.py
│ ├── executor.py
│ ├── output_parser.py
│ └── tools_handler.py
├── crew.py
├── process.py
├── task.py
├── tasks
│ ├── __init__.py
│ └── task_output.py
├── tools
│ ├── __init__.py
│ ├── agent_tools.py
│ ├── cache_tools.py
│ ├── gemini_tools.py
│ └── phi2_tools.py
├── translations
│ ├── el.json
│ └── en.json
└── utilities
│ ├── __init__.py
│ ├── i18n.py
│ ├── logger.py
│ ├── prompts.py
│ └── rpm_controller.py
├── data
├── fraud.json
├── fraud2.json
├── insurance_data.json
├── insurance_fraud_ring.json
├── marvel.json
└── neo4jdata.json
├── images
├── CaseManager.png
├── ClaimsProcessor.png
├── InsuranceActor.png
├── LeadActor.png
├── LeadLawyer.png
├── LegalAdvisor.png
└── SupportingActor.png
└── requirements.txt
/README.md:
--------------------------------------------------------------------------------
1 | # Phi2Hackathon
2 | Leveraging revolutionary Agent and Phi-2 technology, Graph Detective uncovers concealed linkages and discerns patterns, enabling pinpoint fraud detection and prevention across insurance, banking, and eCommerce with unparalleled efficiency.
3 |
4 | # Description
5 |
6 | Graph Detective harnesses the power of state-of-the-art Agent and Phi-2 technology to redefine fraud detection and prevention in the insurance, banking, and eCommerce sectors. By unveiling hidden connections and identifying patterns, it offers an unrivaled solution that combines Generative AI Agents with Phi-2's speed and precision, enabling investigators to tackle fraud with unparalleled efficiency and accuracy.
7 |
8 | This groundbreaking app not only simplifies data analysis by allowing direct interaction with the Generative AI Agent, bypassing the need for complex coding or manual analysis, but also stands out for its ability to deliver consistent results without the common pitfalls of data hallucination, requiring minimal tuning.
9 |
10 | With fraud impacting the financial sectors to the tune of $308 billion annually in the United States alone, Graph Detective is poised to revolutionize the industry by offering an unmatched efficiency improvement over traditional methods, ensuring it remains at the forefront of meeting the evolving needs of fraud detection and prevention professionals.
11 |
12 | What sets our app apart is its unique integration of Phi-2 and Generative AI Agents, providing a solution that not only quickly identifies fraud patterns but is also easy to implement within Agent frameworks (such as CrewAI and LangGraph), making it a game-changer in the fight against sophisticated fraud schemes.
13 |
14 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 |
3 | import os
4 |
5 | from SPARQLWrapper import SPARQLWrapper, JSON
6 | from streamlit_agraph import agraph, TripleStore, Node, Edge, Config
7 | from layout import footer
8 | import json
9 |
10 | import google.generativeai as genai
11 |
12 | # Tool import
13 | from crewai.tools.gemini_tools import GeminiSearchTools
14 |
15 | from crewai.tools.phi2_tools import Phi2SearchTools
16 |
17 | # Google Langchain
18 | from langchain_google_genai import GoogleGenerativeAI
19 |
20 | # Crew imports
21 | from crewai import Agent, Task, Crew, Process
22 |
23 | # Retrieve API Key from Environment Variable
24 | GOOGLE_AI_STUDIO = os.environ.get('GOOGLE_API_KEY')
25 |
26 | # Ensure the API key is available
27 | if not GOOGLE_AI_STUDIO:
28 | st.error("API key not found. Please set the GOOGLE_AI_STUDIO environment variable.")
29 | else:
30 | # Set gemini_llm
31 | gemini_llm = GoogleGenerativeAI(model="gemini-pro", google_api_key=GOOGLE_AI_STUDIO)
32 |
33 | # Base Example with Gemini Search
34 |
35 | TITLE1 = """
Phi-2 Geneation
"""
36 |
37 |
38 |
39 |
40 | # CrewAI Code Start ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
41 |
42 | def crewai_process(research_topic):
43 | # Define your agents with roles and goals
44 | Sam = Agent(
45 | role='Data Analyst specializing in network structures and graph theory.',
46 | goal="""To uncover hidden structures and patterns within complex networks and to detect connection
47 | patterns that might indicate fraudulent activities.""",
48 | backstory=""" Sam has a background in computer science with a focus on data analysis.
49 | Having worked in cybersecurity, Sam developed a keen eye for detecting anomalies in network traffic,
50 | which translates well into analyzing complex graphs for irregular and overly connected patterns.""",
51 | verbose=True,
52 | allow_delegation=True,
53 | llm = gemini_llm,
54 | tools=[
55 | Phi2SearchTools.phi2_search
56 | ]
57 |
58 | )
59 |
60 | Donna = Agent(
61 | role='Behavioral Analyst with expertise in pattern recognition in data.',
62 | goal="""To detect atypical behavior patterns that might indicate fraudulent activities.""",
63 | backstory="""Donna's background in behavioral science and her experience in financial fraud detection have equipped
64 | her with a unique perspective on spotting unusual patterns in data. She excels in interpreting complex behaviors
65 | and identifying deviations from the norm. """,
66 | verbose=True,
67 | llm = gemini_llm,
68 | tools=[
69 | GeminiSearchTools.gemini_search
70 | ]
71 |
72 | )
73 |
74 | Henry = Agent(
75 | role='Graph Visualization Specialist.',
76 | goal="""To create clear, comprehensible visual representations of complex data, particularly focusing on fraudulent networks. """,
77 | backstory="""YHenry has a background in graphic design and computer science. He found his niche in data visualization,
78 | where he combines his artistic skills with technical knowledge to make complex data easily understandable.
79 | Over the years, Henry has specialized in visualizing criminal networks, using his skills to aid law enforcement
80 | and fraud detection teams. """,
81 | verbose=True,
82 | allow_delegation=True,
83 | llm = gemini_llm,
84 | tools=[
85 | GeminiSearchTools.gemini_search
86 | ]
87 |
88 | )
89 |
90 |
91 |
92 | # Create tasks for your agents
93 | task1 = Task(
94 | description=f""" Sam will focus on the structural analysis of the network {research_topic}.
95 | This includes: Identifying nodes or groups of nodes with unusually high numbers of connections.
96 | Look for connections of multiple parties among same accidents that could indicate a fraud ring.
97 | use ROLE and NAME to do your analysis. Analyzing the network for the formation of densely connected
98 | subgraphs or communities. OUTPUT RESULT, GIVE DETAILS OF THE NODES AND CONNECTION THAT MAY BE FRAUD
99 | Use Phi2_search to analyze the graph.
100 | """,
101 | agent=Sam
102 | )
103 |
104 | task2 = Task(
105 | description="""Donna cleans up Sam's work ensuring that the cases presented are valid""",
106 | agent=Donna
107 | )
108 |
109 | task3 = Task(
110 | description="""
111 | Henry's task is to take the fraudulent nodes identified by Sam and Donna and construct a detailed visual graph.
112 | This graph should highlight the relationships and interactions within the fraud ring. His output should be a JSON
113 | structure with the following characteristics:
114 | DON'T EXPLAIN WHAT TO DO, OUTPUT THE RESULTS IN THE FOLLOWING GRAPH FORMAT EXAMPLE:
115 |
116 | {
117 | "name": "Claims Center",
118 | "img": "https://www.svgrepo.com/show/448123/scope-expense-claims-read.svg",
119 | "children": [
120 | {
121 | "name": "Accident 1",
122 | "children": [
123 | {
124 | "role": "Driver 1",
125 | "name": "Person 1",
126 | "link": "http://accidentnetwork.chart/person_1",
127 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
128 | "size": 50000
129 | },
130 | {
131 | "role": "Witness 2",
132 | "name": "Person 2",
133 | "link": "http://accidentnetwork.chart/person_2",
134 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
135 | "size": 45000
136 | },
137 | {
138 | "role": "Lawyer 4",
139 | "name": "Person 4",
140 | "link": "http://accidentnetwork.chart/person_4",
141 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
142 | "size": 40000
143 | }
144 | ]
145 | },
146 | {
147 | "name": "Accident 2",
148 | "children": [
149 | {
150 | "role": "Passenger 3",
151 | "name": "Person 3",
152 | "link": "http://accidentnetwork.chart/person_3",
153 | "img": "https://www.svgrepo.com/show/340795/passenger-plus.svg",
154 | "size": 50000
155 | },
156 | {
157 | "role": "Driver 5",
158 | "name": "Person 5",
159 | "link": "http://accidentnetwork.chart/person_5",
160 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
161 | "size": 45000
162 | },
163 | {
164 | "role": "Adjuster 6",
165 | "name": "Person 6",
166 | "link": "http://accidentnetwork.chart/person_6",
167 | "img": "https://www.svgrepo.com/show/223812/insurance-user.svg",
168 | "size": 40000
169 | },
170 |
171 | {
172 | "role": "Lawyer 4",
173 | "name": "Person 4",
174 | "link": "http://accidentnetwork.chart/person_4",
175 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
176 | "size": 40000
177 | }
178 |
179 | ]
180 | }
181 |
182 | ]
183 | }
184 |
185 |
186 | """,
187 | agent=Henry
188 | )
189 |
190 |
191 |
192 | # Instantiate your crew with a sequential process
193 | crew = Crew(
194 | agents=[Sam],
195 | tasks=[task1],
196 | process=Process.sequential
197 | )
198 |
199 | # Get your crew to , work!
200 | result = crew.kickoff()
201 |
202 | return result
203 |
204 |
205 |
206 |
207 | # CrewAI Code End ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
208 |
209 |
210 |
211 |
212 |
213 | # Data Start ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
214 |
215 |
216 | # Data End ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
217 |
218 | if 'fraud_topic' not in st.session_state:
219 | st.session_state['fraud_topic'] = ''
220 |
221 | # Strealit Agraph Start +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
222 |
223 | def get_inspired():
224 | sparql = SPARQLWrapper("http://dbpedia.org/sparql")
225 |
226 | query_string = """
227 | SELECT ?name_pe1_en ?rel_en ?name_pe2_en
228 | WHERE {
229 | {
230 | SELECT ?name_p1 ?rel ?name_p2
231 | WHERE {
232 | ?p1 a foaf:Person .
233 | ?p1 dbo:influencedBy ?p2 .
234 | ?p2 a foaf:Person .
235 | ?p1 foaf:name ?name_p1 .
236 | ?p2 foaf:name ?name_p2 .
237 | dbo:influencedBy rdfs:label ?rel .
238 | }
239 | LIMIT 100
240 | }
241 | UNION
242 | {
243 | SELECT ?name_p1 ?rel ?name_p2
244 | WHERE {
245 | ?p1 a foaf:Person .
246 | ?p1 dbo:influenced ?p2 .
247 | ?p2 a foaf:Person .
248 | ?p1 foaf:name ?name_p1 .
249 | ?p2 foaf:name ?name_p2 .
250 | dbo:influenced rdfs:label ?rel .
251 | }
252 | LIMIT 100
253 | }
254 | FILTER ( LANG(?name_p1) = "en" && LANG(?rel) = "en" && LANG(?name_p2) = "en" )
255 | BIND ( STR(?name_p1) AS ?name_pe1_en )
256 | BIND ( STR(?rel) AS ?rel_en )
257 | BIND ( STR(?name_p2) AS ?name_pe2_en )
258 | }
259 | """
260 |
261 | sparql.setQuery(query_string)
262 | sparql.setReturnFormat(JSON)
263 | results = sparql.query().convert()
264 | store = TripleStore()
265 | for result in results["results"]["bindings"]:
266 | node1 = result["name_pe1_en"]["value"]
267 | link = result["rel_en"]["value"]
268 | node2 = result["name_pe2_en"]["value"]
269 | store.add_triple(node1, link, node2)
270 | return store
271 |
272 | def app():
273 | query_type = st.sidebar.selectbox("Fraud Investigation Tpye: ", ["Insurance", "Neo4j" ]) # could add more stuff here later on or add other endpoints in the sidebar.
274 | config = Config(height=600, width=700, nodeHighlightBehavior=True, highlightColor="#F7A7A6", directed=True,
275 | collapsible=True)
276 |
277 | if query_type=="Insurance":
278 |
279 | st.title("Insurance Fraud Graph")
280 | #based on Insurance Fraud
281 | with open("data/fraud.json", encoding="utf8") as f:
282 | fraud_file = json.loads(f.read())
283 | st.session_state['fraud_topic'] = fraud_file
284 | fraud_store = TripleStore()
285 | for sub_graph in fraud_file["children"]:
286 | fraud_store.add_triple(fraud_file["name"], "has_subgroup", sub_graph["name"], picture=fraud_file["img"])
287 | for node in sub_graph["children"]:
288 | node1 = node["role"]
289 | link = "blongs_to"
290 | node2 = sub_graph["name"]
291 | pic = node["img"]
292 | fraud_store.add_triple(node1, link, node2, picture=pic)
293 | agraph(list(fraud_store.getNodes()), (fraud_store.getEdges()), config)
294 |
295 |
296 | if query_type=="Neo4j":
297 | st.title("Neo4j Fraud Ring")
298 |
299 | with open("data/neo4jdata.json", encoding="utf8") as f:
300 | fraud_file = json.loads(f.read())
301 | st.session_state['fraud_topic'] = fraud_file
302 | fraud_store = TripleStore()
303 | for sub_graph in fraud_file["children"]:
304 | fraud_store.add_triple(fraud_file["name"], "has_subgroup", sub_graph["name"], picture=fraud_file["img"])
305 | for node in sub_graph["children"]:
306 | node1 = node["role"]
307 | link = "blongs_to"
308 | node2 = sub_graph["name"]
309 | pic = node["img"]
310 | fraud_store.add_triple(node1, link, node2, picture=pic)
311 | agraph(list(fraud_store.getNodes()), (fraud_store.getEdges()), config)
312 |
313 |
314 |
315 | if query_type=="eCommerce":
316 | st.title("eCommerce Fraud Graph")
317 | #based on http://marvel-force-chart.surge.sh/
318 | with open("data/fraud.json", encoding="utf8") as f:
319 | fraud_file = json.loads(f.read())
320 | st.session_state['fraud_topic'] = fraud_file
321 | fraud_store = TripleStore()
322 | for sub_graph in fraud_file["children"]:
323 | fraud_store.add_triple(fraud_file["name"], "has_subgroup", sub_graph["name"], picture=fraud_file["img"])
324 | for node in sub_graph["children"]:
325 | node1 = node["role"]
326 | link = "blongs_to"
327 | node2 = sub_graph["name"]
328 | pic = node["img"]
329 | fraud_store.add_triple(node1, link, node2, picture=pic)
330 | agraph(list(fraud_store.getNodes()), (fraud_store.getEdges()), config)
331 |
332 |
333 | # Strealit Agraph END +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
334 |
335 |
336 | # Streamlit Crew Input Start ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
337 |
338 | # input_topic = st.text_area("What Exciting Adventures Await Us", height=100, placeholder="Start Our Story...")
339 |
340 | # st.session_state['on_topic'] = input_topic
341 | # Button to run the process
342 |
343 |
344 | st.title("Fraud Graph")
345 |
346 | if st.button("Search for Fraud"):
347 | # Run the crewai process
348 | with st.spinner('Generating Content...'):
349 | # result = crewai_process(input_topic)
350 | result = crewai_process(st.session_state['fraud_topic'])
351 | # Display the result
352 | st.text_area("Output", value=result , height=300)
353 |
354 |
355 |
356 | # Streamlit Crew Input End ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
357 |
358 | if __name__ == '__main__':
359 | app()
360 |
361 |
362 |
363 |
--------------------------------------------------------------------------------
/crewai/__init__.py:
--------------------------------------------------------------------------------
1 | from crewai.agent import Agent
2 | from crewai.crew import Crew
3 | from crewai.process import Process
4 | from crewai.task import Task
5 |
--------------------------------------------------------------------------------
/crewai/agent.py:
--------------------------------------------------------------------------------
1 | import uuid
2 | from typing import Any, List, Optional
3 |
4 | from langchain.agents.format_scratchpad import format_log_to_str
5 | from langchain.agents.agent import RunnableAgent
6 | from langchain.memory import ConversationSummaryMemory
7 | from langchain.tools.render import render_text_description
8 | from langchain_core.runnables.config import RunnableConfig
9 | from langchain_openai import ChatOpenAI
10 | from langchain_core.language_models import BaseLanguageModel
11 | from pydantic import (
12 | UUID4,
13 | BaseModel,
14 | ConfigDict,
15 | Field,
16 | InstanceOf,
17 | PrivateAttr,
18 | field_validator,
19 | model_validator,
20 | )
21 | from pydantic_core import PydanticCustomError
22 |
23 | from crewai.agents import (
24 | CacheHandler,
25 | CrewAgentExecutor,
26 | CrewAgentOutputParser,
27 | ToolsHandler,
28 | )
29 | from crewai.utilities import I18N, Logger, Prompts, RPMController
30 |
31 |
32 | class Agent(BaseModel):
33 | """Represents an agent in a system.
34 |
35 | Each agent has a role, a goal, a backstory, and an optional language model (llm).
36 | The agent can also have memory, can operate in verbose mode, and can delegate tasks to other agents.
37 |
38 | Attributes:
39 | agent_executor: An instance of the CrewAgentExecutor class.
40 | role: The role of the agent.
41 | goal: The objective of the agent.
42 | backstory: The backstory of the agent.
43 | llm: The language model that will run the agent.
44 | max_iter: Maximum number of iterations for an agent to execute a task.
45 | memory: Whether the agent should have memory or not.
46 | max_rpm: Maximum number of requests per minute for the agent execution to be respected.
47 | verbose: Whether the agent execution should be in verbose mode.
48 | allow_delegation: Whether the agent is allowed to delegate tasks to other agents.
49 | tools: Tools at agents disposal
50 | """
51 |
52 | __hash__ = object.__hash__ # type: ignore
53 | _logger: Logger = PrivateAttr()
54 | _rpm_controller: RPMController = PrivateAttr(default=None)
55 | _request_within_rpm_limit: Any = PrivateAttr(default=None)
56 |
57 | model_config = ConfigDict(arbitrary_types_allowed=True)
58 | id: UUID4 = Field(
59 | default_factory=uuid.uuid4,
60 | frozen=True,
61 | description="Unique identifier for the object, not set by user.",
62 | )
63 | role: str = Field(description="Role of the agent")
64 | goal: str = Field(description="Objective of the agent")
65 | backstory: str = Field(description="Backstory of the agent")
66 | max_rpm: Optional[int] = Field(
67 | default=None,
68 | description="Maximum number of requests per minute for the agent execution to be respected.",
69 | )
70 | memory: bool = Field(
71 | default=True, description="Whether the agent should have memory or not"
72 | )
73 | verbose: bool = Field(
74 | default=False, description="Verbose mode for the Agent Execution"
75 | )
76 | allow_delegation: bool = Field(
77 | default=True, description="Allow delegation of tasks to agents"
78 | )
79 | tools: List[Any] = Field(
80 | default_factory=list, description="Tools at agents disposal"
81 | )
82 | max_iter: Optional[int] = Field(
83 | default=15, description="Maximum iterations for an agent to execute a task"
84 | )
85 | agent_executor: InstanceOf[CrewAgentExecutor] = Field(
86 | default=None, description="An instance of the CrewAgentExecutor class."
87 | )
88 | tools_handler: InstanceOf[ToolsHandler] = Field(
89 | default=None, description="An instance of the ToolsHandler class."
90 | )
91 | cache_handler: InstanceOf[CacheHandler] = Field(
92 | default=CacheHandler(), description="An instance of the CacheHandler class."
93 | )
94 | i18n: I18N = Field(default=I18N(), description="Internationalization settings.")
95 | llm: Any = Field(
96 | default_factory=lambda: ChatOpenAI(
97 | model="gpt-4",
98 | ),
99 | description="Language model that will run the agent.",
100 | )
101 |
102 | @field_validator("id", mode="before")
103 | @classmethod
104 | def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
105 | if v:
106 | raise PydanticCustomError(
107 | "may_not_set_field", "This field is not to be set by the user.", {}
108 | )
109 |
110 | @model_validator(mode="after")
111 | def set_private_attrs(self):
112 | """Set private attributes."""
113 | self._logger = Logger(self.verbose)
114 | if self.max_rpm and not self._rpm_controller:
115 | self._rpm_controller = RPMController(
116 | max_rpm=self.max_rpm, logger=self._logger
117 | )
118 | return self
119 |
120 | @model_validator(mode="after")
121 | def check_agent_executor(self) -> "Agent":
122 | """Check if the agent executor is set."""
123 | if not self.agent_executor:
124 | self.set_cache_handler(self.cache_handler)
125 | return self
126 |
127 | def execute_task(
128 | self,
129 | task: str,
130 | context: Optional[str] = None,
131 | tools: Optional[List[Any]] = None,
132 | ) -> str:
133 | """Execute a task with the agent.
134 |
135 | Args:
136 | task: Task to execute.
137 | context: Context to execute the task in.
138 | tools: Tools to use for the task.
139 |
140 | Returns:
141 | Output of the agent
142 | """
143 |
144 | if context:
145 | task = self.i18n.slice("task_with_context").format(
146 | task=task, context=context
147 | )
148 |
149 | tools = tools or self.tools
150 | self.agent_executor.tools = tools
151 |
152 | result = self.agent_executor.invoke(
153 | {
154 | "input": task,
155 | "tool_names": self.__tools_names(tools),
156 | "tools": render_text_description(tools),
157 | },
158 | RunnableConfig(callbacks=[self.tools_handler]),
159 | )["output"]
160 |
161 | if self.max_rpm:
162 | self._rpm_controller.stop_rpm_counter()
163 |
164 | return result
165 |
166 | def set_cache_handler(self, cache_handler: CacheHandler) -> None:
167 | """Set the cache handler for the agent.
168 |
169 | Args:
170 | cache_handler: An instance of the CacheHandler class.
171 | """
172 | self.cache_handler = cache_handler
173 | self.tools_handler = ToolsHandler(cache=self.cache_handler)
174 | self.__create_agent_executor()
175 |
176 | def set_rpm_controller(self, rpm_controller: RPMController) -> None:
177 | """Set the rpm controller for the agent.
178 |
179 | Args:
180 | rpm_controller: An instance of the RPMController class.
181 | """
182 | if not self._rpm_controller:
183 | self._rpm_controller = rpm_controller
184 | self.__create_agent_executor()
185 |
186 | def __create_agent_executor(self) -> None:
187 | """Create an agent executor for the agent.
188 |
189 | Returns:
190 | An instance of the CrewAgentExecutor class.
191 | """
192 | agent_args = {
193 | "input": lambda x: x["input"],
194 | "tools": lambda x: x["tools"],
195 | "tool_names": lambda x: x["tool_names"],
196 | "agent_scratchpad": lambda x: format_log_to_str(x["intermediate_steps"]),
197 | }
198 | executor_args = {
199 | "i18n": self.i18n,
200 | "tools": self.tools,
201 | "verbose": self.verbose,
202 | "handle_parsing_errors": True,
203 | "max_iterations": self.max_iter,
204 | }
205 |
206 | if self._rpm_controller:
207 | executor_args["request_within_rpm_limit"] = (
208 | self._rpm_controller.check_or_wait
209 | )
210 |
211 | if self.memory:
212 | summary_memory = ConversationSummaryMemory(
213 | llm=self.llm, input_key="input", memory_key="chat_history"
214 | )
215 | executor_args["memory"] = summary_memory
216 | agent_args["chat_history"] = lambda x: x["chat_history"]
217 | prompt = Prompts(i18n=self.i18n).task_execution_with_memory()
218 | else:
219 | prompt = Prompts(i18n=self.i18n).task_execution()
220 |
221 | execution_prompt = prompt.partial(
222 | goal=self.goal,
223 | role=self.role,
224 | backstory=self.backstory,
225 | )
226 |
227 | bind = self.llm.bind(stop=[self.i18n.slice("observation")])
228 | inner_agent = (
229 | agent_args
230 | | execution_prompt
231 | | bind
232 | | CrewAgentOutputParser(
233 | tools_handler=self.tools_handler,
234 | cache=self.cache_handler,
235 | i18n=self.i18n,
236 | )
237 | )
238 | self.agent_executor = CrewAgentExecutor(
239 | agent=RunnableAgent(runnable=inner_agent), **executor_args
240 | )
241 |
242 | @staticmethod
243 | def __tools_names(tools) -> str:
244 | return ", ".join([t.name for t in tools])
245 |
--------------------------------------------------------------------------------
/crewai/agents/__init__.py:
--------------------------------------------------------------------------------
1 | from .cache.cache_handler import CacheHandler
2 | from .executor import CrewAgentExecutor
3 | from .output_parser import CrewAgentOutputParser
4 | from .tools_handler import ToolsHandler
5 |
--------------------------------------------------------------------------------
/crewai/agents/cache/__init__.py:
--------------------------------------------------------------------------------
1 | from .cache_handler import CacheHandler
2 | from .cache_hit import CacheHit
3 |
--------------------------------------------------------------------------------
/crewai/agents/cache/cache_handler.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 |
4 | class CacheHandler:
5 | """Callback handler for tool usage."""
6 |
7 | _cache: dict = {}
8 |
9 | def __init__(self):
10 | self._cache = {}
11 |
12 | def add(self, tool, input, output):
13 | input = input.strip()
14 | self._cache[f"{tool}-{input}"] = output
15 |
16 | def read(self, tool, input) -> Optional[str]:
17 | input = input.strip()
18 | return self._cache.get(f"{tool}-{input}")
19 |
--------------------------------------------------------------------------------
/crewai/agents/cache/cache_hit.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | from pydantic import BaseModel, Field
4 |
5 | from .cache_handler import CacheHandler
6 |
7 |
8 | class CacheHit(BaseModel):
9 | """Cache Hit Object."""
10 |
11 | class Config:
12 | arbitrary_types_allowed = True
13 |
14 | # Making it Any instead of AgentAction to avoind
15 | # pydantic v1 vs v2 incompatibility, langchain should
16 | # soon be updated to pydantic v2
17 | action: Any = Field(description="Action taken")
18 | cache: CacheHandler = Field(description="Cache Handler for the tool")
19 |
--------------------------------------------------------------------------------
/crewai/agents/exceptions.py:
--------------------------------------------------------------------------------
1 | from langchain_core.exceptions import OutputParserException
2 |
3 | from crewai.utilities import I18N
4 |
5 |
6 | class TaskRepeatedUsageException(OutputParserException):
7 | """Exception raised when a task is used twice in a roll."""
8 |
9 | i18n: I18N = I18N()
10 | error: str = "TaskRepeatedUsageException"
11 | message: str
12 |
13 | def __init__(self, i18n: I18N, tool: str, tool_input: str, text: str):
14 | self.i18n = i18n
15 | self.text = text
16 | self.tool = tool
17 | self.tool_input = tool_input
18 | self.message = self.i18n.errors("task_repeated_usage").format(
19 | tool=tool, tool_input=tool_input
20 | )
21 |
22 | super().__init__(
23 | error=self.error,
24 | observation=self.message,
25 | send_to_llm=True,
26 | llm_output=self.text,
27 | )
28 |
29 | def __str__(self):
30 | return self.message
31 |
--------------------------------------------------------------------------------
/crewai/agents/executor.py:
--------------------------------------------------------------------------------
1 | import time
2 | from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
3 |
4 | from langchain.agents import AgentExecutor
5 | from langchain.agents.agent import ExceptionTool
6 | from langchain.agents.tools import InvalidTool
7 | from langchain.callbacks.manager import CallbackManagerForChainRun
8 | from langchain_core.agents import AgentAction, AgentFinish, AgentStep
9 | from langchain_core.exceptions import OutputParserException
10 | from langchain_core.pydantic_v1 import root_validator
11 | from langchain_core.tools import BaseTool
12 | from langchain_core.utils.input import get_color_mapping
13 |
14 | from crewai.agents.cache.cache_hit import CacheHit
15 | from crewai.tools.cache_tools import CacheTools
16 | from crewai.utilities import I18N
17 |
18 |
19 | class CrewAgentExecutor(AgentExecutor):
20 | i18n: I18N = I18N()
21 | iterations: int = 0
22 | request_within_rpm_limit: Any = None
23 | max_iterations: Optional[int] = 15
24 | force_answer_max_iterations: Optional[int] = None
25 |
26 | @root_validator()
27 | def set_force_answer_max_iterations(cls, values: Dict) -> Dict:
28 | values["force_answer_max_iterations"] = values["max_iterations"] - 2
29 | return values
30 |
31 | def _should_force_answer(self) -> bool:
32 | return True if self.iterations == self.force_answer_max_iterations else False
33 |
34 | def _force_answer(self, output: AgentAction):
35 | return AgentStep(
36 | action=output, observation=self.i18n.errors("used_too_many_tools")
37 | )
38 |
39 | def _call(
40 | self,
41 | inputs: Dict[str, str],
42 | run_manager: Optional[CallbackManagerForChainRun] = None,
43 | ) -> Dict[str, Any]:
44 | """Run text through and get agent response."""
45 | # Construct a mapping of tool name to tool for easy lookup
46 | name_to_tool_map = {tool.name: tool for tool in self.tools}
47 | # We construct a mapping from each tool to a color, used for logging.
48 | color_mapping = get_color_mapping(
49 | [tool.name for tool in self.tools], excluded_colors=["green", "red"]
50 | )
51 | intermediate_steps: List[Tuple[AgentAction, str]] = []
52 | # Let's start tracking the number of iterations and time elapsed
53 | self.iterations = 0
54 | time_elapsed = 0.0
55 | start_time = time.time()
56 | # We now enter the agent loop (until it returns something).
57 | while self._should_continue(self.iterations, time_elapsed):
58 | if not self.request_within_rpm_limit or self.request_within_rpm_limit():
59 | next_step_output = self._take_next_step(
60 | name_to_tool_map,
61 | color_mapping,
62 | inputs,
63 | intermediate_steps,
64 | run_manager=run_manager,
65 | )
66 | if isinstance(next_step_output, AgentFinish):
67 | return self._return(
68 | next_step_output, intermediate_steps, run_manager=run_manager
69 | )
70 |
71 | intermediate_steps.extend(next_step_output)
72 | if len(next_step_output) == 1:
73 | next_step_action = next_step_output[0]
74 | # See if tool should return directly
75 | tool_return = self._get_tool_return(next_step_action)
76 | if tool_return is not None:
77 | return self._return(
78 | tool_return, intermediate_steps, run_manager=run_manager
79 | )
80 | self.iterations += 1
81 | time_elapsed = time.time() - start_time
82 | output = self.agent.return_stopped_response(
83 | self.early_stopping_method, intermediate_steps, **inputs
84 | )
85 | return self._return(output, intermediate_steps, run_manager=run_manager)
86 |
87 | def _iter_next_step(
88 | self,
89 | name_to_tool_map: Dict[str, BaseTool],
90 | color_mapping: Dict[str, str],
91 | inputs: Dict[str, str],
92 | intermediate_steps: List[Tuple[AgentAction, str]],
93 | run_manager: Optional[CallbackManagerForChainRun] = None,
94 | ) -> Iterator[Union[AgentFinish, AgentAction, AgentStep]]:
95 | """Take a single step in the thought-action-observation loop.
96 |
97 | Override this to take control of how the agent makes and acts on choices.
98 | """
99 | try:
100 | intermediate_steps = self._prepare_intermediate_steps(intermediate_steps)
101 |
102 | # Call the LLM to see what to do.
103 | output = self.agent.plan(
104 | intermediate_steps,
105 | callbacks=run_manager.get_child() if run_manager else None,
106 | **inputs,
107 | )
108 | if self._should_force_answer():
109 | if isinstance(output, AgentAction):
110 | output = output
111 | elif isinstance(output, CacheHit):
112 | output = output.action
113 | else:
114 | raise ValueError(
115 | f"Unexpected output type from agent: {type(output)}"
116 | )
117 | yield self._force_answer(output)
118 | return
119 |
120 | except OutputParserException as e:
121 | if isinstance(self.handle_parsing_errors, bool):
122 | raise_error = not self.handle_parsing_errors
123 | else:
124 | raise_error = False
125 | if raise_error:
126 | raise ValueError(
127 | "An output parsing error occurred. "
128 | "In order to pass this error back to the agent and have it try "
129 | "again, pass `handle_parsing_errors=True` to the AgentExecutor. "
130 | f"This is the error: {str(e)}"
131 | )
132 | text = str(e)
133 | if isinstance(self.handle_parsing_errors, bool):
134 | if e.send_to_llm:
135 | observation = str(e.observation)
136 | text = str(e.llm_output)
137 | else:
138 | observation = "Invalid or incomplete response"
139 | elif isinstance(self.handle_parsing_errors, str):
140 | observation = self.handle_parsing_errors
141 | elif callable(self.handle_parsing_errors):
142 | observation = self.handle_parsing_errors(e)
143 | else:
144 | raise ValueError("Got unexpected type of `handle_parsing_errors`")
145 | output = AgentAction("_Exception", observation, text)
146 | if run_manager:
147 | run_manager.on_agent_action(output, color="green")
148 | tool_run_kwargs = self.agent.tool_run_logging_kwargs()
149 | observation = ExceptionTool().run(
150 | output.tool_input,
151 | verbose=self.verbose,
152 | color=None,
153 | callbacks=run_manager.get_child() if run_manager else None,
154 | **tool_run_kwargs,
155 | )
156 |
157 | if self._should_force_answer():
158 | yield self._force_answer(output)
159 | return
160 |
161 | yield AgentStep(action=output, observation=observation)
162 | return
163 |
164 | # If the tool chosen is the finishing tool, then we end and return.
165 | if isinstance(output, AgentFinish):
166 | yield output
167 | return
168 |
169 | # Override tool usage to use CacheTools
170 | if isinstance(output, CacheHit):
171 | cache = output.cache
172 | action = output.action
173 | tool = CacheTools(cache_handler=cache).tool()
174 | output = action.copy()
175 | output.tool_input = f"tool:{action.tool}|input:{action.tool_input}"
176 | output.tool = tool.name
177 | name_to_tool_map[tool.name] = tool
178 | color_mapping[tool.name] = color_mapping[action.tool]
179 |
180 | actions: List[AgentAction]
181 | actions = [output] if isinstance(output, AgentAction) else output
182 | yield from actions
183 | for agent_action in actions:
184 | if run_manager:
185 | run_manager.on_agent_action(agent_action, color="green")
186 | # Otherwise we lookup the tool
187 | if agent_action.tool in name_to_tool_map:
188 | tool = name_to_tool_map[agent_action.tool]
189 | return_direct = tool.return_direct
190 | color = color_mapping[agent_action.tool]
191 | tool_run_kwargs = self.agent.tool_run_logging_kwargs()
192 | if return_direct:
193 | tool_run_kwargs["llm_prefix"] = ""
194 | # We then call the tool on the tool input to get an observation
195 | observation = tool.run(
196 | agent_action.tool_input,
197 | verbose=self.verbose,
198 | color=color,
199 | callbacks=run_manager.get_child() if run_manager else None,
200 | **tool_run_kwargs,
201 | )
202 | else:
203 | tool_run_kwargs = self.agent.tool_run_logging_kwargs()
204 | observation = InvalidTool().run(
205 | {
206 | "requested_tool_name": agent_action.tool,
207 | "available_tool_names": list(name_to_tool_map.keys()),
208 | },
209 | verbose=self.verbose,
210 | color=None,
211 | callbacks=run_manager.get_child() if run_manager else None,
212 | **tool_run_kwargs,
213 | )
214 | yield AgentStep(action=agent_action, observation=observation)
215 |
--------------------------------------------------------------------------------
/crewai/agents/output_parser.py:
--------------------------------------------------------------------------------
1 | import re
2 | from typing import Union
3 |
4 | from langchain.agents.output_parsers import ReActSingleInputOutputParser
5 | from langchain_core.agents import AgentAction, AgentFinish
6 |
7 | from crewai.agents.cache import CacheHandler, CacheHit
8 | from crewai.agents.exceptions import TaskRepeatedUsageException
9 | from crewai.agents.tools_handler import ToolsHandler
10 | from crewai.utilities import I18N
11 |
12 | FINAL_ANSWER_ACTION = "Final Answer:"
13 | FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE = (
14 | "Parsing LLM output produced both a final answer and a parse-able action:"
15 | )
16 |
17 |
18 | class CrewAgentOutputParser(ReActSingleInputOutputParser):
19 | """Parses ReAct-style LLM calls that have a single tool input.
20 |
21 | Expects output to be in one of two formats.
22 |
23 | If the output signals that an action should be taken,
24 | should be in the below format. This will result in an AgentAction
25 | being returned.
26 |
27 | ```
28 | Thought: agent thought here
29 | Action: search
30 | Action Input: what is the temperature in SF?
31 | ```
32 |
33 | If the output signals that a final answer should be given,
34 | should be in the below format. This will result in an AgentFinish
35 | being returned.
36 |
37 | ```
38 | Thought: agent thought here
39 | Final Answer: The temperature is 100 degrees
40 | ```
41 |
42 | It also prevents tools from being reused in a roll.
43 | """
44 |
45 | class Config:
46 | arbitrary_types_allowed = True
47 |
48 | tools_handler: ToolsHandler
49 | cache: CacheHandler
50 | i18n: I18N
51 |
52 | def parse(self, text: str) -> Union[AgentAction, AgentFinish, CacheHit]:
53 | regex = (
54 | r"Action\s*\d*\s*:[\s]*(.*?)[\s]*Action\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)"
55 | )
56 | if action_match := re.search(regex, text, re.DOTALL):
57 | action = action_match.group(1).strip()
58 | action_input = action_match.group(2)
59 | tool_input = action_input.strip(" ")
60 | tool_input = tool_input.strip('"')
61 |
62 | if last_tool_usage := self.tools_handler.last_used_tool:
63 | usage = {
64 | "tool": action,
65 | "input": tool_input,
66 | }
67 | if usage == last_tool_usage:
68 | raise TaskRepeatedUsageException(
69 | text=text,
70 | tool=action,
71 | tool_input=tool_input,
72 | i18n=self.i18n,
73 | )
74 |
75 | if self.cache.read(action, tool_input):
76 | action = AgentAction(action, tool_input, text)
77 | return CacheHit(action=action, cache=self.cache)
78 |
79 | return super().parse(text)
80 |
--------------------------------------------------------------------------------
/crewai/agents/tools_handler.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Dict
2 |
3 | from langchain.callbacks.base import BaseCallbackHandler
4 |
5 | from ..tools.cache_tools import CacheTools
6 | from .cache.cache_handler import CacheHandler
7 |
8 |
9 | class ToolsHandler(BaseCallbackHandler):
10 | """Callback handler for tool usage."""
11 |
12 | last_used_tool: Dict[str, Any] = {}
13 | cache: CacheHandler
14 |
15 | def __init__(self, cache: CacheHandler, **kwargs: Any):
16 | """Initialize the callback handler."""
17 | self.cache = cache
18 | super().__init__(**kwargs)
19 |
20 | def on_tool_start(
21 | self, serialized: Dict[str, Any], input_str: str, **kwargs: Any
22 | ) -> Any:
23 | """Run when tool starts running."""
24 | name = serialized.get("name")
25 | if name not in ["invalid_tool", "_Exception"]:
26 | tools_usage = {
27 | "tool": name,
28 | "input": input_str,
29 | }
30 | self.last_used_tool = tools_usage
31 |
32 | def on_tool_end(self, output: str, **kwargs: Any) -> Any:
33 | """Run when tool ends running."""
34 | if (
35 | "is not a valid tool" not in output
36 | and "Invalid or incomplete response" not in output
37 | and "Invalid Format" not in output
38 | ):
39 | if self.last_used_tool["tool"] != CacheTools().name:
40 | self.cache.add(
41 | tool=self.last_used_tool["tool"],
42 | input=self.last_used_tool["input"],
43 | output=output,
44 | )
45 |
--------------------------------------------------------------------------------
/crewai/crew.py:
--------------------------------------------------------------------------------
1 | import json
2 | import uuid
3 | from typing import Any, Dict, List, Optional, Union
4 |
5 | from pydantic import (
6 | UUID4,
7 | BaseModel,
8 | ConfigDict,
9 | Field,
10 | InstanceOf,
11 | Json,
12 | PrivateAttr,
13 | field_validator,
14 | model_validator,
15 | )
16 | from pydantic_core import PydanticCustomError
17 |
18 | from crewai.agent import Agent
19 | from crewai.agents.cache import CacheHandler
20 | from crewai.process import Process
21 | from crewai.task import Task
22 | from crewai.tools.agent_tools import AgentTools
23 | from crewai.utilities import I18N, Logger, RPMController
24 |
25 |
26 | class Crew(BaseModel):
27 | """
28 | Represents a group of agents, defining how they should collaborate and the tasks they should perform.
29 |
30 | Attributes:
31 | tasks: List of tasks assigned to the crew.
32 | agents: List of agents part of this crew.
33 | process: The process flow that the crew will follow (e.g., sequential).
34 | verbose: Indicates the verbosity level for logging during execution.
35 | config: Configuration settings for the crew.
36 | _cache_handler: Handles caching for the crew's operations.
37 | max_rpm: Maximum number of requests per minute for the crew execution to be respected.
38 | id: A unique identifier for the crew instance.
39 | """
40 |
41 | __hash__ = object.__hash__ # type: ignore
42 | _rpm_controller: RPMController = PrivateAttr()
43 | _logger: Logger = PrivateAttr()
44 | _cache_handler: InstanceOf[CacheHandler] = PrivateAttr(default=CacheHandler())
45 | model_config = ConfigDict(arbitrary_types_allowed=True)
46 | tasks: List[Task] = Field(default_factory=list)
47 | agents: List[Agent] = Field(default_factory=list)
48 | process: Process = Field(default=Process.sequential)
49 | verbose: Union[int, bool] = Field(default=0)
50 | config: Optional[Union[Json, Dict[str, Any]]] = Field(default=None)
51 | id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
52 | max_rpm: Optional[int] = Field(
53 | default=None,
54 | description="Maximum number of requests per minute for the crew execution to be respected.",
55 | )
56 | language: str = Field(
57 | default="en",
58 | description="Language used for the crew, defaults to English.",
59 | )
60 |
61 | @field_validator("id", mode="before")
62 | @classmethod
63 | def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
64 | """Prevent manual setting of the 'id' field by users."""
65 | if v:
66 | raise PydanticCustomError(
67 | "may_not_set_field", "The 'id' field cannot be set by the user.", {}
68 | )
69 |
70 | @field_validator("config", mode="before")
71 | @classmethod
72 | def check_config_type(
73 | cls, v: Union[Json, Dict[str, Any]]
74 | ) -> Union[Json, Dict[str, Any]]:
75 | """Validates that the config is a valid type.
76 | Args:
77 | v: The config to be validated.
78 | Returns:
79 | The config if it is valid.
80 | """
81 |
82 | # TODO: Improve typing
83 | return json.loads(v) if isinstance(v, Json) else v # type: ignore
84 |
85 | @model_validator(mode="after")
86 | def set_private_attrs(self) -> "Crew":
87 | """Set private attributes."""
88 | self._cache_handler = CacheHandler()
89 | self._logger = Logger(self.verbose)
90 | self._rpm_controller = RPMController(max_rpm=self.max_rpm, logger=self._logger)
91 | return self
92 |
93 | @model_validator(mode="after")
94 | def check_config(self):
95 | """Validates that the crew is properly configured with agents and tasks."""
96 | if not self.config and not self.tasks and not self.agents:
97 | raise PydanticCustomError(
98 | "missing_keys",
99 | "Either 'agents' and 'tasks' need to be set or 'config'.",
100 | {},
101 | )
102 |
103 | if self.config:
104 | self._setup_from_config()
105 |
106 | if self.agents:
107 | for agent in self.agents:
108 | agent.set_cache_handler(self._cache_handler)
109 | agent.set_rpm_controller(self._rpm_controller)
110 | return self
111 |
112 | def _setup_from_config(self):
113 | assert self.config is not None, "Config should not be None."
114 |
115 | """Initializes agents and tasks from the provided config."""
116 | if not self.config.get("agents") or not self.config.get("tasks"):
117 | raise PydanticCustomError(
118 | "missing_keys_in_config", "Config should have 'agents' and 'tasks'.", {}
119 | )
120 |
121 | self.agents = [Agent(**agent) for agent in self.config["agents"]]
122 | self.tasks = [self._create_task(task) for task in self.config["tasks"]]
123 |
124 | def _create_task(self, task_config: Dict[str, Any]) -> Task:
125 | """Creates a task instance from its configuration.
126 |
127 | Args:
128 | task_config: The configuration of the task.
129 |
130 | Returns:
131 | A task instance.
132 | """
133 | task_agent = next(
134 | agt for agt in self.agents if agt.role == task_config["agent"]
135 | )
136 | del task_config["agent"]
137 | return Task(**task_config, agent=task_agent)
138 |
139 | def kickoff(self) -> str:
140 | """Starts the crew to work on its assigned tasks."""
141 | for agent in self.agents:
142 | agent.i18n = I18N(language=self.language)
143 |
144 | if self.process == Process.sequential:
145 | return self._sequential_loop()
146 | else:
147 | raise NotImplementedError(
148 | f"The process '{self.process}' is not implemented yet."
149 | )
150 |
151 | def _sequential_loop(self) -> str:
152 | """Executes tasks sequentially and returns the final output."""
153 | task_output = ""
154 | for task in self.tasks:
155 | self._prepare_and_execute_task(task)
156 | task_output = task.execute(task_output)
157 |
158 | role = task.agent.role if task.agent is not None else "None"
159 | self._logger.log("debug", f"[{role}] Task output: {task_output}\n\n")
160 |
161 | if self.max_rpm:
162 | self._rpm_controller.stop_rpm_counter()
163 |
164 | return task_output
165 |
166 | def _prepare_and_execute_task(self, task: Task) -> None:
167 | """Prepares and logs information about the task being executed.
168 |
169 | Args:
170 | task: The task to be executed.
171 | """
172 | if task.agent is not None and task.agent.allow_delegation:
173 | task.tools += AgentTools(agents=self.agents).tools()
174 |
175 | role = task.agent.role if task.agent is not None else "None"
176 | self._logger.log("debug", f"Working Agent: {role}")
177 | self._logger.log("info", f"Starting Task: {task.description}")
178 |
--------------------------------------------------------------------------------
/crewai/process.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 |
3 |
4 | class Process(str, Enum):
5 | """
6 | Class representing the different processes that can be used to tackle tasks
7 | """
8 |
9 | sequential = "sequential"
10 | # TODO: consensual = 'consensual'
11 | # TODO: hierarchical = 'hierarchical'
12 |
--------------------------------------------------------------------------------
/crewai/task.py:
--------------------------------------------------------------------------------
1 | import uuid
2 | from typing import Any, List, Optional
3 |
4 | from pydantic import UUID4, BaseModel, Field, field_validator, model_validator
5 | from pydantic_core import PydanticCustomError
6 |
7 | from crewai.agent import Agent
8 | from crewai.tasks.task_output import TaskOutput
9 | from crewai.utilities import I18N
10 |
11 |
12 | class Task(BaseModel):
13 | """Class that represent a task to be executed."""
14 |
15 | __hash__ = object.__hash__ # type: ignore
16 | i18n: I18N = I18N()
17 | description: str = Field(description="Description of the actual task.")
18 | callback: Optional[Any] = Field(
19 | description="Callback to be executed after the task is completed.", default=None
20 | )
21 | agent: Optional[Agent] = Field(
22 | description="Agent responsible for executiong the task.", default=None
23 | )
24 | expected_output: Optional[str] = Field(
25 | description="Clear definition of expected output for the task.",
26 | default=None,
27 | )
28 | output: Optional[TaskOutput] = Field(
29 | description="Task output, it's final result after being executed", default=None
30 | )
31 | tools: List[Any] = Field(
32 | default_factory=list,
33 | description="Tools the agent is limited to use for this task.",
34 | )
35 | id: UUID4 = Field(
36 | default_factory=uuid.uuid4,
37 | frozen=True,
38 | description="Unique identifier for the object, not set by user.",
39 | )
40 |
41 | @field_validator("id", mode="before")
42 | @classmethod
43 | def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
44 | if v:
45 | raise PydanticCustomError(
46 | "may_not_set_field", "This field is not to be set by the user.", {}
47 | )
48 |
49 | @model_validator(mode="after")
50 | def check_tools(self):
51 | """Check if the tools are set."""
52 | if not self.tools and self.agent and self.agent.tools:
53 | self.tools.extend(self.agent.tools)
54 | return self
55 |
56 | def execute(self, context: Optional[str] = None) -> str:
57 | """Execute the task.
58 |
59 | Returns:
60 | Output of the task.
61 | """
62 | if not self.agent:
63 | raise Exception(
64 | f"The task '{self.description}' has no agent assigned, therefore it can't be executed directly and should be executed in a Crew using a specific process that support that, either consensual or hierarchical."
65 | )
66 |
67 | result = self.agent.execute_task(
68 | task=self._prompt(), context=context, tools=self.tools
69 | )
70 |
71 | self.output = TaskOutput(description=self.description, result=result)
72 | self.callback(self.output) if self.callback else None
73 | return result
74 |
75 | def _prompt(self) -> str:
76 | """Prompt the task.
77 |
78 | Returns:
79 | Prompt of the task.
80 | """
81 | tasks_slices = [self.description]
82 |
83 | if self.expected_output:
84 | output = self.i18n.slice("expected_output").format(
85 | expected_output=self.expected_output
86 | )
87 | tasks_slices = [self.description, output]
88 | return "\n".join(tasks_slices)
89 |
--------------------------------------------------------------------------------
/crewai/tasks/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qaillc/Phi2Hackathon/66b0ad3e17fc4a525dae2d40dda999fe03a00c04/crewai/tasks/__init__.py
--------------------------------------------------------------------------------
/crewai/tasks/task_output.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | from pydantic import BaseModel, Field, model_validator
4 |
5 |
6 | class TaskOutput(BaseModel):
7 | """Class that represents the result of a task."""
8 |
9 | description: str = Field(description="Description of the task")
10 | summary: Optional[str] = Field(description="Summary of the task", default=None)
11 | result: str = Field(description="Result of the task")
12 |
13 | @model_validator(mode="after")
14 | def set_summary(self):
15 | excerpt = " ".join(self.description.split(" ")[:10])
16 | self.summary = f"{excerpt}..."
17 | return self
18 |
--------------------------------------------------------------------------------
/crewai/tools/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qaillc/Phi2Hackathon/66b0ad3e17fc4a525dae2d40dda999fe03a00c04/crewai/tools/__init__.py
--------------------------------------------------------------------------------
/crewai/tools/agent_tools.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 |
3 | from langchain.tools import Tool
4 | from pydantic import BaseModel, Field
5 |
6 | from crewai.agent import Agent
7 | from crewai.utilities import I18N
8 |
9 |
10 | class AgentTools(BaseModel):
11 | """Default tools around agent delegation"""
12 |
13 | agents: List[Agent] = Field(description="List of agents in this crew.")
14 | i18n: I18N = Field(default=I18N(), description="Internationalization settings.")
15 |
16 | def tools(self):
17 | return [
18 | Tool.from_function(
19 | func=self.delegate_work,
20 | name="Delegate work to co-worker",
21 | description=self.i18n.tools("delegate_work").format(
22 | coworkers=", ".join([agent.role for agent in self.agents])
23 | ),
24 | ),
25 | Tool.from_function(
26 | func=self.ask_question,
27 | name="Ask question to co-worker",
28 | description=self.i18n.tools("ask_question").format(
29 | coworkers=", ".join([agent.role for agent in self.agents])
30 | ),
31 | ),
32 | ]
33 |
34 | def delegate_work(self, command):
35 | """Useful to delegate a specific task to a coworker."""
36 | return self.__execute(command)
37 |
38 | def ask_question(self, command):
39 | """Useful to ask a question, opinion or take from a coworker."""
40 | return self.__execute(command)
41 |
42 | def __execute(self, command):
43 | """Execute the command."""
44 | try:
45 | agent, task, context = command.split("|")
46 | except ValueError:
47 | return self.i18n.errors("agent_tool_missing_param")
48 |
49 | if not agent or not task or not context:
50 | return self.i18n.errors("agent_tool_missing_param")
51 |
52 | agent = [
53 | available_agent
54 | for available_agent in self.agents
55 | if available_agent.role == agent
56 | ]
57 |
58 | if not agent:
59 | return self.i18n.errors("agent_tool_unexsiting_coworker").format(
60 | coworkers=", ".join([agent.role for agent in self.agents])
61 | )
62 |
63 | agent = agent[0]
64 | return agent.execute_task(task, context)
65 |
--------------------------------------------------------------------------------
/crewai/tools/cache_tools.py:
--------------------------------------------------------------------------------
1 | from langchain.tools import Tool
2 | from pydantic import BaseModel, ConfigDict, Field
3 |
4 | from crewai.agents.cache import CacheHandler
5 |
6 |
7 | class CacheTools(BaseModel):
8 | """Default tools to hit the cache."""
9 |
10 | model_config = ConfigDict(arbitrary_types_allowed=True)
11 | name: str = "Hit Cache"
12 | cache_handler: CacheHandler = Field(
13 | description="Cache Handler for the crew",
14 | default=CacheHandler(),
15 | )
16 |
17 | def tool(self):
18 | return Tool.from_function(
19 | func=self.hit_cache,
20 | name=self.name,
21 | description="Reads directly from the cache",
22 | )
23 |
24 | def hit_cache(self, key):
25 | split = key.split("tool:")
26 | tool = split[1].split("|input:")[0].strip()
27 | tool_input = split[1].split("|input:")[1].strip()
28 | return self.cache_handler.read(tool, tool_input)
29 |
--------------------------------------------------------------------------------
/crewai/tools/gemini_tools.py:
--------------------------------------------------------------------------------
1 | # tools created using gemini
2 |
3 | import json
4 | import os
5 |
6 | import google.generativeai as genai
7 | from google.api_core import exceptions
8 |
9 | # Retrieve API Key from Environment Variable
10 | GOOGLE_AI_STUDIO = os.environ.get('GOOGLE_API_KEY')
11 |
12 | # Ensure the API key is available
13 | if not GOOGLE_AI_STUDIO:
14 | raise ValueError("API key not found. Please set the GOOGLE_AI_STUDIO2 environment variable.")
15 |
16 | import requests
17 | from langchain.tools import tool
18 |
19 | # Rest of your code remains the same
20 | genai.configure(api_key=GOOGLE_AI_STUDIO)
21 | model = genai.GenerativeModel('gemini-pro')
22 |
23 | class GeminiSearchTools():
24 | @tool("Gemini search the internet")
25 | def gemini_search(query):
26 | """
27 | Searches for content based on the provided query using the Gemini model.
28 | Handles DeadlineExceeded exceptions from the Google API.
29 | Args:
30 | query (str): The search query.
31 | Returns:
32 | str: The response text from the Gemini model or an error message.
33 | """
34 | try:
35 | response = model.generate_content(query)
36 | return response.text
37 | except exceptions.DeadlineExceeded as e:
38 | # Handle the DeadlineExceeded exception here
39 | print("Error: Deadline Exceeded -", str(e))
40 | # You can return a custom message or take other appropriate actions
41 | return "Error: The request timed out. Please try again later."
42 |
43 |
44 |
45 | @tool("Gemini search news on the internet")
46 | def gemini_search_news(query):
47 | """
48 | Searches for content based on the provided query using the Gemini model.
49 | Handles DeadlineExceeded exceptions from the Google API.
50 | Args:
51 | query (str): The search query.
52 | Returns:
53 | str: The response text from the Gemini model or an error message.
54 | """
55 | try:
56 | response = model.generate_content(query)
57 | return response.text
58 | except exceptions.DeadlineExceeded as e:
59 | # Handle the DeadlineExceeded exception here
60 | print("Error: Deadline Exceeded -", str(e))
61 | # You can return a custom message or take other appropriate actions
62 | return "Error: The request timed out. Please try again later."
--------------------------------------------------------------------------------
/crewai/tools/phi2_tools.py:
--------------------------------------------------------------------------------
1 | # tools created using Phi2
2 |
3 | import json
4 | import os
5 |
6 | import requests
7 | from langchain.tools import tool
8 |
9 | import spaces
10 | import torch
11 | from transformers import AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer
12 | from threading import Thread
13 | device = "cpu"
14 | if torch.cuda.is_available():
15 | device = "cuda"
16 | if torch.backends.mps.is_available():
17 | device = "mps"
18 |
19 |
20 | tokenizer = AutoTokenizer.from_pretrained("microsoft/phi-2", trust_remote_code=True)
21 | model = AutoModelForCausalLM.from_pretrained(
22 | "microsoft/phi-2",
23 | torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
24 | trust_remote_code=True,
25 | ).to(device)
26 |
27 |
28 | #@spaces.GPU(enable_queue=True)
29 | class Phi2SearchTools():
30 | @tool("Phi2 Normal")
31 | def phi2_search(text, temperature=.75, maxLen=2048):
32 | """
33 | Searches for content based on the provided query using the Gemini model.
34 | Handles DeadlineExceeded exceptions from the Google API.
35 | Args:
36 | query (str): The search query.
37 | Returns:
38 | str: The response text from the Gemini model or an error message.
39 | """
40 | inputs = tokenizer([text], return_tensors="pt").to(device)
41 | streamer = TextIteratorStreamer(tokenizer)
42 | generation_kwargs = dict(inputs, streamer=streamer, max_new_tokens=maxLen, temperature=temperature)
43 | thread = Thread(target=model.generate, kwargs=generation_kwargs)
44 | thread.start()
45 | t = ""
46 | toks = 0
47 | for out in streamer:
48 | t += out
49 | yield t
50 |
51 |
52 |
--------------------------------------------------------------------------------
/crewai/translations/el.json:
--------------------------------------------------------------------------------
1 | {
2 | "slices": {
3 | "observation": "\nΠαρατήρηση",
4 | "task": "Αρχή! Αυτό είναι ΠΟΛΥ σημαντικό για εσάς, η δουλειά σας εξαρτάται από αυτό!\n\nΤρέχουσα εργασία: {input}",
5 | "memory": "Αυτή είναι η περίληψη της μέχρι τώρα δουλειάς σας:\n{chat_history}",
6 | "role_playing": "Είσαι {role}.\n{backstory}\n\nΟ προσωπικός σας στόχος είναι: {goal}",
7 | "tools": "ΕΡΓΑΛΕΙΑ:\n------\nΈχετε πρόσβαση μόνο στα ακόλουθα εργαλεία:\n\n{tools}\n\nΓια να χρησιμοποιήσετε ένα εργαλείο, χρησιμοποιήστε την ακόλουθη ακριβώς μορφή:\n\n```\nΣκέψη: Χρειάζεται να χρησιμοποιήσω κάποιο εργαλείο; Ναί\nΔράση: η ενέργεια που πρέπει να γίνει, πρέπει να είναι μία από τις[{tool_names}], μόνο το όνομα.\nΕνέργεια προς εισαγωγή: η είσοδος στη δράση\nΠαρατήρηση: το αποτέλεσμα της δράσης\n```\n\nΌταν έχετε μια απάντηση για την εργασία σας ή εάν δεν χρειάζεται να χρησιμοποιήσετε ένα εργαλείο, ΠΡΕΠΕΙ να χρησιμοποιήσετε τη μορφή:\n\n```\nΣκέψη: Χρειάζεται να χρησιμοποιήσω κάποιο εργαλείο; Οχι\nΤελική απάντηση: [η απάντησή σας εδώ]",
8 | "task_with_context": "{task}\nΑυτό είναι το πλαίσιο με το οποίο εργάζεστε:\n{context}",
9 | "expected_output": "Η τελική σας απάντηση πρέπει να είναι: {expected_output}"
10 | },
11 | "errors": {
12 | "used_too_many_tools": "Έχω χρησιμοποιήσει πάρα πολλά εργαλεία για αυτήν την εργασία. Θα σας δώσω την απόλυτη ΚΑΛΥΤΕΡΗ τελική μου απάντηση τώρα και δεν θα χρησιμοποιήσω άλλα εργαλεία.",
13 | "agent_tool_missing_param": "\nΣφάλμα κατά την εκτέλεση του εργαλείου. Λείπουν ακριβώς 3 διαχωρισμένες τιμές σωλήνων (|). Για παράδειγμα, `coworker|task|context`. Πρέπει να φροντίσω να περάσω το πλαίσιο ως πλαίσιο.\n",
14 | "agent_tool_unexsiting_coworker": "\nΣφάλμα κατά την εκτέλεση του εργαλείου. Ο συνάδελφος που αναφέρεται στο Ενέργεια προς εισαγωγή δεν βρέθηκε, πρέπει να είναι μία από τις ακόλουθες επιλογές: {coworkers}.\n",
15 | "task_repeated_usage": "Μόλις χρησιμοποίησα το {tool} εργαλείο με είσοδο {tool_input}. Άρα ξέρω ήδη το αποτέλεσμα αυτού και δεν χρειάζεται να το χρησιμοποιήσω τώρα.\n"
16 | },
17 | "tools": {
18 | "delegate_work": "Χρήσιμο για την ανάθεση μιας συγκεκριμένης εργασίας σε έναν από τους παρακάτω συναδέλφους: {coworkers}.\nΗ είσοδος σε αυτό το εργαλείο θα πρέπει να είναι ένα κείμενο χωρισμένο σε σωλήνα (|) μήκους 3 (τρία), που αντιπροσωπεύει τον συνάδελφο στον οποίο θέλετε να του ζητήσετε (μία από τις επιλογές), την εργασία και όλο το πραγματικό πλαίσιο που έχετε για την εργασία .\nΓια παράδειγμα, `coworker|task|context`.",
19 | "ask_question": "Χρήσιμο για να κάνετε μια ερώτηση, γνώμη ή αποδοχή από τους παρακάτω συναδέλφους: {coworkers}.\nΗ είσοδος σε αυτό το εργαλείο θα πρέπει να είναι ένα κείμενο χωρισμένο σε σωλήνα (|) μήκους 3 (τρία), που αντιπροσωπεύει τον συνάδελφο στον οποίο θέλετε να το ρωτήσετε (μία από τις επιλογές), την ερώτηση και όλο το πραγματικό πλαίσιο που έχετε για την ερώτηση.\nΓια παράδειγμα, `coworker|question|context`."
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/crewai/translations/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "slices": {
3 | "observation": "\nObservation",
4 | "task": "Begin! This is VERY important to you, your job depends on it!\n\nCurrent Task: {input}",
5 | "memory": "This is the summary of your work so far:\n{chat_history}",
6 | "role_playing": "You are {role}.\n{backstory}\n\nYour personal goal is: {goal}",
7 | "tools": "TOOLS:\n------\nYou have access to only the following tools:\n\n{tools}\n\nTo use a tool, please use the exact following format:\n\n```\nThought: Do I need to use a tool? Yes\nAction: the action to take, should be one of [{tool_names}], just the name.\nAction Input: the input to the action\nObservation: the result of the action\n```\n\nWhen you have a response for your task, or if you do not need to use a tool, you MUST use the format:\n\n```\nThought: Do I need to use a tool? No\nFinal Answer: [your response here]",
8 | "task_with_context": "{task}\nThis is the context you're working with:\n{context}",
9 | "expected_output": "Your final answer must be: {expected_output}"
10 | },
11 | "errors": {
12 | "used_too_many_tools": "I've used too many tools for this task. I'm going to give you my absolute BEST Final answer now and not use any more tools.",
13 | "agent_tool_missing_param": "\nError executing tool. Missing exact 3 pipe (|) separated values. For example, `coworker|task|context`. I need to make sure to pass context as context.\n",
14 | "agent_tool_unexsiting_coworker": "\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options: {coworkers}.\n",
15 | "task_repeated_usage": "I just used the {tool} tool with input {tool_input}. So I already know the result of that and don't need to use it now.\n"
16 | },
17 | "tools": {
18 | "delegate_work": "Useful to delegate a specific task to one of the following co-workers: {coworkers}.\nThe input to this tool should be a pipe (|) separated text of length 3 (three), representing the co-worker you want to ask it to (one of the options), the task and all actual context you have for the task.\nFor example, `coworker|task|context`.",
19 | "ask_question": "Useful to ask a question, opinion or take from on of the following co-workers: {coworkers}.\nThe input to this tool should be a pipe (|) separated text of length 3 (three), representing the co-worker you want to ask it to (one of the options), the question and all actual context you have for the question.\n For example, `coworker|question|context`."
20 | }
21 | }
--------------------------------------------------------------------------------
/crewai/utilities/__init__.py:
--------------------------------------------------------------------------------
1 | from .i18n import I18N
2 | from .logger import Logger
3 | from .prompts import Prompts
4 | from .rpm_controller import RPMController
5 |
--------------------------------------------------------------------------------
/crewai/utilities/i18n.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | from typing import Dict, Optional
4 |
5 | from pydantic import BaseModel, Field, PrivateAttr, ValidationError, model_validator
6 |
7 |
8 | class I18N(BaseModel):
9 | _translations: Dict[str, Dict[str, str]] = PrivateAttr()
10 | language: Optional[str] = Field(
11 | default="en",
12 | description="Language used to load translations",
13 | )
14 |
15 | @model_validator(mode="after")
16 | def load_translation(self) -> "I18N":
17 | """Load translations from a JSON file based on the specified language."""
18 | try:
19 | dir_path = os.path.dirname(os.path.realpath(__file__))
20 | prompts_path = os.path.join(
21 | dir_path, f"../translations/{self.language}.json"
22 | )
23 |
24 | with open(prompts_path, "r") as f:
25 | self._translations = json.load(f)
26 | except FileNotFoundError:
27 | raise ValidationError(
28 | f"Translation file for language '{self.language}' not found."
29 | )
30 | except json.JSONDecodeError:
31 | raise ValidationError(f"Error decoding JSON from the prompts file.")
32 |
33 | if not self._translations:
34 | self._translations = {}
35 |
36 | return self
37 |
38 | def slice(self, slice: str) -> str:
39 | return self.retrieve("slices", slice)
40 |
41 | def errors(self, error: str) -> str:
42 | return self.retrieve("errors", error)
43 |
44 | def tools(self, error: str) -> str:
45 | return self.retrieve("tools", error)
46 |
47 | def retrieve(self, kind, key) -> str:
48 | try:
49 | return self._translations[kind][key]
50 | except:
51 | raise ValidationError(f"Translation for '{kind}':'{key}' not found.")
52 |
--------------------------------------------------------------------------------
/crewai/utilities/logger.py:
--------------------------------------------------------------------------------
1 | class Logger:
2 | def __init__(self, verbose_level=0):
3 | verbose_level = (
4 | 2 if isinstance(verbose_level, bool) and verbose_level else verbose_level
5 | )
6 | self.verbose_level = verbose_level
7 |
8 | def log(self, level, message):
9 | level_map = {"debug": 1, "info": 2}
10 | if self.verbose_level and level_map.get(level, 0) <= self.verbose_level:
11 | print(f"\n[{level.upper()}]: {message}")
12 |
--------------------------------------------------------------------------------
/crewai/utilities/prompts.py:
--------------------------------------------------------------------------------
1 | from typing import ClassVar
2 |
3 | from langchain.prompts import PromptTemplate, BasePromptTemplate
4 | from pydantic import BaseModel, Field
5 |
6 | from crewai.utilities import I18N
7 |
8 |
9 | class Prompts(BaseModel):
10 | """Manages and generates prompts for a generic agent with support for different languages."""
11 |
12 | i18n: I18N = Field(default=I18N())
13 |
14 | SCRATCHPAD_SLICE: ClassVar[str] = "\n{agent_scratchpad}"
15 |
16 | def task_execution_with_memory(self) -> BasePromptTemplate:
17 | """Generate a prompt for task execution with memory components."""
18 | return self._build_prompt(["role_playing", "tools", "memory", "task"])
19 |
20 | def task_execution_without_tools(self) -> BasePromptTemplate:
21 | """Generate a prompt for task execution without tools components."""
22 | return self._build_prompt(["role_playing", "task"])
23 |
24 | def task_execution(self) -> BasePromptTemplate:
25 | """Generate a standard prompt for task execution."""
26 | return self._build_prompt(["role_playing", "tools", "task"])
27 |
28 | def _build_prompt(self, components: list[str]) -> BasePromptTemplate:
29 | """Constructs a prompt string from specified components."""
30 | prompt_parts = [self.i18n.slice(component) for component in components]
31 | prompt_parts.append(self.SCRATCHPAD_SLICE)
32 | return PromptTemplate.from_template("".join(prompt_parts))
33 |
--------------------------------------------------------------------------------
/crewai/utilities/rpm_controller.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 | from typing import Union
4 |
5 | from pydantic import BaseModel, ConfigDict, Field, PrivateAttr, model_validator
6 |
7 | from crewai.utilities.logger import Logger
8 |
9 |
10 | class RPMController(BaseModel):
11 | model_config = ConfigDict(arbitrary_types_allowed=True)
12 | max_rpm: Union[int, None] = Field(default=None)
13 | logger: Logger = Field(default=None)
14 | _current_rpm: int = PrivateAttr(default=0)
15 | _timer: threading.Timer | None = PrivateAttr(default=None)
16 | _lock: threading.Lock = PrivateAttr(default=None)
17 |
18 | @model_validator(mode="after")
19 | def reset_counter(self):
20 | if self.max_rpm:
21 | self._lock = threading.Lock()
22 | self._reset_request_count()
23 | return self
24 |
25 | def check_or_wait(self):
26 | if not self.max_rpm:
27 | return True
28 |
29 | with self._lock:
30 | if self._current_rpm < self.max_rpm:
31 | self._current_rpm += 1
32 | return True
33 | else:
34 | self.logger.log(
35 | "info", "Max RPM reached, waiting for next minute to start."
36 | )
37 | self._wait_for_next_minute()
38 | self._current_rpm = 1
39 | return True
40 |
41 | def stop_rpm_counter(self):
42 | if self._timer:
43 | self._timer.cancel()
44 | self._timer = None
45 |
46 | def _wait_for_next_minute(self):
47 | time.sleep(60)
48 | with self._lock:
49 | self._current_rpm = 0
50 |
51 | def _reset_request_count(self):
52 | with self._lock:
53 | self._current_rpm = 0
54 | if self._timer:
55 | self._timer.cancel()
56 | self._timer = threading.Timer(60.0, self._reset_request_count)
57 | self._timer.start()
58 |
--------------------------------------------------------------------------------
/data/fraud.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Claims Center",
3 | "img": "https://www.svgrepo.com/show/448123/scope-expense-claims-read.svg",
4 | "children": [
5 | {
6 | "name": "Accident 1",
7 | "children": [
8 | {
9 | "role": "Driver 1",
10 | "name": "Person 1",
11 | "link": "http://accidentnetwork.chart/person_1",
12 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
13 | "size": 50000
14 | },
15 | {
16 | "role": "Witness 2",
17 | "name": "Person 2",
18 | "link": "http://accidentnetwork.chart/person_2",
19 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
20 | "size": 45000
21 | },
22 | {
23 | "role": "Lawyer 4",
24 | "name": "Person 4",
25 | "link": "http://accidentnetwork.chart/person_4",
26 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
27 | "size": 40000
28 | }
29 | ]
30 | },
31 | {
32 | "name": "Accident 2",
33 | "children": [
34 | {
35 | "role": "Passenger 3",
36 | "name": "Person 3",
37 | "link": "http://accidentnetwork.chart/person_3",
38 | "img": "https://www.svgrepo.com/show/340795/passenger-plus.svg",
39 | "size": 50000
40 | },
41 | {
42 | "role": "Driver 5",
43 | "name": "Person 5",
44 | "link": "http://accidentnetwork.chart/person_5",
45 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
46 | "size": 45000
47 | },
48 | {
49 | "role": "Adjuster 6",
50 | "name": "Person 6",
51 | "link": "http://accidentnetwork.chart/person_6",
52 | "img": "https://www.svgrepo.com/show/223812/insurance-user.svg",
53 | "size": 40000
54 | },
55 |
56 | {
57 | "role": "Lawyer 4",
58 | "name": "Person 4",
59 | "link": "http://accidentnetwork.chart/person_4",
60 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
61 | "size": 40000
62 | }
63 |
64 | ]
65 | },
66 | {
67 | "name": "Accident 3",
68 | "children": [
69 | {
70 | "role": "Driver 1",
71 | "name": "Person 1",
72 | "link": "http://accidentnetwork.chart/person_1",
73 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
74 | "size": 55000
75 | },
76 | {
77 | "role": "Witness 2",
78 | "name": "Person 2",
79 | "link": "http://accidentnetwork.chart/person_2",
80 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
81 | "size": 48000
82 | }
83 | ]
84 | },
85 | {
86 | "name": "Accident 4",
87 | "children": [
88 | {
89 | "role": "Driver 5",
90 | "name": "Person 5",
91 | "link": "http://accidentnetwork.chart/person_5",
92 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
93 | "size": 47000
94 | },
95 | {
96 | "role": "Lawyer 4",
97 | "name": "Person 4",
98 | "link": "http://accidentnetwork.chart/person_4",
99 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
100 | "size": 42000
101 | },
102 | {
103 | "role": "Adjuster 6",
104 | "name": "Person 6",
105 | "link": "http://accidentnetwork.chart/person_6",
106 | "img": "https://www.svgrepo.com/show/223812/insurance-user.svg",
107 | "size": 43000
108 | }
109 | ]
110 | },
111 | {
112 | "name": "Accident 5",
113 | "children": [
114 | {
115 | "role": "Passenger 3",
116 | "name": "Person 3",
117 | "link": "http://accidentnetwork.chart/person_3",
118 | "img": "https://www.svgrepo.com/show/340795/passenger-plus.svg",
119 | "size": 52000
120 | },
121 | {
122 | "role": "Adjuster 6",
123 | "name": "Person 6",
124 | "link": "http://accidentnetwork.chart/person_6",
125 | "img": "https://www.svgrepo.com/show/223812/insurance-user.svg",
126 | "size": 43000
127 | },
128 | {
129 | "role": "Witness 2",
130 | "name": "Person 2",
131 | "link": "http://accidentnetwork.chart/person_2",
132 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
133 | "size": 48000
134 | }
135 | ]
136 | },
137 |
138 | {
139 | "name": "Accident 6",
140 | "children": [
141 | {
142 | "role": "Driver 7",
143 | "name": "Person 7",
144 | "link": "http://accidentnetwork.chart/person_7",
145 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
146 | "size": 50000
147 | },
148 | {
149 | "role": "Witness 8",
150 | "name": "Person 8",
151 | "link": "http://accidentnetwork.chart/person_8",
152 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
153 | "size": 45000
154 | },
155 | {
156 | "role": "Lawyer 9",
157 | "name": "Person 9",
158 | "link": "http://accidentnetwork.chart/person_9",
159 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
160 | "size": 40000
161 | }
162 | ]
163 | },
164 | {
165 | "name": "Accident 7",
166 | "children": [
167 | {
168 | "role": "Passenger 10",
169 | "name": "Person 10",
170 | "link": "http://accidentnetwork.chart/person_10",
171 | "img": "https://www.svgrepo.com/show/340795/passenger-plus.svg",
172 | "size": 50000
173 | },
174 | {
175 | "role": "Driver 11",
176 | "name": "Person 11",
177 | "link": "http://accidentnetwork.chart/person_11",
178 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
179 | "size": 45000
180 | },
181 | {
182 | "role": "Adjuster 12",
183 | "name": "Person 12",
184 | "link": "http://accidentnetwork.chart/person_12",
185 | "img": "https://www.svgrepo.com/show/223812/insurance-user.svg",
186 | "size": 40000
187 | },
188 |
189 | {
190 | "role": "Lawyer 13",
191 | "name": "Person 13",
192 | "link": "http://accidentnetwork.chart/person_13",
193 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
194 | "size": 40000
195 | }
196 |
197 | ]
198 | },
199 | {
200 | "name": "Accident 8",
201 | "children": [
202 | {
203 | "role": "Driver 14",
204 | "name": "Person 14",
205 | "link": "http://accidentnetwork.chart/person_14",
206 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
207 | "size": 55000
208 | },
209 | {
210 | "role": "Witness 15",
211 | "name": "Person 15",
212 | "link": "http://accidentnetwork.chart/person_15",
213 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
214 | "size": 48000
215 | }
216 | ]
217 | },
218 | {
219 | "name": "Accident 9",
220 | "children": [
221 | {
222 | "role": "Driver 16",
223 | "name": "Person 16",
224 | "link": "http://accidentnetwork.chart/person_16",
225 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
226 | "size": 47000
227 | },
228 | {
229 | "role": "Lawyer 17",
230 | "name": "Person 17",
231 | "link": "http://accidentnetwork.chart/person_17",
232 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
233 | "size": 42000
234 | }
235 | ]
236 | },
237 | {
238 | "name": "Accident 10",
239 | "children": [
240 | {
241 | "role": "Passenger 18",
242 | "name": "Person 18",
243 | "link": "http://accidentnetwork.chart/person_18",
244 | "img": "https://www.svgrepo.com/show/340795/passenger-plus.svg",
245 | "size": 52000
246 | },
247 | {
248 | "role": "Adjuster 19",
249 | "name": "Person 19",
250 | "link": "http://accidentnetwork.chart/person_19",
251 | "img": "https://www.svgrepo.com/show/223812/insurance-user.svg",
252 | "size": 43000
253 | },
254 | {
255 | "role": "Witness 20",
256 | "name": "Person 20",
257 | "link": "http://accidentnetwork.chart/person_20",
258 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
259 | "size": 48000
260 | }
261 | ]
262 | }
263 |
264 |
265 | ]
266 | }
267 |
268 |
--------------------------------------------------------------------------------
/data/fraud2.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Address 1",
3 | "img": "./operations.png",
4 | "children": [
5 | {
6 | "name": "Account Holder 1",
7 | "children": [
8 | {
9 | "role": "Credit Card 1",
10 | "name": "Credit Card 1",
11 | "link": "http://operationphantomclaims.chart/lawyers/jonathan_smith",
12 | "img": "https://yt3.ggpht.com/bL1xQ_58wHFjdPJrnVNsKgmJIrNuwq9A3W_OFggf6a9F8YT-PAAiKr5Cp1Q6rEvL42TueR9irw=s48-c-k-c0x00ffffff-no-rj",
13 | "size": 50000
14 | },
15 | {
16 | "role": "Bank Account 1",
17 | "name": "Bank Account 1",
18 | "link": "http://operationphantomclaims.chart/lawyers/emily_johnson",
19 | "img": "https://yt3.ggpht.com/ytc/AGIKgqO8nsbuMeqmVSLAhP-Dr2Qn_-aYdSCyklqYHJCKyJo=s48-c-k-c0x00ffffff-no-rj",
20 | "size": 45000
21 | },
22 | {
23 | "role": "Unsecured Loan 1",
24 | "name": "Unsecured Loan 1",
25 | "link": "http://operationphantomclaims.chart/lawyers/michael_davis",
26 | "img": "./CaseManager.png",
27 | "size": 40000
28 | },
29 | {
30 | "role": "Phone Number 1",
31 | "name": "Phone Number 1",
32 | "link": "http://operationphantomclaims.chart/lawyers/michael_davis",
33 | "img": "./CaseManager.png",
34 | "size": 40000
35 | },
36 | {
37 | "role": "SSN 1",
38 | "name": "SSN 1",
39 | "link": "http://operationphantomclaims.chart/lawyers/michael_davis",
40 | "img": "./CaseManager.png",
41 | "size": 40000
42 | }
43 | ]
44 | },
45 | {
46 | "name": "Account Holder 2",
47 | "children": [
48 | {
49 | "role": "Credit Card 2",
50 | "name": "Credit Card 2",
51 | "link": "http://operationphantomclaims.chart/actors/alex_martinez",
52 | "img": "./LeadActor.png",
53 | "size": 45000
54 | },
55 | {
56 | "role": "Bank Account 2",
57 | "name": "Bank Account 2",
58 | "link": "http://operationphantomclaims.chart/actors/rachel_green",
59 | "img": "./SupportingActor.png",
60 | "size": 40000
61 | },
62 | {
63 | "role": "SSN 2",
64 | "name": "SSN 2",
65 | "link": "http://operationphantomclaims.chart/actors/rachel_green",
66 | "img": "./SupportingActor.png",
67 | "size": 40000
68 | },
69 | {
70 | "role": "Phone Number 1",
71 | "name": "Phone Number 1",
72 | "link": "http://operationphantomclaims.chart/lawyers/michael_davis",
73 | "img": "./CaseManager.png",
74 | "size": 40000
75 | }
76 | ]
77 | },
78 | {
79 | "name": "Account Holder 3",
80 | "children": [
81 | {
82 | "role": "Bank Account 3",
83 | "name": "Bank Account 3",
84 | "link": "http://operationphantomclaims.chart/insiders/david_lee",
85 | "img": "./InsuranceAgent.png",
86 | "size": 40000
87 | },
88 | {
89 | "role": "Unsecured Loan 3",
90 | "name": "Unsecured Loan 3",
91 | "link": "http://operationphantomclaims.chart/insiders/sophia_turner",
92 | "img": "./ClaimsProcessor.png",
93 | "size": 38000
94 | },
95 | {
96 | "role": "Phone Number 2",
97 | "name": "Phone Number 2",
98 | "link": "http://operationphantomclaims.chart/insiders/sophia_turner",
99 | "img": "./ClaimsProcessor.png",
100 | "size": 38000
101 | },
102 | {
103 | "role": "SSN 1",
104 | "name": "SSN 1",
105 | "link": "http://operationphantomclaims.chart/lawyers/michael_davis",
106 | "img": "./CaseManager.png",
107 | "size": 40000
108 | }
109 | ]
110 | }
111 | ]
112 | }
113 |
--------------------------------------------------------------------------------
/data/insurance_data.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Accident Network - Potential Fraud Indicators",
3 | "img": "./accidents_fraud.png",
4 | "children": [
5 | {
6 | "name": "Accident 1",
7 | "children": [
8 | {
9 | "role": "Driver",
10 | "name": "Person 1",
11 | "link": "http://accidentnetwork.chart/person_1",
12 | "img": "./Person1.png",
13 | "size": 50000
14 | },
15 | {
16 | "role": "Witness",
17 | "name": "Person 2",
18 | "link": "http://accidentnetwork.chart/person_2",
19 | "img": "./Person2.png",
20 | "size": 45000
21 | },
22 | {
23 | "role": "Lawyer",
24 | "name": "Person 4",
25 | "link": "http://accidentnetwork.chart/person_4",
26 | "img": "./Person4.png",
27 | "size": 40000
28 | }
29 | ]
30 | },
31 | {
32 | "name": "Accident 2",
33 | "children": [
34 | {
35 | "role": "Passenger",
36 | "name": "Person 3",
37 | "link": "http://accidentnetwork.chart/person_3",
38 | "img": "./Person3.png",
39 | "size": 50000
40 | },
41 | {
42 | "role": "Driver",
43 | "name": "Person 5",
44 | "link": "http://accidentnetwork.chart/person_5",
45 | "img": "./Person5.png",
46 | "size": 45000
47 | },
48 | {
49 | "role": "Adjuster",
50 | "name": "Person 6",
51 | "link": "http://accidentnetwork.chart/person_6",
52 | "img": "./Person6.png",
53 | "size": 40000
54 | }
55 | ]
56 | },
57 | {
58 | "name": "Accident 3",
59 | "children": [
60 | {
61 | "role": "Driver",
62 | "name": "Person 1",
63 | "link": "http://accidentnetwork.chart/person_1",
64 | "img": "./Person1.png",
65 | "size": 55000
66 | },
67 | {
68 | "role": "Witness",
69 | "name": "Person 2",
70 | "link": "http://accidentnetwork.chart/person_2",
71 | "img": "./Person2.png",
72 | "size": 48000
73 | }
74 | ]
75 | },
76 | {
77 | "name": "Accident 4",
78 | "children": [
79 | {
80 | "role": "Driver",
81 | "name": "Person 5",
82 | "link": "http://accidentnetwork.chart/person_5",
83 | "img": "./Person5.png",
84 | "size": 47000
85 | },
86 | {
87 | "role": "Lawyer",
88 | "name": "Person 4",
89 | "link": "http://accidentnetwork.chart/person_4",
90 | "img": "./Person4.png",
91 | "size": 42000
92 | }
93 | ]
94 | },
95 | {
96 | "name": "Accident 5",
97 | "children": [
98 | {
99 | "role": "Passenger",
100 | "name": "Person 3",
101 | "link": "http://accidentnetwork.chart/person_3",
102 | "img": "./Person3.png",
103 | "size": 52000
104 | },
105 | {
106 | "role": "Adjuster",
107 | "name": "Person 6",
108 | "link": "http://accidentnetwork.chart/person_6",
109 | "img": "./Person6.png",
110 | "size": 43000
111 | }
112 | ]
113 | }
114 | ]
115 | }
--------------------------------------------------------------------------------
/data/insurance_fraud_ring.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Operation Phantom Claims",
3 | "img": "https://via.placeholder.com/150",
4 | "children": [
5 | {
6 | "name": "Providers",
7 | "children": [
8 | {
9 | "role": "Doctor",
10 | "name": "Dr. Emily Harris",
11 | "link": "Goal: To make extra income by diagnosing false injuries. Backstory: Once a respected physician, faced financial ruin and turned to insurance fraud.",
12 | "img": "https://via.placeholder.com/150"
13 | },
14 | {
15 | "role": "Lawyer",
16 | "name": "James Clarkson",
17 | "link": "Goal: To gain financially by filing fraudulent claims. Backstory: An ambitious lawyer with a declining career, saw opportunity in insurance fraud.",
18 | "img": "https://via.placeholder.com/150"
19 | },
20 | {
21 | "role": "Body Shop Owner",
22 | "name": "Mia Thompson",
23 | "link": "Goal: To boost business revenue by misrepresenting vehicle damages. Backstory: Inherited a struggling body shop and resorted to fraud to save it.",
24 | "img": "https://via.placeholder.com/150"
25 | }
26 | ]
27 | },
28 | {
29 | "name": "Participants",
30 | "children": [
31 | {
32 | "role": "Driver",
33 | "name": "Alex Martinez",
34 | "link": "Goal: To make quick money by pretending to be involved in accidents. Backstory: Part-time student with debt, lured into the fraud for financial relief.",
35 | "img": "https://via.placeholder.com/150"
36 | },
37 | {
38 | "role": "Passenger",
39 | "name": "Rachel Young",
40 | "link": "Goal: To support her family financially through fraud. Backstory: A single mother, joined the fraud ring out of desperation to provide for her children.",
41 | "img": "https://via.placeholder.com/150"
42 | },
43 | {
44 | "role": "Pedestrian",
45 | "name": "Ethan Smith",
46 | "link": "Goal: To earn money for his startup by faking injuries. Backstory: Aspiring entrepreneur needing funds, saw the fraud as a temporary solution.",
47 | "img": "https://via.placeholder.com/150"
48 | },
49 | {
50 | "role": "Witness",
51 | "name": "Olivia Brown",
52 | "link": "Goal: To fund her travels through participation in the fraud scheme. Backstory: Travel enthusiast lacking funds, joined the fraud ring for financial gain.",
53 | "img": "https://via.placeholder.com/150"
54 | }
55 | ]
56 | }
57 | ]
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/data/marvel.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "marvel",
3 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/marvel.png",
4 | "children": [
5 | {
6 | "name": "Heroes",
7 | "children": [
8 | {
9 | "hero": "Spider-Man",
10 | "name": "Peter Benjamin Parker",
11 | "link": "http://marvel.com/characters/54/spider-man",
12 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_spiderman.png",
13 | "size": 40000
14 | },
15 | {
16 | "hero": "CAPTAIN MARVEL",
17 | "name": "Carol Danvers",
18 | "link": "http://marvel.com/characters/9/captain_marvel",
19 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_captainmarvel.png",
20 | "size": 40000
21 | },
22 | {
23 | "hero": "HULK",
24 | "name": "Robert Bruce Banner",
25 | "link": "http://marvel.com/characters/25/hulk",
26 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_hulk.png",
27 | "size": 40000
28 | },
29 | {
30 | "hero": "Black Widow",
31 | "name": "Natalia 'Natasha' Alianovna Romanova",
32 | "link": "http://marvel.com/characters/6/black_widow",
33 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_blackwidow.png",
34 | "size": 40000
35 | },
36 | {
37 | "hero": "Daredevil",
38 | "name": "Matthew Michael Murdock",
39 | "link": "http://marvel.com/characters/11/daredevil",
40 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_daredevil.png",
41 | "size": 40000
42 | },
43 | {
44 | "hero": "Wolverine",
45 | "name": "James Howlett",
46 | "link": "http://marvel.com/characters/66/wolverine",
47 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_wolverine.png",
48 | "size": 40000
49 | },
50 | {
51 | "hero": "Captain America",
52 | "name": "Steven Rogers",
53 | "link": "http://marvel.com/characters/8/captain_america",
54 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_captainamerica.png",
55 | "size": 40000
56 | },
57 | {
58 | "hero": "Iron Man",
59 | "name": "Anthony Edward 'Tony' Stark",
60 | "link": "http://marvel.com/characters/29/iron_man",
61 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_ironman.png",
62 | "size": 40000
63 | },
64 | {
65 | "hero": "THOR",
66 | "name": "Thor Odinson",
67 | "link": "http://marvel.com/characters/60/thor",
68 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_thor.png",
69 | "size": 40000
70 | }
71 | ]
72 | },
73 | {
74 | "name": "Villains",
75 | "children": [
76 | {
77 | "hero": "Dr. Doom",
78 | "name": "Victor von Doom",
79 | "link": "http://marvel.com/characters/13/dr_doom",
80 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/drdoom.png",
81 | "size": 40000
82 | },
83 | {
84 | "hero": "Mystique",
85 | "name": "Unrevealed",
86 | "link": "http://marvel.com/characters/1552/mystique",
87 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/mystique.png",
88 | "size": 40000
89 | },
90 | {
91 | "hero": "Red Skull",
92 | "name": "Johann Shmidt",
93 | "link": "http://marvel.com/characters/1901/red_skull",
94 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/redskull.png",
95 | "size": 40000
96 | },
97 | {
98 | "hero": "Ronan",
99 | "name": "Ronan",
100 | "link": "http://marvel.com/characters/49/ronan",
101 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/ronan.png",
102 | "size": 40000
103 | },
104 | {
105 | "hero": "Magneto",
106 | "name": "Max Eisenhardt",
107 | "link": "http://marvel.com/characters/35/magneto",
108 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/magneto.png",
109 | "size": 40000
110 | },
111 | {
112 | "hero": "Thanos",
113 | "name": "Thanos",
114 | "link": "http://marvel.com/characters/58/thanos",
115 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/thanos.png",
116 | "size": 40000
117 | },
118 | {
119 | "hero": "Black Cat",
120 | "name": "Felicia Hardy",
121 | "link": "http://marvel.com/characters/271/black_cat",
122 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/blackcat.png",
123 | "size": 40000
124 | }
125 | ]
126 | },
127 | {
128 | "name": "Teams",
129 | "children": [
130 | {
131 | "hero": "Avengers",
132 | "name": "",
133 | "link": "http://marvel.com/characters/68/avengers",
134 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/avengers.png",
135 | "size": 40000
136 | },
137 | {
138 | "hero": "Guardians of the Galaxy",
139 | "name": "",
140 | "link": "http://marvel.com/characters/70/guardians_of_the_galaxy",
141 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/gofgalaxy.png",
142 | "size": 40000
143 | },
144 | {
145 | "hero": "Defenders",
146 | "name": "",
147 | "link": "http://marvel.com/characters/534/defenders",
148 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/defenders.png",
149 | "size": 40000
150 | },
151 | {
152 | "hero": "X-Men",
153 | "name": "",
154 | "link": "http://marvel.com/characters/71/x-men",
155 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/xmen.png",
156 | "size": 40000
157 | },
158 | {
159 | "hero": "Fantastic Four",
160 | "name": "",
161 | "link": "http://marvel.com/characters/69/fantastic_four",
162 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/fantasticfour.png",
163 | "size": 40000
164 | },
165 | {
166 | "hero": "Inhumans",
167 | "name": "",
168 | "link": "http://marvel.com/characters/1040/inhumans",
169 | "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/inhumans.png",
170 | "size": 40000
171 | }
172 | ]
173 | }
174 | ]
175 | }
--------------------------------------------------------------------------------
/data/neo4jdata.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Claims Center",
3 | "img": "https://www.svgrepo.com/show/448123/scope-expense-claims-read.svg",
4 | "children": [
5 | {
6 | "name": "Accident 1",
7 | "children": [
8 | {
9 | "role": "Driver 1",
10 | "name": "Person 1",
11 | "link": "http://accidentnetwork.chart/person_1",
12 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
13 | "size": 50000
14 | },
15 | {
16 | "role": "Witness 2",
17 | "name": "Person 2",
18 | "link": "http://accidentnetwork.chart/person_2",
19 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
20 | "size": 45000
21 | },
22 | {
23 | "role": "Lawyer 4",
24 | "name": "Person 4",
25 | "link": "http://accidentnetwork.chart/person_4",
26 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
27 | "size": 40000
28 | }
29 | ]
30 | },
31 | {
32 | "name": "Accident 2",
33 | "children": [
34 | {
35 | "role": "Passenger 3",
36 | "name": "Person 3",
37 | "link": "http://accidentnetwork.chart/person_3",
38 | "img": "https://www.svgrepo.com/show/340795/passenger-plus.svg",
39 | "size": 50000
40 | },
41 | {
42 | "role": "Driver 5",
43 | "name": "Person 5",
44 | "link": "http://accidentnetwork.chart/person_5",
45 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
46 | "size": 45000
47 | },
48 | {
49 | "role": "Adjuster 6",
50 | "name": "Person 6",
51 | "link": "http://accidentnetwork.chart/person_6",
52 | "img": "https://www.svgrepo.com/show/223812/insurance-user.svg",
53 | "size": 40000
54 | },
55 |
56 | {
57 | "role": "Lawyer 4",
58 | "name": "Person 4",
59 | "link": "http://accidentnetwork.chart/person_4",
60 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
61 | "size": 40000
62 | }
63 |
64 | ]
65 | },
66 | {
67 | "name": "Accident 3",
68 | "children": [
69 | {
70 | "role": "Driver 1",
71 | "name": "Person 1",
72 | "link": "http://accidentnetwork.chart/person_1",
73 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
74 | "size": 55000
75 | },
76 | {
77 | "role": "Witness 2",
78 | "name": "Person 2",
79 | "link": "http://accidentnetwork.chart/person_2",
80 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
81 | "size": 48000
82 | }
83 | ]
84 | },
85 | {
86 | "name": "Accident 4",
87 | "children": [
88 | {
89 | "role": "Driver 5",
90 | "name": "Person 5",
91 | "link": "http://accidentnetwork.chart/person_5",
92 | "img": "https://www.svgrepo.com/show/214436/driving-license.svg",
93 | "size": 47000
94 | },
95 | {
96 | "role": "Lawyer 4",
97 | "name": "Person 4",
98 | "link": "http://accidentnetwork.chart/person_4",
99 | "img": "https://www.svgrepo.com/show/492976/lawyer-explaining.svg",
100 | "size": 42000
101 | },
102 | {
103 | "role": "Adjuster 6",
104 | "name": "Person 6",
105 | "link": "http://accidentnetwork.chart/person_6",
106 | "img": "https://www.svgrepo.com/show/223812/insurance-user.svg",
107 | "size": 43000
108 | }
109 | ]
110 | },
111 | {
112 | "name": "Accident 5",
113 | "children": [
114 | {
115 | "role": "Passenger 3",
116 | "name": "Person 3",
117 | "link": "http://accidentnetwork.chart/person_3",
118 | "img": "https://www.svgrepo.com/show/340795/passenger-plus.svg",
119 | "size": 52000
120 | },
121 | {
122 | "role": "Adjuster 6",
123 | "name": "Person 6",
124 | "link": "http://accidentnetwork.chart/person_6",
125 | "img": "https://www.svgrepo.com/show/223812/insurance-user.svg",
126 | "size": 43000
127 | },
128 | {
129 | "role": "Witness 2",
130 | "name": "Person 2",
131 | "link": "http://accidentnetwork.chart/person_2",
132 | "img": "https://www.svgrepo.com/show/85131/witness.svg",
133 | "size": 48000
134 | }
135 | ]
136 | }
137 |
138 | ]
139 | }
140 |
--------------------------------------------------------------------------------
/images/CaseManager.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qaillc/Phi2Hackathon/66b0ad3e17fc4a525dae2d40dda999fe03a00c04/images/CaseManager.png
--------------------------------------------------------------------------------
/images/ClaimsProcessor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qaillc/Phi2Hackathon/66b0ad3e17fc4a525dae2d40dda999fe03a00c04/images/ClaimsProcessor.png
--------------------------------------------------------------------------------
/images/InsuranceActor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qaillc/Phi2Hackathon/66b0ad3e17fc4a525dae2d40dda999fe03a00c04/images/InsuranceActor.png
--------------------------------------------------------------------------------
/images/LeadActor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qaillc/Phi2Hackathon/66b0ad3e17fc4a525dae2d40dda999fe03a00c04/images/LeadActor.png
--------------------------------------------------------------------------------
/images/LeadLawyer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qaillc/Phi2Hackathon/66b0ad3e17fc4a525dae2d40dda999fe03a00c04/images/LeadLawyer.png
--------------------------------------------------------------------------------
/images/LegalAdvisor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qaillc/Phi2Hackathon/66b0ad3e17fc4a525dae2d40dda999fe03a00c04/images/LegalAdvisor.png
--------------------------------------------------------------------------------
/images/SupportingActor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qaillc/Phi2Hackathon/66b0ad3e17fc4a525dae2d40dda999fe03a00c04/images/SupportingActor.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | streamlit
2 | py2neo
3 | IPython
4 | # streamlit_agraph
5 |
6 | torch
7 | transformers
8 | einops
9 |
10 | SPARQLWrapper
11 |
12 | numpy
13 | pandas
14 | htbuilder
15 | streamlit
16 | streamlit-agraph==0.0.28
17 | SPARQLWrapper
18 | networkx
19 |
20 |
21 | # [-e] git+https://github.com/openlegaldata/oldp-sdk-python.git#egg=oldp-api
22 | # -e https://github.com/openlegaldata/oldp-sdk-python.git#egg=oldp-api
23 |
24 |
25 | openai
26 | langchain
27 | dedent
28 | unstructured
29 | faiss-cpu
30 | sec-api
31 | yfinance
32 | google-generativeai==0.3.1
33 | google-ai-generativelanguage==0.4.0
34 | streamlit
35 | tiktoken
36 | langchain_openai
37 | langchain-google-genai
38 | clarifai
39 | Pillow
40 |
41 |
--------------------------------------------------------------------------------