cwyodmodules 0.3.44__py3-none-any.whl → 0.3.45__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,230 +1,237 @@
1
- from graphrag.indexing.types import (
2
- EntityModel,
3
- RelationshipModel,
4
- ChunkModel,
5
- HighLevelKeywords
6
- )
7
-
8
- from graphrag.database.base import get_db
9
- from graphrag.database.models import Chunk, Entity, Relationship
10
-
11
- from graphrag.indexing.utils import calculate_hash
12
- from graphrag.llm.llm import extract_entities_completion
13
-
14
- from typing import (List,
15
- Tuple,
16
- Dict,
17
- Any,
18
- Set)
19
- from fuzzywuzzy import fuzz
20
- from openai import RateLimitError
21
-
22
- import uuid
23
- import asyncio
24
- import uuid
25
-
26
-
27
- def _extract_chunk_info_from_db_if_exists(chunk: str) -> Tuple[List[EntityModel], List[RelationshipModel], ChunkModel] | None:
28
-
29
- db = next(get_db())
30
- hash = "chunk-" + calculate_hash(text=chunk)
31
- exists = db.query(Chunk).filter(Chunk.hash == hash).first()
32
- if exists:
33
- entities_models, relationships_models = [], []
34
- entities = db.query(Entity).filter(Entity.chunk_id == exists.chunk_id).all()
35
- for entity in entities:
36
- entity_model = EntityModel(
37
- entity_name=entity.entity_name,
38
- entity_type=entity.entity_type,
39
- entity_description=entity.description,
40
- chunk_id=str(exists.chunk_id)
41
- )
42
- entities_models.append(entity_model)
43
- relationships = db.query(Relationship).filter(Relationship.chunk_id == exists.chunk_id).all()
44
- for rel in relationships:
45
- rel_model = RelationshipModel(
46
- source_entity=rel.source_entity.entity_name,
47
- target_entity=rel.target_entity.entity_name,
48
- relationship_description=rel.description,
49
- relationship_strength=rel.weight,
50
- chunk_id=str(exists.chunk_id),
51
- relationship_keywords=rel.keywords
52
- )
53
- relationships_models.append(rel_model)
54
- db.close()
55
- return entities_models, relationships_models, ChunkModel(text=exists.text, id=str(exists.chunk_id))
56
- db.close()
57
- return None
58
-
59
-
60
- def _merge_entities(entities: List[EntityModel], threshold: int=75) -> Tuple[List[EntityModel], Dict[str, Set[str]]]:
61
-
62
- def find_most_similar(entity: EntityModel, candidates: List[EntityModel], threshold: int) -> List[EntityModel]:
63
-
64
- most_sim_entity: List[EntityModel] = []
65
- for candidate_entity in candidates:
66
- if (entity.entity_type != candidate_entity.entity_type): continue
67
- try:
68
- score = fuzz.ratio(entity.entity_name, candidate_entity.entity_name)
69
- except IndexError:
70
- continue
71
- if score > threshold:
72
- most_sim_entity.append(candidate_entity)
73
-
74
- return most_sim_entity
75
-
76
- kept_vs_merged = {}
77
-
78
- merged_entities = set()
79
- modified_entities: Dict[Tuple[str, str, str, str], List[EntityModel]] = {}
80
- for index, entity in enumerate(entities):
81
- most_sim_entities = find_most_similar(entity=entity, candidates=entities[index+1:], threshold=threshold)
82
- entity_key = (entity.entity_name, entity.entity_type, entity.entity_description)
83
-
84
- if entity_key in merged_entities:
85
- print(f"{entity_key} already exists as an entity")
86
- continue
87
-
88
- if (entity.entity_name, entity.entity_type, entity.entity_description, entity.get_chunk_id) not in modified_entities:
89
- modified_entities[(entity.entity_name, entity.entity_type, entity.entity_description, entity.get_chunk_id)] = []
90
- if most_sim_entities:
91
- for most_sim_entity in most_sim_entities:
92
- most_sim_key = (most_sim_entity.entity_name, most_sim_entity.entity_type, most_sim_entity.entity_description)
93
- print(f"{most_sim_key[:2]} has been identified as similar to another entity")
94
- merged_entities.add(most_sim_key)
95
- modified_entities[(entity.entity_name, entity.entity_type, entity.entity_description, entity.get_chunk_id)].append(most_sim_entity)
96
- if most_sim_entity.entity_name not in kept_vs_merged:
97
- kept_vs_merged[most_sim_entity.entity_name] = {entity.entity_name}
98
- else:
99
- kept_vs_merged[most_sim_entity.entity_name].add(entity.entity_name)
100
-
101
- updated_entities = []
102
- for entity_info, sim_entities in modified_entities.items():
103
-
104
- if entity_info[:-1] in merged_entities and not len(sim_entities): continue
105
-
106
- updated_entities.append(
107
- EntityModel(
108
- entity_name=entity_info[0],
109
- entity_type=entity_info[1],
110
- entity_description=entity_info[2] + "\n".join([sim_entity.entity_description for sim_entity in sim_entities]),
111
- chunk_id=set([entity_info[3]] + [sim_entity.get_chunk_id for sim_entity in sim_entities])
112
- )
113
- )
114
-
115
- return updated_entities, kept_vs_merged
116
-
117
-
118
- def _merge_relationships(
119
- relationships: List[RelationshipModel], kept_vs_merged_entities: Dict[str, List[str]]
120
- ) -> List[RelationshipModel]:
121
-
122
- for relationship in relationships:
123
- source, target = relationship.source_entity, relationship.target_entity
124
- try:
125
- if source in kept_vs_merged_entities:
126
- relationship.source_entity = list(kept_vs_merged_entities[source])[0]
127
- if target in kept_vs_merged_entities:
128
- relationship.target_entity = list(kept_vs_merged_entities[target])[0]
129
- except (KeyError, IndexError):
130
- print(f"Something went wrong for edge: {(source, target)}")
131
- continue
132
-
133
-
134
- merged_relationships = {}
135
- for relationship in relationships:
136
- edge = (relationship.source_entity, relationship.target_entity)
137
- if edge not in merged_relationships:
138
- merged_relationships[edge] = relationship
139
- continue
140
- print(f"Edge: ({source}, {target}) already exists")
141
- existing_edge = merged_relationships[edge]
142
- existing_edge.relationship_description += "\n" + relationship.relationship_description
143
- existing_edge.relationship_strength += relationship.relationship_strength
144
- existing_edge.relationship_keywords += relationship.relationship_keywords
145
- existing_edge.relationship_keywords = list(set(existing_edge.relationship_keywords))
146
- existing_edge.update_chunk_ids(relationship.chunk_id)
147
-
148
- return list(merged_relationships.values())
149
-
150
-
151
- async def _extract_graph_information_from_chunk(chunk: str, entity_types: Dict[str, str], gleaning: int=1) -> Tuple[List[EntityModel], List[RelationshipModel], ChunkModel] | None:
152
-
153
- already_exists = _extract_chunk_info_from_db_if_exists(chunk=chunk)
154
- if already_exists is not None:
155
- return already_exists
156
- chunk_info: Dict[str, Any] = {}
157
- for _ in range(gleaning):
158
- gleaning_chunk_info = await extract_entities_completion(chunk=chunk,
159
- history=None,
160
- entity_types=entity_types)
161
- if gleaning_chunk_info is None: continue
162
-
163
- more_chunk_info = await extract_entities_completion(
164
- chunk=chunk, history=str(chunk_info), entity_types=entity_types
165
- )
166
- if more_chunk_info is not None:
167
- chunk_info.update(more_chunk_info)
168
-
169
- chunk_model = ChunkModel(text=chunk, id=str(uuid.uuid4()))
170
- try:
171
- entities, relationships, high_level_keywords = [chunk_info[key] for key in ("entities", "relationships", "content_keywords")]
172
- except KeyError as e:
173
- print(f"KeyError -> {e}")
174
- print(chunk_info)
175
- raise e
176
- if isinstance(high_level_keywords, list): high_level_keywords = {"content_keywords": high_level_keywords}
177
- entities_models, relationships_models, high_level_keywords_models = [
178
- [model(**val, chunk_id={chunk_model.id}) for val in values] if isinstance(values, list) else [model(**values, chunk_id={chunk_model.id})]
179
- for model, values in zip((EntityModel, RelationshipModel, HighLevelKeywords),
180
- (entities, relationships, high_level_keywords))
181
- ]
182
- return entities_models, relationships_models, chunk_model
183
-
184
-
185
- async def extract_entities(chunks: List[str], entity_types: Dict[str, str], gleaning: int=1, batch: int=15) -> Tuple[List[EntityModel], List[RelationshipModel], Dict[str, Set[str]], List[ChunkModel]]:
186
-
187
- if len(chunks) > batch:
188
- results = []
189
- for k in range(0, len(chunks), batch):
190
- batch_chunks = chunks[k: k + batch]
191
- try:
192
- results.extend(
193
- await asyncio.gather(*[
194
- _extract_graph_information_from_chunk(chunk=chunk, gleaning=gleaning, entity_types=entity_types) for chunk in batch_chunks
195
- ])
196
- )
197
- except RateLimitError:
198
- print("Rate limit error. Sleeping for a few seconds...")
199
- await asyncio.sleep(2)
200
- sub_batch = batch // 2
201
- for j in range(0, len(batch_chunks), sub_batch):
202
- results.extend(
203
- await asyncio.gather(*[
204
- _extract_graph_information_from_chunk(chunk=chunk, gleaning=gleaning, entity_types=entity_types) for chunk in batch_chunks[j: j + sub_batch]
205
- ])
206
- )
207
- await asyncio.sleep(1)
208
- await asyncio.sleep(1)
209
- else:
210
- results = await asyncio.gather(*[
211
- _extract_graph_information_from_chunk(chunk=chunk, gleaning=gleaning, entity_types=entity_types) for chunk in chunks
212
- ])
213
-
214
- if results is None:
215
- return None
216
-
217
- entities, relationships, chunks_models = [], [], []
218
-
219
- for result in results:
220
- if result is None:
221
- continue
222
- entities_n, relationships_n, chunk = result
223
- entities.extend(entities_n)
224
- relationships.extend(relationships_n)
225
- chunks_models.append(chunk)
226
-
227
- entities, kept_vs_merged = _merge_entities(entities=entities)
228
- relationships = _merge_relationships(relationships=relationships, kept_vs_merged_entities=kept_vs_merged)
229
-
230
- return entities, relationships, kept_vs_merged, chunks_models
1
+ from .types import (
2
+ EntityExtractionResult,
3
+ RelationshipExtractionResult,
4
+ Chunk,
5
+ EntityModel,
6
+ RelationshipModel,
7
+ KeptVsMerged,
8
+ ChunkModel,
9
+ HighLevelKeywords
10
+ )
11
+ from ..llm.entity_extraction import extract_entities as llm_extract_entities
12
+ from typing import List, Dict, Tuple
13
+ import pandas as pd
14
+
15
+ from graphrag.database.base import get_db
16
+ from graphrag.database.models import Chunk, Entity, Relationship
17
+
18
+ from graphrag.indexing.utils import calculate_hash
19
+ from graphrag.llm.llm import extract_entities_completion
20
+
21
+ from typing import (List,
22
+ Tuple,
23
+ Dict,
24
+ Any,
25
+ Set)
26
+ from fuzzywuzzy import fuzz
27
+ from openai import RateLimitError
28
+
29
+ import uuid
30
+ import asyncio
31
+ import uuid
32
+
33
+
34
+ def _extract_chunk_info_from_db_if_exists(chunk: str) -> Tuple[List[EntityModel], List[RelationshipModel], ChunkModel] | None:
35
+
36
+ db = next(get_db())
37
+ hash = "chunk-" + calculate_hash(text=chunk)
38
+ exists = db.query(Chunk).filter(Chunk.hash == hash).first()
39
+ if exists:
40
+ entities_models, relationships_models = [], []
41
+ entities = db.query(Entity).filter(Entity.chunk_id == exists.chunk_id).all()
42
+ for entity in entities:
43
+ entity_model = EntityModel(
44
+ entity_name=entity.entity_name,
45
+ entity_type=entity.entity_type,
46
+ entity_description=entity.description,
47
+ chunk_id=str(exists.chunk_id)
48
+ )
49
+ entities_models.append(entity_model)
50
+ relationships = db.query(Relationship).filter(Relationship.chunk_id == exists.chunk_id).all()
51
+ for rel in relationships:
52
+ rel_model = RelationshipModel(
53
+ source_entity=rel.source_entity.entity_name,
54
+ target_entity=rel.target_entity.entity_name,
55
+ relationship_description=rel.description,
56
+ relationship_strength=rel.weight,
57
+ chunk_id=str(exists.chunk_id),
58
+ relationship_keywords=rel.keywords
59
+ )
60
+ relationships_models.append(rel_model)
61
+ db.close()
62
+ return entities_models, relationships_models, ChunkModel(text=exists.text, id=str(exists.chunk_id))
63
+ db.close()
64
+ return None
65
+
66
+
67
+ def _merge_entities(entities: List[EntityModel], threshold: int=75) -> Tuple[List[EntityModel], Dict[str, Set[str]]]:
68
+
69
+ def find_most_similar(entity: EntityModel, candidates: List[EntityModel], threshold: int) -> List[EntityModel]:
70
+
71
+ most_sim_entity: List[EntityModel] = []
72
+ for candidate_entity in candidates:
73
+ if (entity.entity_type != candidate_entity.entity_type): continue
74
+ try:
75
+ score = fuzz.ratio(entity.entity_name, candidate_entity.entity_name)
76
+ except IndexError:
77
+ continue
78
+ if score > threshold:
79
+ most_sim_entity.append(candidate_entity)
80
+
81
+ return most_sim_entity
82
+
83
+ kept_vs_merged = {}
84
+
85
+ merged_entities = set()
86
+ modified_entities: Dict[Tuple[str, str, str, str], List[EntityModel]] = {}
87
+ for index, entity in enumerate(entities):
88
+ most_sim_entities = find_most_similar(entity=entity, candidates=entities[index+1:], threshold=threshold)
89
+ entity_key = (entity.entity_name, entity.entity_type, entity.entity_description)
90
+
91
+ if entity_key in merged_entities:
92
+ print(f"{entity_key} already exists as an entity")
93
+ continue
94
+
95
+ if (entity.entity_name, entity.entity_type, entity.entity_description, entity.get_chunk_id) not in modified_entities:
96
+ modified_entities[(entity.entity_name, entity.entity_type, entity.entity_description, entity.get_chunk_id)] = []
97
+ if most_sim_entities:
98
+ for most_sim_entity in most_sim_entities:
99
+ most_sim_key = (most_sim_entity.entity_name, most_sim_entity.entity_type, most_sim_entity.entity_description)
100
+ print(f"{most_sim_key[:2]} has been identified as similar to another entity")
101
+ merged_entities.add(most_sim_key)
102
+ modified_entities[(entity.entity_name, entity.entity_type, entity.entity_description, entity.get_chunk_id)].append(most_sim_entity)
103
+ if most_sim_entity.entity_name not in kept_vs_merged:
104
+ kept_vs_merged[most_sim_entity.entity_name] = {entity.entity_name}
105
+ else:
106
+ kept_vs_merged[most_sim_entity.entity_name].add(entity.entity_name)
107
+
108
+ updated_entities = []
109
+ for entity_info, sim_entities in modified_entities.items():
110
+
111
+ if entity_info[:-1] in merged_entities and not len(sim_entities): continue
112
+
113
+ updated_entities.append(
114
+ EntityModel(
115
+ entity_name=entity_info[0],
116
+ entity_type=entity_info[1],
117
+ entity_description=entity_info[2] + "\n".join([sim_entity.entity_description for sim_entity in sim_entities]),
118
+ chunk_id=set([entity_info[3]] + [sim_entity.get_chunk_id for sim_entity in sim_entities])
119
+ )
120
+ )
121
+
122
+ return updated_entities, kept_vs_merged
123
+
124
+
125
+ def _merge_relationships(
126
+ relationships: List[RelationshipModel], kept_vs_merged_entities: Dict[str, List[str]]
127
+ ) -> List[RelationshipModel]:
128
+
129
+ for relationship in relationships:
130
+ source, target = relationship.source_entity, relationship.target_entity
131
+ try:
132
+ if source in kept_vs_merged_entities:
133
+ relationship.source_entity = list(kept_vs_merged_entities[source])[0]
134
+ if target in kept_vs_merged_entities:
135
+ relationship.target_entity = list(kept_vs_merged_entities[target])[0]
136
+ except (KeyError, IndexError):
137
+ print(f"Something went wrong for edge: {(source, target)}")
138
+ continue
139
+
140
+
141
+ merged_relationships = {}
142
+ for relationship in relationships:
143
+ edge = (relationship.source_entity, relationship.target_entity)
144
+ if edge not in merged_relationships:
145
+ merged_relationships[edge] = relationship
146
+ continue
147
+ print(f"Edge: ({source}, {target}) already exists")
148
+ existing_edge = merged_relationships[edge]
149
+ existing_edge.relationship_description += "\n" + relationship.relationship_description
150
+ existing_edge.relationship_strength += relationship.relationship_strength
151
+ existing_edge.relationship_keywords += relationship.relationship_keywords
152
+ existing_edge.relationship_keywords = list(set(existing_edge.relationship_keywords))
153
+ existing_edge.update_chunk_ids(relationship.chunk_id)
154
+
155
+ return list(merged_relationships.values())
156
+
157
+
158
+ async def _extract_graph_information_from_chunk(chunk: str, entity_types: Dict[str, str], gleaning: int=1) -> Tuple[List[EntityModel], List[RelationshipModel], ChunkModel] | None:
159
+
160
+ already_exists = _extract_chunk_info_from_db_if_exists(chunk=chunk)
161
+ if already_exists is not None:
162
+ return already_exists
163
+ chunk_info: Dict[str, Any] = {}
164
+ for _ in range(gleaning):
165
+ gleaning_chunk_info = await extract_entities_completion(chunk=chunk,
166
+ history=None,
167
+ entity_types=entity_types)
168
+ if gleaning_chunk_info is None: continue
169
+
170
+ more_chunk_info = await extract_entities_completion(
171
+ chunk=chunk, history=str(chunk_info), entity_types=entity_types
172
+ )
173
+ if more_chunk_info is not None:
174
+ chunk_info.update(more_chunk_info)
175
+
176
+ chunk_model = ChunkModel(text=chunk, id=str(uuid.uuid4()))
177
+ try:
178
+ entities, relationships, high_level_keywords = [chunk_info[key] for key in ("entities", "relationships", "content_keywords")]
179
+ except KeyError as e:
180
+ print(f"KeyError -> {e}")
181
+ print(chunk_info)
182
+ raise e
183
+ if isinstance(high_level_keywords, list): high_level_keywords = {"content_keywords": high_level_keywords}
184
+ entities_models, relationships_models, high_level_keywords_models = [
185
+ [model(**val, chunk_id={chunk_model.id}) for val in values] if isinstance(values, list) else [model(**values, chunk_id={chunk_model.id})]
186
+ for model, values in zip((EntityModel, RelationshipModel, HighLevelKeywords),
187
+ (entities, relationships, high_level_keywords))
188
+ ]
189
+ return entities_models, relationships_models, chunk_model
190
+
191
+
192
+ async def extract_entities(chunks: List[str], entity_types: Dict[str, str], gleaning: int=1, batch: int=15) -> Tuple[List[EntityModel], List[RelationshipModel], Dict[str, Set[str]], List[ChunkModel]]:
193
+
194
+ if len(chunks) > batch:
195
+ results = []
196
+ for k in range(0, len(chunks), batch):
197
+ batch_chunks = chunks[k: k + batch]
198
+ try:
199
+ results.extend(
200
+ await asyncio.gather(*[
201
+ _extract_graph_information_from_chunk(chunk=chunk, gleaning=gleaning, entity_types=entity_types) for chunk in batch_chunks
202
+ ])
203
+ )
204
+ except RateLimitError:
205
+ print("Rate limit error. Sleeping for a few seconds...")
206
+ await asyncio.sleep(2)
207
+ sub_batch = batch // 2
208
+ for j in range(0, len(batch_chunks), sub_batch):
209
+ results.extend(
210
+ await asyncio.gather(*[
211
+ _extract_graph_information_from_chunk(chunk=chunk, gleaning=gleaning, entity_types=entity_types) for chunk in batch_chunks[j: j + sub_batch]
212
+ ])
213
+ )
214
+ await asyncio.sleep(1)
215
+ await asyncio.sleep(1)
216
+ else:
217
+ results = await asyncio.gather(*[
218
+ _extract_graph_information_from_chunk(chunk=chunk, gleaning=gleaning, entity_types=entity_types) for chunk in chunks
219
+ ])
220
+
221
+ if results is None:
222
+ return None
223
+
224
+ entities, relationships, chunks_models = [], [], []
225
+
226
+ for result in results:
227
+ if result is None:
228
+ continue
229
+ entities_n, relationships_n, chunk = result
230
+ entities.extend(entities_n)
231
+ relationships.extend(relationships_n)
232
+ chunks_models.append(chunk)
233
+
234
+ entities, kept_vs_merged = _merge_entities(entities=entities)
235
+ relationships = _merge_relationships(relationships=relationships, kept_vs_merged_entities=kept_vs_merged)
236
+
237
+ return entities, relationships, kept_vs_merged, chunks_models
@@ -1,34 +1,34 @@
1
- from graphrag.indexing import (create_chunks,
2
- upsert_data_and_create_graph,
3
- extract_entities)
4
- from graphrag.query.generate import _local_query, _global_query, _hybrid_query, _naive_rag
5
-
6
- from graphrag.config import GlobalConfig
7
- from typing import List, Dict, Tuple, Any, Set
8
-
9
- import networkx as nx
10
-
11
-
12
- async def insert(text: str, config: GlobalConfig) -> nx.Graph:
13
- chunks = await create_chunks(text=text,
14
- min_token_size=config.min_chunk_size,
15
- max_token_size=config.max_chunk_size)
16
- print(f"{len(chunks)} chunks created")
17
- entities, relationships, kept_vs_merged, chunk_models = await extract_entities(chunks=chunks, entity_types=config.entity_types, gleaning=config.max_gleaning, batch=config.batch)
18
- print(f"{len(entities)} entities extracted and {len(relationships)} relationships extracted. ")
19
- graph = await upsert_data_and_create_graph(entities=entities, relationships=relationships, chunks=chunk_models)
20
- return graph
21
-
22
- async def local_query(query: str, config: GlobalConfig) -> Tuple[str | None, List[str], Dict[str, Dict[str, Any]], List[str]]:
23
- response, chunk_texts, nodes, keywords = await _local_query(query=query, top_k=config.keywords_top_k, max_nodes=config.graph_top_k, order_range=config.order_range)
24
- return response, chunk_texts, nodes, keywords
25
-
26
- async def global_query(query: str, config: GlobalConfig) -> Tuple[str | None, List[str], Dict[str, Any], List[str]]:
27
- response, chunk_texts, chunks, keywords = await _global_query(query=query, top_k=config.keywords_top_k, max_nodes=config.graph_top_k, alpha=config.alpha)
28
- return response, chunk_texts, chunks, keywords
29
-
30
- async def hybrid_query(query: str, config: GlobalConfig) -> Tuple[str | None, List[str], Tuple[Dict[str, Any], Dict[str, Dict[str, Any]]], Set[str]]:
31
- return await _hybrid_query(query=query, top_k=config.keywords_top_k, max_nodes=config.graph_top_k, alpha=config.alpha, order_range=config.order_range)
32
-
33
- async def naive_query(query: str, config: GlobalConfig) -> Tuple[str, List[str]]:
34
- return await _naive_rag(query=query, top_k=config.graph_top_k)
1
+ from .indexing import (create_chunks,
2
+ upsert_data_and_create_graph,
3
+ extract_entities)
4
+ from .query.generate import _local_query, _global_query, _hybrid_query, _naive_rag
5
+
6
+ from .config import GlobalConfig
7
+ from typing import List, Dict, Tuple, Any, Set
8
+
9
+ import networkx as nx
10
+
11
+
12
+ async def insert(text: str, config: GlobalConfig) -> nx.Graph:
13
+ chunks = await create_chunks(text=text,
14
+ min_token_size=config.min_chunk_size,
15
+ max_token_size=config.max_chunk_size)
16
+ print(f"{len(chunks)} chunks created")
17
+ entities, relationships, kept_vs_merged, chunk_models = await extract_entities(chunks=chunks, entity_types=config.entity_types, gleaning=config.max_gleaning, batch=config.batch)
18
+ print(f"{len(entities)} entities extracted and {len(relationships)} relationships extracted. ")
19
+ graph = await upsert_data_and_create_graph(entities=entities, relationships=relationships, chunks=chunk_models)
20
+ return graph
21
+
22
+ async def local_query(query: str, config: GlobalConfig) -> Tuple[str | None, List[str], Dict[str, Dict[str, Any]], List[str]]:
23
+ response, chunk_texts, nodes, keywords = await _local_query(query=query, top_k=config.keywords_top_k, max_nodes=config.graph_top_k, order_range=config.order_range)
24
+ return response, chunk_texts, nodes, keywords
25
+
26
+ async def global_query(query: str, config: GlobalConfig) -> Tuple[str | None, List[str], Dict[str, Any], List[str]]:
27
+ response, chunk_texts, chunks, keywords = await _global_query(query=query, top_k=config.keywords_top_k, max_nodes=config.graph_top_k, alpha=config.alpha)
28
+ return response, chunk_texts, chunks, keywords
29
+
30
+ async def hybrid_query(query: str, config: GlobalConfig) -> Tuple[str | None, List[str], Tuple[Dict[str, Any], Dict[str, Dict[str, Any]]], Set[str]]:
31
+ return await _hybrid_query(query=query, top_k=config.keywords_top_k, max_nodes=config.graph_top_k, alpha=config.alpha, order_range=config.order_range)
32
+
33
+ async def naive_query(query: str, config: GlobalConfig) -> Tuple[str, List[str]]:
34
+ return await _naive_rag(query=query, top_k=config.graph_top_k)