mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-09-22 00:32:49 +00:00
up
This commit is contained in:
parent
d0aae68164
commit
cca6cce0e0
5 changed files with 22 additions and 46 deletions
|
|
@ -15,9 +15,7 @@ Contract — six abstract methods, two blocks:
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from abc import abstractmethod
|
||||
from collections.abc import AsyncIterator
|
||||
from pathlib import Path
|
||||
|
||||
from ..base_component import BaseComponent
|
||||
|
|
@ -30,16 +28,11 @@ class BaseFileGraph(BaseComponent):
|
|||
|
||||
component_type = ComponentEnum.FILE_GRAPH
|
||||
|
||||
def __init__(self, store_name: str = "default", **kwargs):
|
||||
def __init__(self, graph_name: str = "default", **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
if not re.match(r"^[a-zA-Z0-9_]+$", store_name):
|
||||
raise ValueError(
|
||||
f"Invalid store name '{store_name}'. " f"Only alphanumeric and underscores allowed.",
|
||||
)
|
||||
self.store_name: str = store_name
|
||||
self.working_dir: str = self.app_context.app_config.working_dir if self.app_context else ""
|
||||
self.store_path: Path = Path(self.working_dir) / "file_graph" / store_name
|
||||
self.store_path.mkdir(parents=True, exist_ok=True)
|
||||
self.graph_name: str = graph_name or self.name
|
||||
self.graph_path: Path = self.working_path / self.component_type.value / graph_name
|
||||
self.graph_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# -- Node CRUD ---------------------------------------------------------
|
||||
|
||||
|
|
@ -58,15 +51,9 @@ class BaseFileGraph(BaseComponent):
|
|||
# -- Link access -------------------------------------------------------
|
||||
|
||||
@abstractmethod
|
||||
async def get_outlinks(
|
||||
self,
|
||||
path: str,
|
||||
) -> list[tuple[FileNode, FileLink]]:
|
||||
async def get_outlinks(self, path: str) -> list[FileLink]:
|
||||
"""Resolved outgoing links from ``path``."""
|
||||
|
||||
@abstractmethod
|
||||
async def get_inlinks(
|
||||
self,
|
||||
path: str,
|
||||
) -> list[tuple[FileNode, FileLink]]:
|
||||
async def get_inlinks(self, path: str) -> list[FileLink]:
|
||||
"""Resolved incoming links to ``path``."""
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ from pathlib import Path
|
|||
from .base_file_graph import BaseFileGraph
|
||||
from ..component_registry import R
|
||||
from ...schema import FileLink, FileNode
|
||||
|
||||
import networkx as nx
|
||||
|
||||
@R.register("local")
|
||||
class LocalFileGraph(BaseFileGraph):
|
||||
|
|
@ -35,21 +35,15 @@ class LocalFileGraph(BaseFileGraph):
|
|||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self._graph = None # networkx.MultiDiGraph; set in _start
|
||||
self._graph_file: Path = self.store_path / "graph.pkl"
|
||||
self._graph_file: Path = self.graph_path / f"{self.graph_name}.pkl"
|
||||
|
||||
# -- Lifecycle ---------------------------------------------------------
|
||||
|
||||
async def _start(self) -> None:
|
||||
await super()._start()
|
||||
try:
|
||||
import networkx as nx
|
||||
except ImportError as e:
|
||||
raise ImportError(
|
||||
"LocalFileGraph requires networkx. Install with `pip install networkx`.",
|
||||
) from e
|
||||
self._graph = self._load_graph(nx) or nx.MultiDiGraph()
|
||||
self.logger.info(
|
||||
f"LocalFileGraph '{self.store_name}' ready: "
|
||||
f"LocalFileGraph '{self.graph_name}' ready: "
|
||||
f"{self._graph.number_of_nodes()} nodes, "
|
||||
f"{self._graph.number_of_edges()} edges",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class Neo4jFileGraph(BaseFileGraph):
|
|||
"CREATE CONSTRAINT file_path_unique IF NOT EXISTS " "FOR (f:File) REQUIRE f.path IS UNIQUE",
|
||||
)
|
||||
self.logger.info(
|
||||
f"Neo4jFileGraph '{self.store_name}' connected at " f"{self._uri}/{self._database}",
|
||||
f"Neo4jFileGraph '{self.graph_name}' connected at " f"{self._uri}/{self._database}",
|
||||
)
|
||||
|
||||
async def _close(self) -> None:
|
||||
|
|
|
|||
|
|
@ -577,9 +577,8 @@ class LinkedFileParser(BaseFileParser):
|
|||
when ``embed_toc``, otherwise just ``content``."""
|
||||
text = _toc_join(before, content, after) if self.embed_toc else content
|
||||
return FileChunk(
|
||||
id=hash_text(text),
|
||||
path=path,
|
||||
start_line=start_line,
|
||||
end_line=end_line,
|
||||
text=text,
|
||||
)
|
||||
).set_hash_id()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import re
|
||||
from abc import abstractmethod
|
||||
|
||||
from ..base_component import BaseComponent
|
||||
|
|
@ -12,15 +11,13 @@ class BaseFileStore(BaseComponent):
|
|||
component_type = ComponentEnum.FILE_STORE
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
store_name: str,
|
||||
embedding_model: str = "default",
|
||||
keyword_index: str = "default",
|
||||
**kwargs,
|
||||
self,
|
||||
store_name: str,
|
||||
embedding_model: str = "default",
|
||||
keyword_index: str = "default",
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(**kwargs)
|
||||
if not re.match(r"^[a-zA-Z0-9_]+$", store_name):
|
||||
raise ValueError(f"Invalid store name '{store_name}'. Only alphanumeric and underscores allowed.")
|
||||
self.store_name = store_name or self.name
|
||||
self._embedding_model_name = embedding_model
|
||||
self._keyword_index_name = keyword_index
|
||||
|
|
@ -46,13 +43,15 @@ class BaseFileStore(BaseComponent):
|
|||
self.keyword_index = None
|
||||
await self.dump_file_nodes()
|
||||
|
||||
async def load_file_nodes(self): ...
|
||||
async def load_file_nodes(self):
|
||||
...
|
||||
|
||||
async def dump_file_nodes(self): ...
|
||||
async def dump_file_nodes(self):
|
||||
...
|
||||
|
||||
async def upsert_file(
|
||||
self,
|
||||
file: tuple[FileNode, list[FileChunk]] | list[tuple[FileNode, list[FileChunk]]],
|
||||
self,
|
||||
file: tuple[FileNode, list[FileChunk]] | list[tuple[FileNode, list[FileChunk]]],
|
||||
) -> None:
|
||||
"""Upsert a file and its chunks into the store."""
|
||||
|
||||
|
|
@ -69,6 +68,3 @@ class BaseFileStore(BaseComponent):
|
|||
@abstractmethod
|
||||
async def keyword_search(self, query: str, limit: int, search_filter: dict) -> list[FileChunk]:
|
||||
"""Perform full-text keyword search."""
|
||||
|
||||
async def graph_search(self, query: str, limit: int, search_filter: dict) -> list[FileChunk] | None:
|
||||
"""Perform graph search."""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue