@amitdeshmukh/ax-crew 8.0.3 → 8.2.0
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/.claude/settings.local.json +5 -1
- package/CHANGELOG.md +24 -1
- package/README.md +106 -7
- package/dist/agents/agentConfig.d.ts +3 -1
- package/dist/agents/agentConfig.js +3 -0
- package/dist/agents/index.d.ts +27 -3
- package/dist/agents/index.js +217 -128
- package/dist/index.d.ts +2 -2
- package/dist/types.d.ts +19 -1
- package/examples/graphjin-database-agent.ts +15 -9
- package/examples/rlm-long-task.ts +126 -0
- package/examples/rlm-shared-fields.ts +181 -0
- package/package.json +3 -3
- package/src/agents/agentConfig.ts +8 -1
- package/src/agents/index.ts +309 -144
- package/src/index.ts +4 -2
- package/src/types.ts +21 -1
- package/tests/execution-mode-metrics.test.ts +231 -0
- package/examples/factory.ts +0 -174
- package/examples/google-gemini-test.ts +0 -291
- package/examples/graphjin-README.md +0 -167
- package/examples/planner.ts +0 -107
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
# GraphJin Database Agent Example
|
|
2
|
-
|
|
3
|
-
This example demonstrates how to integrate GraphJin MCP server with AxCrew to give AI agents direct database access.
|
|
4
|
-
|
|
5
|
-
## What is GraphJin?
|
|
6
|
-
|
|
7
|
-
GraphJin is a compiler that connects AI assistants to databases. It auto-discovers your database schema, understands relationships, and compiles queries to optimized SQL. Works with PostgreSQL, MySQL, MongoDB, SQLite, Oracle, and MSSQL.
|
|
8
|
-
|
|
9
|
-
## Setup
|
|
10
|
-
|
|
11
|
-
### 1. Install GraphJin
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install -g graphjin
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
Or on macOS with Homebrew:
|
|
18
|
-
```bash
|
|
19
|
-
brew install dosco/graphjin/graphjin
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### 2. Start GraphJin Demo Server
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
# Clone GraphJin repo to get example databases
|
|
26
|
-
git clone https://github.com/dosco/graphjin
|
|
27
|
-
cd graphjin
|
|
28
|
-
|
|
29
|
-
# Start the demo webshop database
|
|
30
|
-
graphjin serve --demo --path examples/webshop
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
This starts GraphJin on `http://localhost:8080` with:
|
|
34
|
-
- Web UI: http://localhost:8080/
|
|
35
|
-
- GraphQL API: http://localhost:8080/api/v1/graphql
|
|
36
|
-
- MCP endpoint: http://localhost:8080/api/v1/mcp
|
|
37
|
-
|
|
38
|
-
### 3. Run the Example
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
cd /path/to/AxCrew/ax-crew
|
|
42
|
-
GEMINI_API_KEY=your-key npm run examples/graphjin-database-agent.ts
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## How It Works
|
|
46
|
-
|
|
47
|
-
The example creates two agents:
|
|
48
|
-
|
|
49
|
-
1. **DatabaseAgent**: Connects to GraphJin MCP server and has access to database tools
|
|
50
|
-
2. **ManagerAgent**: Orchestrates queries and delegates to DatabaseAgent
|
|
51
|
-
|
|
52
|
-
The GraphJin MCP server provides tools like:
|
|
53
|
-
- `get_tables` - List database tables
|
|
54
|
-
- `get_table_schema` - Get table structure
|
|
55
|
-
- `execute_graphql` - Query the database
|
|
56
|
-
- `search_schema` - Search for tables/columns
|
|
57
|
-
- And many more...
|
|
58
|
-
|
|
59
|
-
## MCP Server Configuration
|
|
60
|
-
|
|
61
|
-
### Proxy Mode (Recommended for Development)
|
|
62
|
-
|
|
63
|
-
Connects to a running GraphJin HTTP server:
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
mcpServers: {
|
|
67
|
-
"graphjin": {
|
|
68
|
-
"command": "graphjin",
|
|
69
|
-
"args": ["mcp", "--server", "http://localhost:8080"]
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Direct Mode
|
|
75
|
-
|
|
76
|
-
Runs GraphJin MCP server directly via stdio:
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
mcpServers: {
|
|
80
|
-
"graphjin": {
|
|
81
|
-
"command": "graphjin",
|
|
82
|
-
"args": ["mcp", "--demo", "--path", "/path/to/config"]
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Known Issue: Schema Validation Error
|
|
88
|
-
|
|
89
|
-
⚠️ **Current Status**: There's a schema validation incompatibility between GraphJin and Ax.
|
|
90
|
-
|
|
91
|
-
### The Problem
|
|
92
|
-
|
|
93
|
-
GraphJin's MCP server uses `mcp.WithArray()` from the `mcp-go` library, which generates JSON schemas without the required `items` property. This violates the JSON Schema specification and causes Ax to reject the schemas with:
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
Error: Function 'update_current_config' parameters schema is invalid.
|
|
97
|
-
Array schema is missing an "items" definition (required by JSON Schema and all LLM providers for function tools)
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Why Other MCP Clients Work
|
|
101
|
-
|
|
102
|
-
Some MCP clients are lenient and accept incomplete schemas, but Ax correctly enforces JSON Schema spec compliance.
|
|
103
|
-
|
|
104
|
-
### The Fix (Required in GraphJin)
|
|
105
|
-
|
|
106
|
-
The issue is in [graphjin/serv/mcp_config.go](graphjin/serv/mcp_config.go) where arrays are defined without item schemas:
|
|
107
|
-
|
|
108
|
-
```go
|
|
109
|
-
// Current (broken):
|
|
110
|
-
mcp.WithArray("tables",
|
|
111
|
-
mcp.Description("Array of table configs to add/update..."),
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
// Should be (fixed):
|
|
115
|
-
mcp.WithArray("tables",
|
|
116
|
-
mcp.Description("Array of table configs to add/update..."),
|
|
117
|
-
mcp.Items(mcp.Object(
|
|
118
|
-
// Define the structure of each table config item
|
|
119
|
-
)),
|
|
120
|
-
)
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
All array parameters in `update_current_config` need proper `items` schemas:
|
|
124
|
-
- `tables` (line 36)
|
|
125
|
-
- `roles` (line 39)
|
|
126
|
-
- `blocklist` (line 42)
|
|
127
|
-
- `functions` (line 45)
|
|
128
|
-
- `remove_databases` (line 48)
|
|
129
|
-
- `remove_tables` (line 51)
|
|
130
|
-
- `remove_roles` (line 54)
|
|
131
|
-
- `remove_blocklist_items` (line 57)
|
|
132
|
-
- `remove_functions` (line 60)
|
|
133
|
-
|
|
134
|
-
### Workaround
|
|
135
|
-
|
|
136
|
-
Until GraphJin is fixed, you can:
|
|
137
|
-
1. Use GraphJin with other MCP clients that are more lenient
|
|
138
|
-
2. Only use read-only tools (like `get_tables`, `execute_graphql`) which don't have this issue
|
|
139
|
-
3. Wait for the GraphJin team to fix the schema definitions
|
|
140
|
-
|
|
141
|
-
## Example Queries
|
|
142
|
-
|
|
143
|
-
Once the schema issue is fixed, you can try queries like:
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
const queries = [
|
|
147
|
-
"What tables are available in the database?",
|
|
148
|
-
"Show me the schema for the products table",
|
|
149
|
-
"How many products are in the database?",
|
|
150
|
-
"List the top 5 most expensive products",
|
|
151
|
-
"What customers have placed orders in the last 30 days?",
|
|
152
|
-
"Update the products table to add a new column called 'featured'",
|
|
153
|
-
];
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
## Next Steps
|
|
157
|
-
|
|
158
|
-
1. **For GraphJin Maintainers**: Fix the array item schemas in `mcp_config.go`
|
|
159
|
-
2. **For Users**: Use read-only GraphJin tools until the fix is merged
|
|
160
|
-
3. **For Ax Users**: The validation is correct and should not be changed
|
|
161
|
-
|
|
162
|
-
## Resources
|
|
163
|
-
|
|
164
|
-
- [GraphJin Documentation](https://graphjin.com)
|
|
165
|
-
- [GraphJin GitHub](https://github.com/dosco/graphjin)
|
|
166
|
-
- [MCP Protocol Spec](https://modelcontextprotocol.io)
|
|
167
|
-
- [JSON Schema Specification](https://json-schema.org)
|
package/examples/planner.ts
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
// LLA: Latitude, Longitude, Altitude (and optional Heading)
|
|
2
|
-
export interface LLA {
|
|
3
|
-
lat: number;
|
|
4
|
-
lon: number;
|
|
5
|
-
alt: number;
|
|
6
|
-
heading?: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Summary of the calculated mission.
|
|
11
|
-
*/
|
|
12
|
-
interface MissionSummary {
|
|
13
|
-
totalDistanceKm: number;
|
|
14
|
-
totalTimeSeconds: number;
|
|
15
|
-
etaFormatted: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* FlightConstantSpeedPlanner
|
|
20
|
-
* Simple waypoint-to-waypoint path generation at constant speed.
|
|
21
|
-
*/
|
|
22
|
-
export class FlightConstantSpeedPlanner {
|
|
23
|
-
private readonly EARTH_RADIUS = 6378137.0;
|
|
24
|
-
|
|
25
|
-
constructor(
|
|
26
|
-
private speed: number, // m/s
|
|
27
|
-
private hz: number = 0.0333 // Default: ~1 point per 30 seconds
|
|
28
|
-
) {}
|
|
29
|
-
|
|
30
|
-
public getMissionDetails(waypoints: LLA[]): { path: LLA[], summary: MissionSummary } {
|
|
31
|
-
const path = this.planRoute(waypoints);
|
|
32
|
-
|
|
33
|
-
const totalTimeSeconds = path.length > 1 ? (path.length - 1) / this.hz : 0;
|
|
34
|
-
const totalDistanceKm = (totalTimeSeconds * this.speed) / 1000;
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
path,
|
|
38
|
-
summary: {
|
|
39
|
-
totalDistanceKm: Number(totalDistanceKm.toFixed(3)),
|
|
40
|
-
totalTimeSeconds: Math.round(totalTimeSeconds),
|
|
41
|
-
etaFormatted: this.formatTime(totalTimeSeconds)
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private planRoute(waypoints: LLA[]): LLA[] {
|
|
47
|
-
if (waypoints.length < 2) return waypoints;
|
|
48
|
-
|
|
49
|
-
let fullPath: LLA[] = [];
|
|
50
|
-
|
|
51
|
-
// Simple: just generate straight segments between consecutive waypoints
|
|
52
|
-
for (let i = 0; i < waypoints.length - 1; i++) {
|
|
53
|
-
const segment = this.generateStraight(waypoints[i], waypoints[i + 1]);
|
|
54
|
-
fullPath = [...fullPath, ...segment];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Add final waypoint
|
|
58
|
-
fullPath.push(waypoints[waypoints.length - 1]);
|
|
59
|
-
|
|
60
|
-
return fullPath;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private generateStraight(start: LLA, end: LLA): LLA[] {
|
|
64
|
-
const dist = this.getDistance(start, end);
|
|
65
|
-
if (dist < 0.01) return [];
|
|
66
|
-
|
|
67
|
-
const steps = Math.max(1, Math.floor((dist / this.speed) * this.hz));
|
|
68
|
-
const heading = this.getBearing(start, end);
|
|
69
|
-
const points: LLA[] = [];
|
|
70
|
-
|
|
71
|
-
for (let i = 0; i < steps; i++) {
|
|
72
|
-
const r = i / steps;
|
|
73
|
-
points.push({
|
|
74
|
-
lat: start.lat + (end.lat - start.lat) * r,
|
|
75
|
-
lon: start.lon + (end.lon - start.lon) * r,
|
|
76
|
-
alt: start.alt + (end.alt - start.alt) * r,
|
|
77
|
-
heading: Number(heading.toFixed(2))
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
return points;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private getBearing(p1: LLA, p2: LLA): number {
|
|
84
|
-
const dLon = (p2.lon - p1.lon) * (Math.PI / 180);
|
|
85
|
-
const lat1 = p1.lat * (Math.PI / 180);
|
|
86
|
-
const lat2 = p2.lat * (Math.PI / 180);
|
|
87
|
-
const y = Math.sin(dLon) * Math.cos(lat2);
|
|
88
|
-
const x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
|
|
89
|
-
return (Math.atan2(y, x) * 180 / Math.PI + 360) % 360;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private getDistance(p1: LLA, p2: LLA): number {
|
|
93
|
-
const dLat = (p2.lat - p1.lat) * (Math.PI / 180);
|
|
94
|
-
const dLon = (p2.lon - p1.lon) * (Math.PI / 180);
|
|
95
|
-
const a = Math.sin(dLat/2)**2 + Math.cos(p1.lat*Math.PI/180) * Math.cos(p2.lat*Math.PI/180) * Math.sin(dLon/2)**2;
|
|
96
|
-
return 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) * this.EARTH_RADIUS;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private formatTime(seconds: number): string {
|
|
100
|
-
const h = Math.floor(seconds / 3600);
|
|
101
|
-
const m = Math.floor((seconds % 3600) / 60);
|
|
102
|
-
const s = Math.floor(seconds % 60);
|
|
103
|
-
const parts = [m, s].map(v => v.toString().padStart(2, '0'));
|
|
104
|
-
if (h > 0) parts.unshift(h.toString().padStart(2, '0'));
|
|
105
|
-
return parts.join(':');
|
|
106
|
-
}
|
|
107
|
-
}
|