Skip to content

Commit e960c5b

Browse files
authored
Merge pull request #7 from TigerGraph-DevLabs/feature/ai_agent
feat: add example using LangGraph LLM and agents to call TigerGraph-MCP
2 parents 489a272 + b6d6c24 commit e960c5b

37 files changed

+1378
-204
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Changelog
22

33
---
4+
### 0.1.5
5+
- feat: add example using LangGraph LLM and agents to call TigerGraph-MCP
6+
- feat: upgrade TigerGraphX to v0.2.9 with new TigerGraphDatabase class integration
7+
- feat: add run algorithm subgraph to onboarding workflow
8+
- feat: add MCP tools for update data source, get/drop all data sources, run gsql, and list metadata
9+
410
### 0.1.4
511
- feat: enable multi-turn human-in-the-loop schema confirmation for iterative refinement
612
- feat: enable multi-turn human-in-the-loop loading job confirmation for iterative refinement

examples/chatbot_langgraph/prompts/__init__.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .planner import ONBOARDING_DETECTOR_PROMPT
2+
from .task_flow import PLAN_TOOL_EXECUTION_PROMPT
23
from .onboarding import PREVIEW_SAMPLE_DATA_PROMPT
34
from .schema import (
45
CLASSIFY_COLUMNS_PROMPT,
@@ -14,12 +15,18 @@
1415
EDIT_LOADING_JOB_PROMPT,
1516
RUN_LOADING_JOB_PROMPT,
1617
)
18+
from .algorithms import (
19+
SUGGEST_ALGORITHMS_PROMPT,
20+
EDIT_ALGORITHM_SELECTION_PROMPT,
21+
RUN_ALGORITHMS_PROMPT,
22+
)
1723

