mcpgraph 0.1.15 → 0.1.17
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.
- package/README.md +61 -1
- package/dist/api.d.ts +13 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +40 -0
- package/dist/api.js.map +1 -1
- package/dist/config/expression-validator.d.ts +12 -0
- package/dist/config/expression-validator.d.ts.map +1 -0
- package/dist/config/expression-validator.js +77 -0
- package/dist/config/expression-validator.js.map +1 -0
- package/dist/config/parser.d.ts.map +1 -1
- package/dist/config/parser.js +9 -0
- package/dist/config/parser.js.map +1 -1
- package/dist/config/schema.d.ts +18 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +5 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/execution/context.d.ts +27 -3
- package/dist/execution/context.d.ts.map +1 -1
- package/dist/execution/context.js +52 -9
- package/dist/execution/context.js.map +1 -1
- package/dist/execution/executor.d.ts.map +1 -1
- package/dist/execution/executor.js +34 -12
- package/dist/execution/executor.js.map +1 -1
- package/dist/execution/nodes/entry-executor.d.ts.map +1 -1
- package/dist/execution/nodes/entry-executor.js +1 -2
- package/dist/execution/nodes/entry-executor.js.map +1 -1
- package/dist/execution/nodes/exit-executor.d.ts +1 -1
- package/dist/execution/nodes/exit-executor.d.ts.map +1 -1
- package/dist/execution/nodes/exit-executor.js +9 -7
- package/dist/execution/nodes/exit-executor.js.map +1 -1
- package/dist/execution/nodes/mcp-tool-executor.d.ts +1 -1
- package/dist/execution/nodes/mcp-tool-executor.d.ts.map +1 -1
- package/dist/execution/nodes/mcp-tool-executor.js +5 -4
- package/dist/execution/nodes/mcp-tool-executor.js.map +1 -1
- package/dist/execution/nodes/switch-executor.d.ts +1 -1
- package/dist/execution/nodes/switch-executor.d.ts.map +1 -1
- package/dist/execution/nodes/switch-executor.js +13 -8
- package/dist/execution/nodes/switch-executor.js.map +1 -1
- package/dist/execution/nodes/transform-executor.d.ts +1 -1
- package/dist/execution/nodes/transform-executor.d.ts.map +1 -1
- package/dist/execution/nodes/transform-executor.js +5 -4
- package/dist/execution/nodes/transform-executor.js.map +1 -1
- package/dist/expressions/json-logic.d.ts +11 -2
- package/dist/expressions/json-logic.d.ts.map +1 -1
- package/dist/expressions/json-logic.js +98 -16
- package/dist/expressions/json-logic.js.map +1 -1
- package/dist/expressions/jsonata-extensions.d.ts +10 -0
- package/dist/expressions/jsonata-extensions.d.ts.map +1 -0
- package/dist/expressions/jsonata-extensions.js +69 -0
- package/dist/expressions/jsonata-extensions.js.map +1 -0
- package/dist/expressions/jsonata.d.ts +8 -1
- package/dist/expressions/jsonata.d.ts.map +1 -1
- package/dist/expressions/jsonata.js +72 -12
- package/dist/expressions/jsonata.js.map +1 -1
- package/dist/types/config.d.ts +5 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/execution.d.ts +1 -1
- package/dist/types/execution.d.ts.map +1 -1
- package/docs/design.md +21 -2
- package/docs/implementation.md +15 -6
- package/docs/introspection-debugging.md +28 -1
- package/examples/api-usage.ts +54 -1
- package/examples/loop_example.yaml +84 -0
- package/package.json +1 -1
package/examples/api-usage.ts
CHANGED
|
@@ -70,7 +70,7 @@ async function introspectionExample() {
|
|
|
70
70
|
if (result.executionHistory) {
|
|
71
71
|
console.log('\nExecution History:');
|
|
72
72
|
for (const record of result.executionHistory) {
|
|
73
|
-
console.log(` ${record.nodeId} (${record.nodeType}): ${record.duration}ms`);
|
|
73
|
+
console.log(` [${record.executionIndex}] ${record.nodeId} (${record.nodeType}): ${record.duration}ms`);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -88,6 +88,57 @@ async function introspectionExample() {
|
|
|
88
88
|
await api.close();
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
// Example: Time-travel debugging with getContextForExecution
|
|
92
|
+
async function timeTravelDebuggingExample() {
|
|
93
|
+
const api = new McpGraphApi('examples/count_files.yaml');
|
|
94
|
+
|
|
95
|
+
let executionIndexToInspect: number | null = null;
|
|
96
|
+
|
|
97
|
+
const { promise, controller } = api.executeTool('count_files', {
|
|
98
|
+
directory: './tests/files',
|
|
99
|
+
}, {
|
|
100
|
+
hooks: {
|
|
101
|
+
onNodeComplete: async (nodeId, node, input, output, duration) => {
|
|
102
|
+
// When count_files_node completes, inspect the context that was available to list_directory_node
|
|
103
|
+
if (nodeId === 'count_files_node') {
|
|
104
|
+
// Find the execution index of list_directory_node
|
|
105
|
+
const state = api.getExecutionState();
|
|
106
|
+
if (state) {
|
|
107
|
+
const listDirRecord = state.executionHistory.find(r => r.nodeId === 'list_directory_node');
|
|
108
|
+
if (listDirRecord) {
|
|
109
|
+
executionIndexToInspect = listDirRecord.executionIndex;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
await promise;
|
|
118
|
+
|
|
119
|
+
if (executionIndexToInspect !== null && controller) {
|
|
120
|
+
// Get the context that was available to list_directory_node when it executed
|
|
121
|
+
const context = api.getContextForExecution(executionIndexToInspect);
|
|
122
|
+
if (context) {
|
|
123
|
+
console.log('\nTime-Travel Debugging:');
|
|
124
|
+
console.log(`Context available to execution #${executionIndexToInspect} (list_directory_node):`);
|
|
125
|
+
console.log(JSON.stringify(context, null, 2));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Get the execution record itself
|
|
129
|
+
const record = api.getExecutionByIndex(executionIndexToInspect);
|
|
130
|
+
if (record) {
|
|
131
|
+
console.log(`\nExecution Record #${executionIndexToInspect}:`);
|
|
132
|
+
console.log(` Node: ${record.nodeId}`);
|
|
133
|
+
console.log(` Type: ${record.nodeType}`);
|
|
134
|
+
console.log(` Duration: ${record.duration}ms`);
|
|
135
|
+
console.log(` Output: ${JSON.stringify(record.output).substring(0, 100)}...`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
await api.close();
|
|
140
|
+
}
|
|
141
|
+
|
|
91
142
|
// Example: Validate config without creating an API instance
|
|
92
143
|
function validateConfigExample() {
|
|
93
144
|
const errors = McpGraphApi.validateConfig('examples/count_files.yaml');
|
|
@@ -118,6 +169,8 @@ if (import.meta.url === `file://${process.argv[1]}`) {
|
|
|
118
169
|
|
|
119
170
|
if (exampleToRun === 'introspection') {
|
|
120
171
|
introspectionExample().catch(console.error);
|
|
172
|
+
} else if (exampleToRun === 'debugging') {
|
|
173
|
+
timeTravelDebuggingExample().catch(console.error);
|
|
121
174
|
} else {
|
|
122
175
|
example().catch(console.error);
|
|
123
176
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
version: "1.0"
|
|
2
|
+
|
|
3
|
+
# MCP Server Metadata
|
|
4
|
+
server:
|
|
5
|
+
name: "loopExample"
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
description: "Example with a loop using history functions"
|
|
8
|
+
|
|
9
|
+
# Tool Definitions
|
|
10
|
+
tools:
|
|
11
|
+
- name: "sum_to_n"
|
|
12
|
+
description: "Sums numbers from 1 to n using a loop"
|
|
13
|
+
inputSchema:
|
|
14
|
+
type: "object"
|
|
15
|
+
properties:
|
|
16
|
+
n:
|
|
17
|
+
type: "number"
|
|
18
|
+
description: "The number to sum to"
|
|
19
|
+
required:
|
|
20
|
+
- n
|
|
21
|
+
outputSchema:
|
|
22
|
+
type: "object"
|
|
23
|
+
properties:
|
|
24
|
+
sum:
|
|
25
|
+
type: "number"
|
|
26
|
+
description: "The sum from 1 to n"
|
|
27
|
+
|
|
28
|
+
# Graph Nodes
|
|
29
|
+
nodes:
|
|
30
|
+
# Entry node: Receives tool arguments
|
|
31
|
+
- id: "entry_sum"
|
|
32
|
+
type: "entry"
|
|
33
|
+
tool: "sum_to_n"
|
|
34
|
+
next: "increment_node"
|
|
35
|
+
|
|
36
|
+
# Increment counter and add to sum
|
|
37
|
+
# Uses $nodeExecution() to get the previous iteration of this node
|
|
38
|
+
# First iteration: $executionCount("increment_node") = 0, so we initialize
|
|
39
|
+
# Subsequent iterations: $nodeExecution("increment_node", -1) gets the last execution
|
|
40
|
+
- id: "increment_node"
|
|
41
|
+
type: "transform"
|
|
42
|
+
transform:
|
|
43
|
+
expr: |
|
|
44
|
+
$executionCount("increment_node") = 0
|
|
45
|
+
? {
|
|
46
|
+
"counter": 1,
|
|
47
|
+
"sum": 1,
|
|
48
|
+
"target": $.entry_sum.n
|
|
49
|
+
}
|
|
50
|
+
: {
|
|
51
|
+
"counter": $nodeExecution("increment_node", -1).counter + 1,
|
|
52
|
+
"sum": $nodeExecution("increment_node", -1).sum + $nodeExecution("increment_node", -1).counter + 1,
|
|
53
|
+
"target": $.entry_sum.n
|
|
54
|
+
}
|
|
55
|
+
next: "check_condition"
|
|
56
|
+
|
|
57
|
+
# Check if we should continue looping
|
|
58
|
+
- id: "check_condition"
|
|
59
|
+
type: "switch"
|
|
60
|
+
conditions:
|
|
61
|
+
- rule:
|
|
62
|
+
"<": [{"var": "$.increment_node.counter"}, {"var": "$.increment_node.target"}]
|
|
63
|
+
target: "increment_node"
|
|
64
|
+
- target: "exit_sum"
|
|
65
|
+
|
|
66
|
+
# Exit node: Extracts the sum from increment_node
|
|
67
|
+
# Uses $previousNode() to verify it returns the switch node's output (target node ID)
|
|
68
|
+
# The output matches the tool's outputSchema (just the sum)
|
|
69
|
+
- id: "exit_sum"
|
|
70
|
+
type: "transform"
|
|
71
|
+
transform:
|
|
72
|
+
expr: |
|
|
73
|
+
$previousNode() = "exit_sum" ? {
|
|
74
|
+
"sum": $.increment_node.sum
|
|
75
|
+
} : {
|
|
76
|
+
"sum": 0,
|
|
77
|
+
"error": "previousNode check failed"
|
|
78
|
+
}
|
|
79
|
+
next: "exit_sum_final"
|
|
80
|
+
|
|
81
|
+
# Final exit node
|
|
82
|
+
- id: "exit_sum_final"
|
|
83
|
+
type: "exit"
|
|
84
|
+
tool: "sum_to_n"
|