added updates to topology
This commit is contained in:
parent
9fd542c28e
commit
d0939b9b3b
12 changed files with 232 additions and 60 deletions
|
|
@ -113,7 +113,7 @@ async def cognify(datasets: Union[str, List[str]] = None):
|
|||
text = "empty file"
|
||||
if text == "":
|
||||
text = "empty file"
|
||||
subchunks = chunk_engine.chunk_data(chunk_strategy, text, chunk_config.chunk_size, chunk_config.chunk_overlap)
|
||||
subchunks,_ = chunk_engine.chunk_data(chunk_strategy, text, chunk_config.chunk_size, chunk_config.chunk_overlap)
|
||||
|
||||
if dataset_name not in data_chunks:
|
||||
data_chunks[dataset_name] = []
|
||||
|
|
@ -145,23 +145,37 @@ async def cognify(datasets: Union[str, List[str]] = None):
|
|||
batch_size = 20
|
||||
file_count = 0
|
||||
files_batch = []
|
||||
from cognee.infrastructure.databases.graph.config import get_graph_config
|
||||
graph_config = get_graph_config()
|
||||
graph_topology = graph_config.graph_model
|
||||
|
||||
|
||||
if graph_config.infer_graph_topology and graph_config.graph_topology_task:
|
||||
from cognee.modules.topology.topology import TopologyEngine
|
||||
topology_engine = TopologyEngine(infer=graph_config.infer_graph_topology)
|
||||
await topology_engine.add_graph_topology(dataset_files=dataset_files)
|
||||
elif not graph_config.infer_graph_topology:
|
||||
from cognee.modules.topology.topology import TopologyEngine
|
||||
topology_engine = TopologyEngine(infer=graph_config.infer_graph_topology)
|
||||
await topology_engine.add_graph_topology(graph_config.topology_file_path)
|
||||
elif not graph_config.graph_topology_task:
|
||||
parent_node_id = f"DefaultGraphModel__{USER_ID}"
|
||||
|
||||
|
||||
for (dataset_name, files) in dataset_files:
|
||||
for file_metadata in files:
|
||||
from cognee.infrastructure.databases.graph.config import get_graph_config
|
||||
graph_config = get_graph_config()
|
||||
graph_topology = graph_config.graph_model
|
||||
|
||||
if graph_topology == SourceCodeGraph:
|
||||
parent_node_id = f"{file_metadata['name']}.{file_metadata['extension']}"
|
||||
if parent_node_id:
|
||||
document_id = await add_document_node(
|
||||
graph_client,
|
||||
parent_node_id = parent_node_id,
|
||||
document_metadata = file_metadata,
|
||||
)
|
||||
else:
|
||||
parent_node_id = f"DefaultGraphModel__{USER_ID}"
|
||||
|
||||
document_id = await add_document_node(
|
||||
graph_client,
|
||||
parent_node_id=parent_node_id,
|
||||
document_metadata=file_metadata,
|
||||
)
|
||||
document_id = await add_document_node(
|
||||
graph_client,
|
||||
parent_node_id=file_metadata['id'],
|
||||
document_metadata=file_metadata,
|
||||
)
|
||||
|
||||
files_batch.append((dataset_name, file_metadata, document_id))
|
||||
file_count += 1
|
||||
|
|
|
|||
|
|
@ -52,14 +52,16 @@ class DefaultChunkEngine():
|
|||
"""
|
||||
|
||||
if self.chunk_strategy == ChunkStrategy.PARAGRAPH:
|
||||
chunked_data = self.chunk_data_by_paragraph(source_data,chunk_size=self.chunk_size, chunk_overlap=self.chunk_overlap)
|
||||
chunked_data, chunk_number = self.chunk_data_by_paragraph(source_data,chunk_size=self.chunk_size, chunk_overlap=self.chunk_overlap)
|
||||
elif self.chunk_strategy == ChunkStrategy.SENTENCE:
|
||||
chunked_data = self.chunk_by_sentence(source_data, chunk_size = self.chunk_size, chunk_overlap=self.chunk_overlap)
|
||||
chunked_data, chunk_number = self.chunk_by_sentence(source_data, chunk_size = self.chunk_size, chunk_overlap=self.chunk_overlap)
|
||||
elif self.chunk_strategy == ChunkStrategy.EXACT:
|
||||
chunked_data = self.chunk_data_exact(source_data, chunk_size = self.chunk_size, chunk_overlap=self.chunk_overlap)
|
||||
chunked_data, chunk_number = self.chunk_data_exact(source_data, chunk_size = self.chunk_size, chunk_overlap=self.chunk_overlap)
|
||||
else:
|
||||
chunked_data, chunk_number = "Invalid chunk strategy.", [0, "Invalid chunk strategy."]
|
||||
|
||||
|
||||
return chunked_data
|
||||
return chunked_data, chunk_number
|
||||
|
||||
|
||||
|
||||
|
|
@ -68,7 +70,11 @@ class DefaultChunkEngine():
|
|||
chunks = []
|
||||
for i in range(0, len(data), chunk_size - chunk_overlap):
|
||||
chunks.append(data[i:i + chunk_size])
|
||||
return chunks
|
||||
numbered_chunks = []
|
||||
for i, chunk in enumerate(chunks):
|
||||
numbered_chunk = [i + 1, chunk]
|
||||
numbered_chunks.append(numbered_chunk)
|
||||
return chunks, numbered_chunks
|
||||
|
||||
|
||||
|
||||
|
|
@ -87,7 +93,12 @@ class DefaultChunkEngine():
|
|||
sentence_chunks.extend(chunks)
|
||||
else:
|
||||
sentence_chunks.append(sentence)
|
||||
return sentence_chunks
|
||||
|
||||
numbered_chunks = []
|
||||
for i, chunk in enumerate(sentence_chunks):
|
||||
numbered_chunk = [i + 1, chunk]
|
||||
numbered_chunks.append(numbered_chunk)
|
||||
return sentence_chunks, numbered_chunks
|
||||
|
||||
|
||||
|
||||
|
|
@ -129,4 +140,9 @@ class DefaultChunkEngine():
|
|||
# Update start_idx to be the current end_idx
|
||||
start_idx = end_idx
|
||||
|
||||
return chunks
|
||||
numbered_chunks = []
|
||||
for i, chunk in enumerate(chunks):
|
||||
numbered_chunk = [i + 1, chunk]
|
||||
numbered_chunks.append(numbered_chunk)
|
||||
|
||||
return chunks, numbered_chunks
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ class LangchainChunkEngine:
|
|||
"""
|
||||
|
||||
if chunk_strategy == ChunkStrategy.CODE:
|
||||
chunked_data = self.chunk_data_by_code(source_data,self.chunk_size, self.chunk_overlap)
|
||||
chunked_data, chunk_number = self.chunk_data_by_code(source_data,self.chunk_size, self.chunk_overlap)
|
||||
|
||||
elif chunk_strategy == ChunkStrategy.LANGCHAIN_CHARACTER:
|
||||
chunked_data = self.chunk_data_by_character(source_data,self.chunk_size, self.chunk_overlap)
|
||||
chunked_data, chunk_number = self.chunk_data_by_character(source_data,self.chunk_size, self.chunk_overlap)
|
||||
else:
|
||||
chunked_data = "Invalid chunk strategy."
|
||||
return chunked_data
|
||||
chunked_data, chunk_number = "Invalid chunk strategy.", [0, "Invalid chunk strategy."]
|
||||
return chunked_data, chunk_number
|
||||
|
||||
|
||||
def chunk_data_by_code(self, data_chunks, chunk_size, chunk_overlap= 10, language=None):
|
||||
|
|
@ -58,14 +58,24 @@ class LangchainChunkEngine:
|
|||
|
||||
only_content = [chunk.page_content for chunk in code_chunks]
|
||||
|
||||
return only_content
|
||||
numbered_chunks = []
|
||||
for i, chunk in enumerate(code_chunks):
|
||||
numbered_chunk = [i + 1, chunk]
|
||||
numbered_chunks.append(numbered_chunk)
|
||||
|
||||
return only_content, numbered_chunks
|
||||
|
||||
def chunk_data_by_character(self, data_chunks, chunk_size=1500, chunk_overlap=10):
|
||||
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
||||
splitter = RecursiveCharacterTextSplitter(chunk_size =chunk_size, chunk_overlap=chunk_overlap)
|
||||
data = splitter.create_documents([data_chunks])
|
||||
data_chunks = splitter.create_documents([data_chunks])
|
||||
|
||||
only_content = [chunk.page_content for chunk in data]
|
||||
only_content = [chunk.page_content for chunk in data_chunks]
|
||||
|
||||
return only_content
|
||||
numbered_chunks = []
|
||||
for i, chunk in enumerate(data_chunks):
|
||||
numbered_chunk = [i + 1, chunk]
|
||||
numbered_chunks.append(numbered_chunk)
|
||||
|
||||
return only_content, numbered_chunks
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,12 @@ class GraphConfig(BaseSettings):
|
|||
)
|
||||
graph_engine: object = GraphDBType.NETWORKX
|
||||
graph_model: object = KnowledgeGraph
|
||||
graph_topology_task: bool = True
|
||||
graph_topology: object = KnowledgeGraph
|
||||
infer_graph_topology: bool = True
|
||||
topology_file_path: str = os.path.join(
|
||||
get_relationaldb_config().db_path, "graph_topology.json"
|
||||
)
|
||||
|
||||
model_config = SettingsConfigDict(env_file=".env", extra="allow")
|
||||
|
||||
|
|
@ -33,6 +38,7 @@ class GraphConfig(BaseSettings):
|
|||
"graph_database_password": self.graph_database_password,
|
||||
"graph_database_port": self.graph_database_port,
|
||||
"graph_engine": self.graph_engine,
|
||||
"infer_graph_topology": self.infer_graph_topology,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
You are a topology master and need to extract the following topology information from the text provided to you.
|
||||
Relationship part'S can't be empty, and have to be logical AND CONNECTING ELEMENTS OF THE TOPOLOGY
|
||||
Relationship parts can't be empty, and have to be logical AND CONNECTING ELEMENTS OF THE TOPOLOGY
|
||||
The source is the parent of the target. And the target is the child of the source.
|
||||
Have in mind this model needs to become a graph later.
|
||||
Have in mind this model needs to become a graph later, and USE EXISTING IDS AS NODE IDS
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
[
|
||||
{
|
||||
"node_id": "1",
|
||||
"name": "Node 1",
|
||||
"node_id": "062c22dfd99b599f90cd2d325c8bcf69",
|
||||
"name": "062c22df-d99b-599f-90cd-2d325c8bcf69",
|
||||
"default_relationship": {
|
||||
"type": "related_to",
|
||||
"source": "1",
|
||||
"target": "2"
|
||||
"source": "062c22dfd99b599f90cd2d325c8bcf69",
|
||||
"target": "6dfe01b607d25b7783c81d6c11ce2aa7"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"node_id": "2",
|
||||
"name": "Node 2",
|
||||
"node_id": "6dfe01b607d25b7783c81d6c11ce2aa7",
|
||||
"name": "6dfe01b6-07d2-5b77-83c8-1d6c11ce2aa7",
|
||||
"default_relationship": {
|
||||
"type": "related_to",
|
||||
"source": "2",
|
||||
"target": "3"
|
||||
"source": "6dfe01b6-07d2-5b77-83c8-1d6c11ce2aa7",
|
||||
"target": "a27bb4fa897e53a594cab446e1d33dbf"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
A quantum computer is a computer that takes advantage of quantum mechanical phenomena.
|
||||
At small scales, physical matter exhibits properties of both particles and waves, and quantum computing leverages this behavior, specifically quantum superposition and entanglement, using specialized hardware that supports the preparation and manipulation of quantum states.
|
||||
Classical physics cannot explain the operation of these quantum devices, and a scalable quantum computer could perform some calculations exponentially faster (with respect to input size scaling) than any modern "classical" computer. In particular, a large-scale quantum computer could break widely used encryption schemes and aid physicists in performing physical simulations; however, the current state of the technology is largely experimental and impractical, with several obstacles to useful applications. Moreover, scalable quantum computers do not hold promise for many practical tasks, and for many important tasks quantum speedups are proven impossible.
|
||||
The basic unit of information in quantum computing is the qubit, similar to the bit in traditional digital electronics. Unlike a classical bit, a qubit can exist in a superposition of its two "basis" states. When measuring a qubit, the result is a probabilistic output of a classical bit, therefore making quantum computers nondeterministic in general. If a quantum computer manipulates the qubit in a particular way, wave interference effects can amplify the desired measurement results. The design of quantum algorithms involves creating procedures that allow a quantum computer to perform calculations efficiently and quickly.
|
||||
Physically engineering high-quality qubits has proven challenging. If a physical qubit is not sufficiently isolated from its environment, it suffers from quantum decoherence, introducing noise into calculations. Paradoxically, perfectly isolating qubits is also undesirable because quantum computations typically need to initialize qubits, perform controlled qubit interactions, and measure the resulting quantum states. Each of those operations introduces errors and suffers from noise, and such inaccuracies accumulate.
|
||||
In principle, a non-quantum (classical) computer can solve the same computational problems as a quantum computer, given enough time. Quantum advantage comes in the form of time complexity rather than computability, and quantum complexity theory shows that some quantum algorithms for carefully selected tasks require exponentially fewer computational steps than the best known non-quantum algorithms. Such tasks can in theory be solved on a large-scale quantum computer whereas classical computers would not finish computations in any reasonable amount of time. However, quantum speedup is not universal or even typical across computational tasks, since basic tasks such as sorting are proven to not allow any asymptotic quantum speedup. Claims of quantum supremacy have drawn significant attention to the discipline, but are demonstrated on contrived tasks, while near-term practical use cases remain limited.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
U analizi komunikacionih sistema kod životinja zadržaćemo se samo na semiotičkim problemima – postoje li u pojedinim sistemima njihove komunikacije ZNACI, semiotički SISTEMI i neke semiotičke OPERACIJE, u onom smislu kako su ti pojmovi definisani i utvrđeni kod ljudi. Analiziraćemo sličnosti i razlike između komunikacije kod životinja i kod ljudi, posebno semiotičke komunikacije kod čoveka.
|
||||
Kada se ima u vidu bogatstvo oblika komunikativnih veza među životinjama: sva raznolikost signala u pogledu fizičkih svojstava – hemijski, oflaktivni (mirisni), akustički (uključiv i ultrazvukove), električni, motorički (kinezički), proksemički (položaj u prostoru), vizuelni i drugi, zatim – raznovrsnost kanala (sredina) kroz koje se ostvaruje veza, kao i raznovrsnost funkcija koje imaju komunikativni sistemi, pitanje je koliko je uopšte opravdano govoriti o komunikaciji životinja u celini.
|
||||
Međutim, kada se pristupi semiotičkoj analizi sistema komunikacije među životinjama, iza raznolikosti nalazi se prilična jednoličnost, čak tolika da se ne može utvrditi postoji li nekakvo usavršavanje sistema komunikacije duž evolucione lestvice.
|
||||
Pogledajmo najpre kakve FUNKCIJE opslužuju sistemi komunikacija kod životinja. Poznati istraživač ovih problema, Marler, ovako rezimira analizu komunikacije među nižim i višim majmunima: „U velikoj većini, celokupni sistem komunikacije izgleda postoji radi organizacije socijalnog ponašanja grupe, regulacije dominantnosti i subordinacije, održanja mira i kohezije u grupi, kao i radi reprodukcije i brige o mladima (Marleu, 1967). Pomenute funkcije mogle bi se, nešto raščlanjenije, ovako opisati:
|
||||
Postoje, najpre, kod nekih vrsta signali za identifikaciju pojedinaca (npr. parovi mužjaka i ženki kod ptica pevačica mogu ostati u stalnoj vezi tokom cele jedne godine i međusobno se identifikuju pomoću pevanja, ponekada u vidu dueta koji može izvesti samo određeni par) ili za identifikaciju vrste (npr. pčele-stražari ubijaju na ulazu u košnicu svaku jedinku koja se na osnovu signala ne može identifikovati kao član tog pčelinjeg društva).
|
||||
Najbrojniji i najraznovrsniji su signali koji saopštavaju o motivacionim i afektivnim stanjima jedinke i o promenama tih stanja, a često i o suptilnim nijansama raspoloženja. Ta vrsta signala kazuje o gladi, seksualnim potrebama, ugroženostistrahu, boli, uzbuđenju, naklonosti, neprijateljstvu i agresivnosti, o zadovoljstvu i o svim varijacijama ovakvih motivacionih stanja i raspoloženja.
|
||||
Izuzetnu biološku vrednost imaju signali koji regulišu međusobne odnose jedinki ili odnose u grupi kao celini. Podsticanje, dozivanje i približavanje partnera, privlačenje i parenje, međusobno prepoznavanje i saradnja između roditelja i mladunčadi – nemogući su bez nekog sistema signalizacije. Određivanje zauzete teritorije, okupljanje grupe, vođstvo i određivanje statusa u grupi, dominacija i potčinjavanje, organizovanje kolonija – to su samo neke od socijalnih funkcija koje poslužuju sistemi komunikacije.
|
||||
U svim sistemima komunikacije među životinjama upadljivo je najmanje onih poruka koje govore o okolini u kojoj životinja živi; samo kod pojedinih vrsta postoje signali koji saopštavaju o postojanju ili lokalizaciji napadača, o hrani ili nalazištu hrane, o lokaciji staništa.
|
||||
Kada se ima u vidu samo ono što je ovde pobrojano, stiče se utisak o bogatstvu informacija koje mogu preneti komunikativni sistemi životinja. Međutim, za pun uvid u prirodu tih sistema potrebno je videti na koji način sistemi komuniciranja kod životinja obavljaju te funkcije. Obično se kaže da ovi sistemi imaju, pre svega ili isključivo socijalne funkcije. To je tačno, ali pod uslovom da se prethodno razjasni šta ovde znači – socijalno. Funkcije tih sistema su socijalne najpre su smislu da signali UTIČU NA DRUGE jedinke. I upravo tako, utiču na druge jedinke, a ne upućeni su drugim jedinkama. U stvari, u razvoju odnosa među jedinkama tokom evolucije izgrađuje se svojevrsna socijalna simbioza, u kojoj neki vidljivi pokazatelji ponašanja jedne jedinke postaju obaveštenja (signali) o njenim motivacionim stanjima. Dakle, signali su (za razliku od SIMBOLA) samo pokazatelji i sastavni delovi motivacionih, afektivnih ili nekih drugih unutrašnjih stanja jedinke. I baš zbog toga se ne može reći da jedinka upućuje drugoj signale, ona prosto doživljava to što doživljava. Neke komponente doživljaja dostupne su opažanju drugih jedinki i u toku zajedničkog života postaju signali određenih stanja. Tokom evolucije ti signali se stabilizuju, stilizuju (ritualizuju) i prerađuju u određeni sistem komunikacije.
|
||||
U tako stvorenoj socijalnoj simbiozi, signali koje upućuju životinje jedne drugima pre su nalozi za izvođenje određenih radnji, tj. pokretači ili inhibitori radnji nego saopštene informacije. Hormonalne i druge promene u organizmu koje dovode do pojave signala u jednoj jedinki skoro automatski u određenim uslovima pokreću lanac hormonalnih i ostalih promena u jedinki koja prima signale, a te promene kod njih izazivaju određene radnje. Dakle, komunikativni sistemi imaju socijalne funkcije zato što menjaju ponašanje drugih jedinki. A to dalje znači da jedina jedinka kojoj životinja ne upućuje signale jeste ona sama, i to je jedna od suštinskih razlika semiotičke komunikacije čoveka i komunikacije među žvotinjama.
|
||||
Iz prethodno opisanog sledi i ovo: signal retko kada ima isto značenje za jedinku koja ga emituje i jedinku koja ga prima. U komunikaciji među životinjama više se radi o odnosima komplementarnosti nego o odnosima recipročnosti (baš kao u nekim neverbalnim vidovima komunikacije kod ljudi: onaj koji pokazuje gnev i onaj ko opaža gnev imaju različite doživljaje). U ovom pogledu signali više služe za socijalnu facilitaciju ponašanja i sinhronizaciju fizioloških stanja i motoričkih radnji u toku interindividualnih aktivnosti (nrp. parenja) ili grupnih aktivnosti (npr. u komunikaciji pčela) nego za socijalnu razmenu.
|
||||
Potrebno je ukazati na još jednu odliku komunikativnih sistema životinja: postoji uska specijalizacija signala za određene funkcije. Svaka od ranije pobrojanih funkcija ima specifične signale koji joj služe (npr. krici kod ptica su signali opasnosti, a pesma ptica-pevačica je ljubavni zov). Ovo, naravno, ne znači da za obavljanje jedne vrste funkcija postoji samo jedna vrsta signala, jer je i u sistemima veze između životinja pravilo da postoji redundansa (npr. za saopštavanje o mestu nalazišta paše pčele koriste istovremeno i „jezik“ igre telom i akustičke signale).
|
||||
U pogledu SEMANTIKE (značenja), sistemi komunikacija među životinjama poseduju dva osnovna svojstva:
|
||||
Postoji konačan i obično veoma mali broj poruka koje stoje svakoj vrsti na raspolaganju – značajnija je karakteristika da je broj signala konačan. Naime, životinja svake vrste dobija nasleđem, ili stiče uz izvesno učenje, određen broj signala i taj repertoar ostaje zatvoren, nepromenljiv. Za razliku od toga, ljudski govor je otvoreni sistem, koji po svojim pravilima stvara nove jedinice sistema.
|
||||
Jedva da poneki istraživač saopštava da je zapazio stvaranje novih signala kod životinja. Tamo gde je signale moguće tehnički pobrojati, nalazi se da njihov broj nije veliki. Tako kod pojedinih vrsta majmuna istraživači redovno utvrđuju da se broj akustičkih signala kreće od 10-15, dok se kod šimpanzi može razlikovati 9 facijanih ekspresija. Ni kod drugih životinja taj broj nije mnogo veći: kod nekih jedva da postoje dva signala u istom kanalu veze, a jedino se kod nekih ptica-pevačica sreće i do nekoliko stotina različitih „motiva“ u pesmama. Pošto većinu komunikativnih sredstava kojima se služe životinje dobijaju nasleđem, ta nasledna određenost vrlo je striktna i u pogledu funkcije i forme signala, tako da je životinja sposobna za komunikaciju koja je karakteristična za njenu vrstu, čak i kada se razvija u izolaciji. Kod nekih vrsta ptica učenje ima značajniju ulogu. Poznato je da mladi nekih vrsta ptica mogu da nauče i pesmu drugih vrsta ptica, u čijoj zajednici odrastaju, dok kod nekih vrsta ptica određene grupacije jedinki stvaraju svoje „dijalekte“. Izgleda da je funkcija tih dijalekata da iz nekih razloga ograniče parenje među pripadnicima različitih grupacija, jer ptice mogu da se pare samo na osnovu ljubavne pesme onog „dijalekta“ kojim se služe. Ovakav način sticanja komunikativnih sistema veoma podseća na usvajanje govora kod dece.
|
||||
Signali nemaju denotativna značenja, tj. ne označavaju neki određeni segment realnosti (denotat), ne saopštavaju nešto o tom denotatu, već samo predstavljaju vid ekspresije stanja organizma. Za semiotičku analizu posebno je značajno da li signali koje životinje koriste zaista označavaju nešto različito od sebe samih, da li kazuju nešto o denotatu, ili su puka ekspresija fizioloških i afektivnih stanja životinje.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Natural language processing (NLP) is an interdisciplinary subfield of computer science and information retrieval. It is primarily concerned with giving computers the ability to support and manipulate human language. It involves processing natural language datasets, such as text corpora or speech corpora, using either rule-based or probabilistic (i.e. statistical and, most recently, neural network-based) machine learning approaches. The goal is a computer capable of "understanding"[citation needed] the contents of documents, including the contextual nuances of the language within them. To this end, natural language processing often borrows ideas from theoretical linguistics. The technology can then accurately extract information and insights contained in the documents as well as categorize and organize the documents themselves.
|
||||
Challenges in natural language processing frequently involve speech recognition, natural-language understanding, and natural-language generation.
|
||||
|
|
@ -0,0 +1 @@
|
|||
German novels are fun to read and talk about nature
|
||||
|
|
@ -8,6 +8,8 @@ async def infer_data_topology(content: str, graph_topology=None):
|
|||
if graph_topology is None:
|
||||
graph_config = get_graph_config()
|
||||
graph_topology = graph_config.graph_topology
|
||||
|
||||
print("content: ", type(content))
|
||||
try:
|
||||
return (await extract_topology(
|
||||
content,
|
||||
|
|
|
|||
|
|
@ -2,11 +2,20 @@
|
|||
|
||||
import csv
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
import aiofiles
|
||||
import pandas as pd
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Any, Dict, List, Optional, Union, Type
|
||||
|
||||
from cognee.infrastructure.data.chunking.config import get_chunk_config
|
||||
from cognee.infrastructure.data.chunking.get_chunking_engine import get_chunk_engine
|
||||
from cognee.infrastructure.databases.graph.get_graph_client import get_graph_client
|
||||
from cognee.infrastructure.databases.relational import get_relationaldb_config
|
||||
from cognee.infrastructure.files.utils.extract_text_from_file import extract_text_from_file
|
||||
from cognee.infrastructure.files.utils.guess_file_type import guess_file_type, FileTypeException
|
||||
from cognee.modules.cognify.config import get_cognify_config
|
||||
from cognee.base_config import get_base_config
|
||||
from cognee.modules.topology.topology_data_models import NodeModel, RelationshipModel, Document, DirectoryModel, DirMetadata, GitHubRepositoryModel
|
||||
|
|
@ -14,10 +23,12 @@ import asyncio
|
|||
cognify_config = get_cognify_config()
|
||||
base_config = get_base_config()
|
||||
|
||||
logger = logging.getLogger("topology")
|
||||
|
||||
class TopologyEngine:
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, infer:bool) -> None:
|
||||
self.models: Dict[str, Type[BaseModel]] = {}
|
||||
self.infer = False
|
||||
self.infer = infer
|
||||
|
||||
async def flatten_model(self, model: NodeModel, parent_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""Flatten the model to a dictionary."""
|
||||
|
|
@ -62,34 +73,122 @@ class TopologyEngine:
|
|||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to load data from {file_path}: {e}")
|
||||
|
||||
async def add_graph_topology(self, file_path: str):
|
||||
async def add_graph_topology(self, file_path: str=None, dataset_files: list[tuple[Any, Any]]=None,):
|
||||
"""Add graph topology from a JSON or CSV file."""
|
||||
try:
|
||||
data = await self.load_data(file_path)
|
||||
flt_topology = await self.recursive_flatten(data)
|
||||
df = pd.DataFrame(flt_topology)
|
||||
if self.infer:
|
||||
from cognee.modules.topology.infer_data_topology import infer_data_topology
|
||||
|
||||
initial_chunks_and_ids = []
|
||||
|
||||
chunk_config = get_chunk_config()
|
||||
chunk_engine = get_chunk_engine()
|
||||
chunk_strategy = chunk_config.chunk_strategy
|
||||
|
||||
|
||||
|
||||
for dataset_name, files in dataset_files:
|
||||
for base_file in files:
|
||||
with open(base_file["file_path"], "rb") as file:
|
||||
try:
|
||||
file_type = guess_file_type(file)
|
||||
text = extract_text_from_file(file, file_type)
|
||||
|
||||
subchunks, chunks_with_ids = chunk_engine.chunk_data(chunk_strategy, text, chunk_config.chunk_size,
|
||||
chunk_config.chunk_overlap)
|
||||
|
||||
if chunks_with_ids[0][0] == 1:
|
||||
initial_chunks_and_ids.append({base_file['id']: chunks_with_ids})
|
||||
|
||||
except FileTypeException:
|
||||
logger.warning("File (%s) has an unknown file type. We are skipping it.", file["id"])
|
||||
|
||||
|
||||
topology = await infer_data_topology(str(initial_chunks_and_ids))
|
||||
graph_client = await get_graph_client()
|
||||
|
||||
for _, row in df.iterrows():
|
||||
node_data = row.to_dict()
|
||||
node_id = node_data.pop("node_id", None)
|
||||
await graph_client.add_node(node_id, node_data)
|
||||
if pd.notna(row.get("relationship_source")) and pd.notna(row.get("relationship_target")):
|
||||
await graph_client.add_edge(row["relationship_source"], row["relationship_target"], relationship_name=row["relationship_type"])
|
||||
for node in topology["nodes"]:
|
||||
await graph_client.add_node(node["id"], node)
|
||||
for edge in topology["edges"]:
|
||||
await graph_client.add_edge(edge["source_node_id"], edge["target_node_id"], relationship_name=edge["relationship_name"])
|
||||
|
||||
return graph_client.graph
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to add graph topology from {file_path}: {e}")
|
||||
|
||||
|
||||
|
||||
else:
|
||||
dataset_level_information = dataset_files[0][1]
|
||||
|
||||
# Extract the list of valid IDs from the explanations
|
||||
valid_ids = {item['id'] for item in dataset_level_information}
|
||||
try:
|
||||
data = await self.load_data(file_path)
|
||||
flt_topology = await self.recursive_flatten(data)
|
||||
df = pd.DataFrame(flt_topology)
|
||||
graph_client = await get_graph_client()
|
||||
|
||||
print("df", df)
|
||||
|
||||
for _, row in df.iterrows():
|
||||
node_data = row.to_dict()
|
||||
node_id = node_data.pop("node_id", None)
|
||||
if node_id in valid_ids:
|
||||
await graph_client.add_node(node_id, node_data)
|
||||
if node_id not in valid_ids:
|
||||
raise ValueError(f"Node ID {node_id} not found in the dataset")
|
||||
if pd.notna(row.get("relationship_source")) and pd.notna(row.get("relationship_target")):
|
||||
await graph_client.add_edge(row["relationship_source"], row["relationship_target"], relationship_name=row["relationship_type"])
|
||||
|
||||
for dataset in dataset_files:
|
||||
print("dataset", dataset)
|
||||
|
||||
return
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to add graph topology from {file_path}: {e}")
|
||||
|
||||
|
||||
|
||||
async def main():
|
||||
topology_engine = TopologyEngine()
|
||||
file_path = 'example_data.json' # or 'example_data.csv'
|
||||
# text = """Conservative PP in the lead in Spain, according to estimate
|
||||
# An estimate has been published for Spain:
|
||||
#
|
||||
# Opposition leader Alberto Núñez Feijóo’s conservative People’s party (PP): 32.4%
|
||||
#
|
||||
# Spanish prime minister Pedro Sánchez’s Socialist party (PSOE): 30.2%
|
||||
#
|
||||
# The far-right Vox party: 10.4%
|
||||
#
|
||||
# In Spain, the right has sought to turn the European election into a referendum on Sánchez.
|
||||
#
|
||||
# Ahead of the vote, public attention has focused on a saga embroiling the prime minister’s wife, Begoña Gómez, who is being investigated over allegations of corruption and influence-peddling, which Sanchez has dismissed as politically-motivated and totally baseless."""
|
||||
# text_two = """The far-right Vox party: 10.4%"""
|
||||
|
||||
# Adding graph topology
|
||||
graph = await topology_engine.add_graph_topology(file_path)
|
||||
print(graph)
|
||||
from cognee.api.v1.add import add
|
||||
dataset_name = "explanations"
|
||||
print(os.getcwd())
|
||||
data_dir = os.path.abspath("../../../.data")
|
||||
print(os.getcwd())
|
||||
|
||||
await add(f"data://{data_dir}", dataset_name="explanations")
|
||||
|
||||
relational_config = get_relationaldb_config()
|
||||
db_engine = relational_config.database_engine
|
||||
|
||||
|
||||
datasets = db_engine.get_datasets()
|
||||
dataset_files =[]
|
||||
|
||||
for added_dataset in datasets:
|
||||
if dataset_name in added_dataset:
|
||||
dataset_files.append((added_dataset, db_engine.get_files_metadata(added_dataset)))
|
||||
|
||||
|
||||
|
||||
print(dataset_files)
|
||||
topology_engine = TopologyEngine(infer=True)
|
||||
file_path = 'example_data.json' # or 'example_data.csv'
|
||||
#
|
||||
# # Adding graph topology
|
||||
graph = await topology_engine.add_graph_topology(file_path, dataset_files=dataset_files)
|
||||
# print(graph)
|
||||
|
||||
# Run the main function
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue