chat-agent/tools
The tools package defines the function schemas exposed to the LLM during the agentic loop and the Python functions that execute them.
The agent has access to 8 tools across three categories: retrieval, graph query, and schema exploration.
Tool registry
tools/__init__.py exports two objects consumed by agent_handler:
TOOLS # list of OpenAI-compatible function schema dicts (sent to the LLM)
TOOL_MAP # dict mapping tool name → async Python function
Retrieval tools
get_graph_overview
Returns a compact structural map of the graph: node types with their counts and their top relationships. Use this for a quick overview before planning queries — cheaper than calling all schema tools individually.
Schema:
{
"name": "get_graph_overview",
"description": "Returns a compact overview of the graph: node types with counts and their top relationships.",
"parameters": {}
}
Implementation (tools/graph_overview.py): thin wrapper around agentlib.graph.context.load_or_build_context(), which returns the cached skeleton generated at server startup.
vector_search
Semantic similarity search over the knowledge graph. Embeds the query and returns the top-k nodes whose text property is closest in vector space.
Schema:
{
"name": "vector_search",
"description": "Semantic search over the knowledge base. Use for factual lookup.",
"parameters": {
"query": { "type": "string" },
"top_k": { "type": "integer", "default": 5 }
},
"required": ["query"]
}
Implementation (tools/vector_search.py):
- Creates a
TuringDBclient and sets the active graph. - Embeds
queryusingagentlib.rag.embeddings.make_handler(). - Calls
VectorIndexManager.vector_search()and returns results aslist[dict].
Results from all vector_search calls during an agent loop are collected into the sources list on the final response.
graph_query
Executes a raw Cypher query against TuringDB. Used for structured graph traversal, filtering across multiple criteria, and aggregations that vector search cannot handle.
Schema:
{
"name": "graph_query",
"description": "Execute a TuringDB Cypher query for structured graph traversal or aggregation.",
"parameters": {
"cypher": { "type": "string" }
},
"required": ["cypher"]
}
Implementation (tools/query_graph.py): thin wrapper around agentlib.graph.query.run_graph_query(). See agentlib/graph for full query semantics.
Return value: list[dict] — one dict per result row, column names matching the RETURN aliases.
TuringDB Cypher deviations
TuringDB uses a Cypher subset. The agent system prompt includes these rules; they are repeated here as a reference.
| Standard Cypher | TuringDB |
|---|---|
RETURN n (full node) | Returns internal node ID only — use RETURN n.property |
labels(n) anywhere | Supported in RETURN only, not in WHERE |
type(r) | Use edgeType(r) |
WITH | Not supported |
CONTAINS | Not supported |
DISTINCT | Not supported |
GROUP BY | Not supported |
Arithmetic in WHERE | Not supported — use in RETURN only |
WHERE x IN [...] | Not supported |
Schema exploration tools
These tools let the LLM iteratively discover the graph structure before writing a graph_query. They are thin wrappers around agentlib.graph.schema functions, which call TuringDB procedures directly.
The agent is instructed to call schema tools one at a time as needed, rather than fetching the full schema upfront.
get_node_labels
Returns all node label types in the graph.
{ "name": "get_node_labels", "parameters": {} }
Calls CALL db.labels(). Returns list[str].
get_edge_types
Returns all edge (relationship) types in the graph.
{ "name": "get_edge_types", "parameters": {} }
Calls CALL db.edgeTypes(). Returns list[str].
get_node_label_counts
Returns each node label with its total node count. Useful for gauging graph size and node type distribution before designing a query.
{ "name": "get_node_label_counts", "parameters": {} }
Calls CALL db.labels() then issues MATCH (n:{label}) RETURN count(n) per label. Returns list[dict] with keys label and count.
get_edge_type_counts
Returns each edge type with its total edge count. Useful for gauging relationship density before designing a query.
{ "name": "get_edge_type_counts", "parameters": {} }
Calls CALL db.edgeTypes() then issues MATCH ()-[e:{type}]->() RETURN count(e) per type. Returns list[dict] with keys edge_type and count.
get_property_types
Returns all property names and their types across nodes and edges.
{ "name": "get_property_types", "parameters": {} }
Calls CALL db.propertyTypes(). Returns list[dict].
Recommended LLM strategy
The agent system prompt guides the LLM to use tools in this order:
- Check the graph skeleton (injected at startup) for a structural overview.
- Call
get_node_labelsorget_edge_typesif the skeleton does not cover what is needed. - Call
get_node_label_countsorget_edge_type_countsto understand size and density. - Call
get_property_typesto discover available properties for a specific query. - Call
graph_querywith a well-formed TuringDB Cypher query. - Call
vector_searchfor free-text or semantic lookups.
Adding a new tool
- Create
tools/my_tool.pywith anasync def tool_my_tool(...) -> list[dict]function. - Add the OpenAI function schema dict to the
TOOLSlist intools/__init__.py. - Add
"my_tool": tool_my_tooltoTOOL_MAP.
The agent handler dispatches to TOOL_MAP by name — no other changes needed.