@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.
@@ -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)
@@ -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
- }