yadnyeshkolte commited on
Commit
3675de8
·
1 Parent(s): 1d4af62

update with removing a

Browse files
backend/package.json CHANGED
@@ -25,4 +25,4 @@
25
  "ts-node-dev": "^2.0.0",
26
  "typescript": "^5.3.0"
27
  }
28
- }
 
25
  "ts-node-dev": "^2.0.0",
26
  "typescript": "^5.3.0"
27
  }
28
+ }
backend/src/index.ts CHANGED
@@ -24,4 +24,4 @@ app.use('/api/generate', generateRouter);
24
 
25
  app.listen(PORT, () => {
26
  console.log(`Backend running on port ${PORT}`);
27
- });
 
24
 
25
  app.listen(PORT, () => {
26
  console.log(`Backend running on port ${PORT}`);
27
+ });
backend/src/services/archestra.ts CHANGED
@@ -3,66 +3,78 @@ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
3
  import EventSource from "eventsource";
4
 
5
  export class ArchestraService {
6
- private client: Client;
7
- private transport: SSEClientTransport;
8
  private isConnected: boolean = false;
 
9
 
10
  constructor() {
11
- const baseUrl = process.env.ARCHESTRA_URL || "http://localhost:9000";
12
  const profileId = process.env.ARCHESTRA_PROFILE_ID;
13
- const token = process.env.ARCHESTRA_TOKEN;
14
 
15
- if (!profileId) throw new Error("ARCHESTRA_PROFILE_ID is required");
16
-
17
  // Polyfill EventSource for Node.js
18
  // @ts-ignore
19
  global.EventSource = EventSource;
20
 
21
- this.transport = new SSEClientTransport(
22
- new URL(`${baseUrl}/v1/mcp/${profileId}`),
23
- {
24
- eventSourceInit: {
 
 
25
  headers: {
26
- Authorization: `Bearer ${token}`
27
  }
28
- }
29
- } as any
30
- );
31
 
32
- this.client = new Client(
33
- {
34
- name: "readmere-backend",
35
- version: "1.0.0",
36
- },
37
- {
38
- capabilities: {},
39
- }
40
- );
41
  }
42
 
43
  async connect() {
44
- if (this.isConnected) return;
45
- await this.client.connect(this.transport);
46
- this.isConnected = true;
47
- console.log("Connected to Archestra MCP Gateway");
 
 
 
 
 
 
 
48
  }
49
 
50
- async listTools() {
51
- await this.connect();
52
- return await this.client.listTools();
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
 
55
  async callTool(name: string, args: any) {
56
- try {
57
- await this.connect();
58
- return await this.client.callTool({
59
- name,
60
- arguments: args,
61
- });
62
- } catch (error) {
63
- console.warn(`Archestra Gateway unreachable, attempting direct call for tool: ${name}`);
64
-
65
- // Fallback: Map tool names to local agent ports
66
  const portMap: Record<string, number> = {
67
  'analyze_repository': 3002,
68
  'get_repo_metadata': 3002,
@@ -76,13 +88,15 @@ export class ArchestraService {
76
  };
77
 
78
  const port = portMap[name];
79
- if (!port) throw error;
80
-
81
- // Direct MCP-over-HTTP call to the local agent
82
- const response = await fetch(`http://localhost:${port}/sse`); // This is simplified for the example
83
- // In a real hackathon fallback, you'd use a direct fetch to the tool logic or a mock
84
- // For now, we will throw a clearer error so the user knows to fix the platform
85
- throw new Error("Archestra Platform is required for this orchestration. Please ensure yadnyeshkolte-archestra-platform is running.");
86
  }
 
 
 
 
 
87
  }
88
- }
 
3
  import EventSource from "eventsource";
4
 
5
  export class ArchestraService {
6
+ private client: Client | null = null;
7
+ private transport: SSEClientTransport | null = null;
8
  private isConnected: boolean = false;
9
+ private useLocalFallback: boolean = false;
10
 
11
  constructor() {
 
12
  const profileId = process.env.ARCHESTRA_PROFILE_ID;
13
+ const baseUrl = process.env.ARCHESTRA_URL;
14
 
 
 
15
  // Polyfill EventSource for Node.js
16
  // @ts-ignore
17
  global.EventSource = EventSource;
18
 
19
+ if (profileId && baseUrl) {
20
+ console.log("Configuring Archestra Platform connection...");
21
+ this.transport = new SSEClientTransport(
22
+ new URL(`${baseUrl}/v1/mcp/${profileId}`),
23
+ {
24
+ eventSourceInit: {
25
  headers: {
26
+ Authorization: `Bearer ${process.env.ARCHESTRA_TOKEN}`
27
  }
28
+ }
29
+ } as any
30
+ );
31
 
32
+ this.client = new Client(
33
+ { name: "readmere-backend", version: "1.0.0" },
34
+ { capabilities: {} }
35
+ );
36
+ } else {
37
+ console.warn("ARCHESTRA_PROFILE_ID or URL not found. Using direct local agent connection.");
38
+ this.useLocalFallback = true;
39
+ }
 
40
  }
41
 
42
  async connect() {
43
+ if (this.useLocalFallback || this.isConnected) return;
44
+ if (!this.client || !this.transport) return;
45
+
46
+ try {
47
+ await this.client.connect(this.transport);
48
+ this.isConnected = true;
49
+ console.log("Connected to Archestra MCP Gateway");
50
+ } catch (e) {
51
+ console.error("Failed to connect to Archestra, falling back to local agents.");
52
+ this.useLocalFallback = true;
53
+ }
54
  }
55
 
56
+ private async callLocalAgent(port: number, toolName: string, args: any) {
57
+ const localTransport = new SSEClientTransport(new URL(`http://localhost:${port}/sse`));
58
+ const localClient = new Client(
59
+ { name: "local-dispatcher", version: "1.0.0" },
60
+ { capabilities: {} }
61
+ );
62
+
63
+ await localClient.connect(localTransport);
64
+ const result = await localClient.callTool({
65
+ name: toolName,
66
+ arguments: args,
67
+ });
68
+
69
+ // Cleanup connection
70
+ await localClient.close();
71
+ return result;
72
  }
73
 
74
  async callTool(name: string, args: any) {
75
+ await this.connect();
76
+
77
+ if (this.useLocalFallback) {
 
 
 
 
 
 
 
78
  const portMap: Record<string, number> = {
79
  'analyze_repository': 3002,
80
  'get_repo_metadata': 3002,
 
88
  };
89
 
90
  const port = portMap[name];
91
+ if (!port) throw new Error(`Tool ${name} not supported in local mode`);
92
+
93
+ console.log(`Direct Call: ${name} on port ${port}`);
94
+ return await this.callLocalAgent(port, name, args);
 
 
 
95
  }
96
+
97
+ return await this.client!.callTool({
98
+ name,
99
+ arguments: args,
100
+ });
101
  }
102
+ }