1824
__all__ = [
1925
"ONBOARDING_DETECTOR_PROMPT",
26+
"PLAN_TOOL_EXECUTION_PROMPT",
2027
"PREVIEW_SAMPLE_DATA_PROMPT",
21-
"CLASSIFY_COLUMNS_PROMPT",
2228
# Schema
29+
"CLASSIFY_COLUMNS_PROMPT",
2330
"DRAFT_SCHEMA_PROMPT",
2431
"EDIT_SCHEMA_PROMPT",
2532
"CREATE_SCHEMA_PROMPT",
@@ -30,4 +37,8 @@
3037
"LOAD_CONFIG_EDGE_MAPPING_PROMPT",
3138
"EDIT_LOADING_JOB_PROMPT",
3239
"RUN_LOADING_JOB_PROMPT",
40+
# Algorithms
41+
"SUGGEST_ALGORITHMS_PROMPT",
42+
"EDIT_ALGORITHM_SELECTION_PROMPT",
43+
"RUN_ALGORITHMS_PROMPT",
3344
]
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
from .queries import WCC_QUERY, PAGERANK_QUERY
2+
3+
SUGGEST_ALGORITHMS_PROMPT = """
4+
## Objective
5+
6+
Suggest suitable graph algorithms for the user to run, based on the current TigerGraph schema. Provide a brief explanation of each algorithm’s purpose and when it is applicable.
7+
8+
## Instructions
9+
10+
1. **Inspect the graph schema**:
11+
- Identify all edge types along with their direction (directed or undirected) and source/target vertex types.
12+
13+
2. **Suggest WCC (Weakly Connected Components)** if:
14+
- The schema contains at least one undirected edge type.
15+
- Do not suggest WCC if all edges are directed.
16+
17+
3. **Suggest PageRank** if:
18+
- There is at least one directed edge type where the source and target node types are the same.
19+
- Do not suggest PageRank if such edges are not found.
20+
21+
4. Do **not** mention any algorithm that is not applicable. Only include suggested algorithms.
22+
23+
5. For each suggested algorithm, include:
24+
- The algorithm name
25+
- A short, user-friendly explanation of what it does
26+
- The kind of insight or output the user might expect
27+
28+
6. If no algorithms are applicable, reply with a short explanation that nothing is recommended based on current schema.
29+
30+
7. End the message by asking the user to confirm if the suggested algorithms look good, or if they want to revise.
31+
32+
## Output Format
33+
34+
Respond in natural language. Examples:
35+
36+
**If both algorithms are suggested:**
37+
```
38+
39+
Based on your graph structure, I suggest the following algorithms:
40+
41+
✅ **WCC (Weakly Connected Components)**
42+
Helps identify clusters of interconnected nodes based on undirected edges. Useful for finding isolated communities or disconnected parts of your graph.
43+
44+
✅ **PageRank**
45+
Ranks nodes by importance using link structure. Commonly used to find influential or highly connected nodes in a network.
46+
47+
Please confirm if this looks good by replying with "confirmed", "approved", "go ahead", or "ok". Or let me know if you'd like to revise anything.
48+
49+
```
50+
51+
**If only one algorithm is suggested (e.g., WCC):**
52+
```
53+
54+
Based on your graph structure, I suggest the following algorithm:
55+
56+
✅ **WCC (Weakly Connected Components)**
57+
Helps identify clusters of interconnected nodes based on undirected edges. Useful for finding isolated communities or disconnected parts of your graph.
58+
59+
Please confirm if this looks good by replying with "confirmed", "approved", "go ahead", or "ok". Or let me know if you'd like to revise anything.
60+
61+
```
62+
63+
**If no algorithms are applicable:**
64+
```
65+
66+
There are currently no suitable algorithms to run based on the structure of your graph.
67+
68+
Please confirm if this looks good by replying with "confirmed", "approved", "go ahead", or "ok". Or let me know if you'd like to revise anything.
69+
70+
```
71+
"""
72+
EDIT_ALGORITHM_SELECTION_PROMPT = """
73+
## Objective
74+
75+
Revise the algorithm selections (WCC and PageRank) based on the user's feedback and confirm the updated choices.
76+
77+
## Instructions
78+
79+
- First, interpret the user's latest input to adjust the algorithm selection.
80+
- If the feedback clearly includes or excludes WCC and/or PageRank, update the selection accordingly.
81+
- If the feedback is ambiguous, incomplete, or includes unsupported algorithms, politely explain that only WCC and PageRank are currently supported.
82+
- Show the updated selection to the user.
83+
- Ask for final confirmation using accepted phrases: "confirmed", "approved", "go ahead", or "ok".
84+
85+
## Output Format
86+
87+
Summarize the final selection for confirmation:
88+
89+
```
90+
91+
Here’s your current selection:
92+
93+
✅ WCC: Yes / No
94+
✅ PageRank: Yes / No
95+
96+
Please confirm to proceed by replying with "confirmed", "approved", "go ahead", or "ok". Or let me know if you'd like to revise anything.
97+
98+
```
99+
"""
100+
101+
RUN_ALGORITHMS_PROMPT = f"""
102+
## Objective
103+
104+
Create, install, and run the selected graph algorithms (WCC and/or PageRank) on the current schema.
105+
106+
## Instructions
107+
108+
1. If no algorithms are selected, do not run any queries.
109+
Simply return:
110+
"No algorithms were selected. Onboarding is now complete."
111+
112+
2. For each selected algorithm, perform the following steps using tool calls:
113+
- Use `CREATE_QUERY` with the corresponding GSQL code below.
114+
- Use `INSTALL_QUERY` to install the query.
115+
- Use `RUN_QUERY` with the appropriate parameters.
116+
117+
---
118+
119+
### WCC (tg_wcc)
120+
121+
- Only run if the user has confirmed.
122+
- Parameters:
123+
- `e_type_set`: all undirected edge types
124+
- `v_type_set`: all node types connected by undirected edges
125+
- `print_limit`: -1
126+
- All other parameters should use default values.
127+
- Expected output: number of connected components.
128+
129+
**GSQL Code:**
130+
```
131+
132+
{WCC_QUERY}
133+
134+
```
135+
136+
---
137+
138+
### PageRank (tg_pagerank)
139+
140+
- Only run if the user has confirmed.
141+
- Only run if there exists a valid (`v_type`, `e_type`) pair such that:
142+
- `e_type` is a directed edge.
143+
- Both the source and target types of `e_type` are the same and equal to `v_type`.
144+
- Parameters:
145+
- `v_type`: node type connected by `e_type`
146+
- `e_type`: directed edge type whose source and target types are both `v_type`
147+
- All other parameters should use default values.
148+
- Expected output: comprehensive ranking details from `pagerank_top_nodes`.
149+
150+
**GSQL Code:**
151+
```
152+
153+
{PAGERANK_QUERY}
154+
155+
```
156+
157+
## Output Format
158+
159+
```
160+
161+
✅ WCC completed. Top connected components:
162+
163+
✅ PageRank completed. Top-ranked nodes:
164+
165+
✅ All selected algorithms have completed. Onboarding is now complete.
166+
167+
```
168+
"""
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from .pagerank_query import PAGERANK_QUERY
2+
from .wcc_query import WCC_QUERY
3+
4+
__all__ = [
5+
"PAGERANK_QUERY",
6+
"WCC_QUERY",
7+
]
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
PAGERANK_QUERY = """
2+
CREATE OR REPLACE DISTRIBUTED QUERY tg_pagerank (STRING v_type, STRING e_type,
3+
FLOAT max_change=0.001, INT maximum_iteration=25, FLOAT damping=0.85, INT top_k = 100,
4+
BOOL print_results = TRUE, STRING result_attribute = "", STRING file_path = "",
5+
BOOL display_edges = FALSE) SYNTAX V1 {
6+
7+
TYPEDEF TUPLE<VERTEX Vertex_ID, FLOAT score> Vertex_Score;
8+
HeapAccum<Vertex_Score>(top_k, score DESC) @@top_scores_heap;
9+
SetAccum<VERTEX> @@top_vertices; # vertices with top score
10+
MaxAccum<FLOAT> @@max_diff = 9999; # max score change in an iteration
11+
SumAccum<FLOAT> @sum_recvd_score = 0; # sum of scores each vertex receives FROM neighbors
12+
SumAccum<FLOAT> @sum_score = 1; # initial score for every vertex is 1.
13+
SetAccum<EDGE> @@edge_set; # list of all edges, if display is needed
14+
FILE f (file_path);
15+
16+
# PageRank iterations
17+
Start = {v_type}; # Start with all vertices of specified type(s)
18+
WHILE @@max_diff > max_change
19+
LIMIT maximum_iteration DO
20+
@@max_diff = 0;
21+
V = SELECT s
22+
FROM Start:s -(e_type:e)- v_type:t
23+
ACCUM
24+
t.@sum_recvd_score += s.@sum_score/(s.outdegree(e_type))
25+
POST-ACCUM
26+
s.@sum_score = (1.0-damping) + damping * s.@sum_recvd_score,
27+
s.@sum_recvd_score = 0,
28+
@@max_diff += abs(s.@sum_score - s.@sum_score');
29+
END; # END WHILE loop
30+
31+
# Output
32+
IF file_path != "" THEN
33+
f.println("Vertex_ID", "PageRank");
34+
END;
35+
V = SELECT s
36+
FROM Start:s
37+
POST-ACCUM
38+
IF result_attribute != "" THEN
39+
s.setAttr(result_attribute, s.@sum_score)
40+
END,
41+
IF file_path != "" THEN
42+
f.println(s, s.@sum_score)
43+
END,
44+
IF print_results THEN
45+
@@top_scores_heap += Vertex_Score(s, s.@sum_score)
46+
END;
47+
IF print_results THEN
48+
PRINT @@top_scores_heap AS pagerank_top_nodes;
49+
IF display_edges THEN
50+
FOREACH vert IN @@top_scores_heap DO
51+
@@top_vertices += vert.Vertex_ID;
52+
END;
53+
Top = {@@top_vertices};
54+
Top = SELECT s
55+
FROM Top:s -(e_type:e)- v_type:t
56+
WHERE @@top_vertices.contains(t)
57+
ACCUM @@edge_set += e;
58+
PRINT Top;
59+
END;
60+
END;
61+
}
62+
"""
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
WCC_QUERY = """
2+
CREATE OR REPLACE DISTRIBUTED QUERY tg_wcc (SET<STRING> v_type_set, SET<STRING> e_type_set, INT print_limit = 100,
3+
BOOL print_results = TRUE, STRING result_attribute = "", STRING file_path = "") SYNTAX V1 {
4+
/*
5+
This query identifies the Connected Components (undirected edges). When finished, each
6+
vertex is assigned an INT label = its component ID number.
7+
v_type_set: vertex types to traverse print_results: print JSON output
8+
e_type_set: edge types to traverse result_attribute: INT attribute to store results to
9+
file_path: file to write CSV output to display_edges: output edges for visualization
10+
print_limit: max #vertices to output (-1 = all)
11+
*/
12+
13+
MinAccum<INT> @min_cc_id = 0; //each vertex's tentative component id
14+
MapAccum<INT, INT> @@comp_sizes_map;
15+
MapAccum<INT, ListAccum<INT>> @@comp_group_by_size_map;
16+
FILE f(file_path);
17+
18+
Start = {v_type_set};
19+
20+
# Initialize: Label each vertex with its own internal ID
21+
S = SELECT x
22+
FROM Start:x
23+
POST-ACCUM x.@min_cc_id = getvid(x);
24+
25+
# Propagate smaller internal IDs until no more ID changes can be Done
26+
WHILE (S.size()>0) DO
27+
S = SELECT t
28+
FROM S:s -(e_type_set:e)- v_type_set:t
29+
ACCUM t.@min_cc_id += s.@min_cc_id // If s has smaller id than t, copy the id to t
30+
HAVING t.@min_cc_id != t.@min_cc_id';
31+
END;
32+
IF file_path != "" THEN
33+
f.println("Vertex_ID","Component_ID");
34+
END;
35+
36+
Start = {v_type_set};
37+
Start = SELECT s
38+
FROM Start:s
39+
POST-ACCUM
40+
IF result_attribute != "" THEN
41+
s.setAttr(result_attribute, s.@min_cc_id)
42+
END,
43+
IF print_results THEN
44+
@@comp_sizes_map += (s.@min_cc_id -> 1)
45+
END,
46+
IF file_path != "" THEN
47+
f.println(s, s.@min_cc_id)
48+
END;
49+
50+
IF print_results THEN
51+
IF print_limit >= 0 THEN
52+
Start = SELECT s
53+
FROM Start:s
54+
LIMIT print_limit;
55+
END;
56+
FOREACH (compId,size) IN @@comp_sizes_map DO
57+
@@comp_group_by_size_map += (size -> compId);
58+
END;
59+
PRINT @@comp_group_by_size_map.size() AS number_of_connected_components;
60+
END;
61+
}
62+
"""
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
PLAN_TOOL_EXECUTION_PROMPT = """
2+
## Role
3+
You are a helpful assistant that uses TigerGraph-MCP tools and flows to fulfill user requests.
4+
5+
## Objective
6+
Understand the user's request and determine whether any tools need to be executed to fulfill it. If all required tool calls have already been completed, present the results in detail. Otherwise, select and execute the next appropriate tool(s), following the correct order.
7+
8+
## Instructions
9+
- First, **check if the user's instruction has already been satisfied** by reviewing the existing conversation and tool responses.
10+
- If the request is complete, do **not** call any more tools. Instead, return a natural language response summarizing all tool results clearly and thoroughly.
11+
- If more steps are required, determine which tool(s) to call next.
12+
13+
### Tool Calling Rules:
14+
- Call tools using `tool_calls`.
15+
- If the request involves creating a schema (`trigger_graph_schema_creation`) or loading data (`trigger_load_data`), you **must** call each of these tools **individually**, without grouping them with any other tools in the same call.
16+
- For example, if the user asks to:
17+
1. Preview sample data
18+
2. Create a schema
19+
3. Load data
20+
Then call tools in this order:
21+
- Preview sample data
22+
- Then call `trigger_graph_schema_creation` **alone**
23+
- Then call `trigger_load_data` **alone**
24+
25+
## Output Format
26+
If you need to call a tool, use tool_calls.
27+
28+
If all tools execution completed, return information to the user, present the results in friendly, readable text in markdown format. Show each tool’s outcome with complete details. Don’t omit any valuable information—for example, if the schema includes attribute names and types, be sure to include both.
29+
30+
Here is an example:
31+
```
32+
33+
1. The node 'john_doe' was successfully added to the graph.
34+
35+
2. Number of nodes in the graph: 232,805 nodes.
36+
37+
3. Number of edges in the graph: 197,845 edges.
38+
39+
4. The neighbor query for 'john_doe' returned 3 connected nodes: 'jane_doe', 'acme_corp', and 'project_alpha'.
40+
41+
```
42+
"""

0 commit comments

Comments
 (0)