Navegador

API Graph

3 days, 13 hours ago by admin

Graph API

from navegador.graph import GraphStore
from navegador.context import ContextLoader, ContextBundle, ContextNode

GraphStore

The database abstraction layer. Both SQLite and Redis backends implement this interface.

class GraphStore:
    @classmethod
    def sqlite(cls, path: str | Path = "navegador.db") -> "GraphStore": ...

    @classmethod
    def redis(cls, url: str = "redis://localhost:6379") -> "GraphStore": ...

    def query(
        self,
        cypher: str,
        params: dict | None = None,
    ) -> list[dict]: ...

    def create_node(
        self,
        label: str,
        properties: dict,
    ) -> str: ...  # returns node ID

    def merge_node(
        self,
        label: str,
        match_properties: dict,
        set_properties: dict | None = None,
    ) -> str: ...  # upsert by match_properties, returns node ID

    def create_edge(
        self,
        from_id: str,
        to_id: str,
        edge_type: str,
        properties: dict | None = None,
    ) -> None: ...

    def merge_edge(
        self,
        from_label: str,
        from_match: dict,
        to_label: str,
        to_match: dict,
        edge_type: str,
        properties: dict | None = None,
    ) -> None: ...

    def clear(self) -> None: ...

    def close(self) -> None: ...

Usage

# SQLite (local dev)
store = GraphStore.sqlite(".navegador/navegador.db")

# Redis (production)
store = GraphStore.redis("redis://localhost:6379")

# raw Cypher query
results = store.query(
    "MATCH (f:Function {name: $name}) RETURN f",
    params={"name": "validate_token"}
)

# create a node
node_id = store.create_node("Concept", {
    "name": "Idempotency",
    "description": "Operations safe to retry"
})

# upsert a node (match by name, update description)
node_id = store.merge_node(
    "Concept",
    match_properties={"name": "Idempotency"},
    set_properties={"description": "Updated description"}
)

# create an edge
store.create_edge(from_id, to_id, "ANNOTATES")

# wipe the graph
store.clear()

Context manager

GraphStore implements the context manager protocol:

with GraphStore.sqlite(".navegador/navegador.db") as store:
    results = store.query("MATCH (n) RETURN count(n) AS total")

ContextLoader

Builds structured context bundles from graph queries. Each method corresponds to a CLI command.

class ContextLoader:
    def __init__(self, store: GraphStore) -> None: ...

    def load_file(self, path: str) -> ContextBundle: ...

    def load_function(
        self,
        name: str,
        *,
        file: str = "",
        depth: int = 1,
    ) -> ContextBundle: ...

    def load_class(
        self,
        name: str,
        *,
        file: str = "",
    ) -> ContextBundle: ...

    def explain(
        self,
        name: str,
        *,
        file: str = "",
    ) -> ContextBundle: ...

    def load_concept(self, name: str) -> ContextBundle: ...

    def load_domain(self, name: str) -> ContextBundle: ...

    def search(
        self,
        query: str,
        *,
        all_layers: bool = False,
        docs_only: bool = False,
        limit: int = 20,
    ) -> list[ContextNode]: ...

    def search_by_docstring(
        self,
        query: str,
        *,
        limit: int = 20,
    ) -> list[ContextNode]: ...

    def decorated_by(
        self,
        decorator: str,
    ) -> list[ContextNode]: ...

Usage

store = GraphStore.sqlite(".navegador/navegador.db")
loader = ContextLoader(store)

# file context
bundle = loader.load_file("src/auth/service.py")

# function with 2-hop call graph
bundle = loader.load_function("validate_token", depth=2)

# class hierarchy
bundle = loader.load_class("PaymentProcessor", file="src/payments/processor.py")

# universal explain
bundle = loader.explain("AuthService")

# concept with annotated code
bundle = loader.load_concept("Idempotency")

# domain overview
bundle = loader.load_domain("Payments")

# search
nodes = loader.search("rate limit", all_layers=True, limit=10)

# all @login_required functions
nodes = loader.decorated_by("login_required")

ContextBundle

The structured result type returned by ContextLoader methods.

@dataclass
class ContextBundle:
    root: ContextNode
    nodes: list[ContextNode]
    edges: list[ContextEdge]
    metadata: dict

    def to_json(self) -> str: ...
    def to_markdown(self) -> str: ...
    def to_dict(self) -> dict: ...

ContextNode

A single node in a context bundle.

@dataclass
class ContextNode:
    id: str
    label: str           # e.g. "Function", "Concept"
    name: str
    properties: dict     # all node properties
    layer: str           # "code" or "knowledge"

ContextEdge

@dataclass
class ContextEdge:
    from_id: str
    to_id: str
    edge_type: str       # e.g. "CALLS", "ANNOTATES"
    properties: dict

Formatting output

bundle = loader.load_function("validate_token")

# JSON string
print(bundle.to_json())

# Markdown string (for agent consumption)
print(bundle.to_markdown())

# Python dict (for further processing)
data = bundle.to_dict()

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button