├── 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 | --------------------------------------------------------------------------------