gopherhole_openclaw_a2a 0.3.13 → 0.3.14

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/dist/index.js CHANGED
@@ -141,6 +141,69 @@ const plugin = {
141
141
  return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: `Unknown action: ${action}` }) }] };
142
142
  },
143
143
  });
144
+ // Register a tool for location-based agent discovery
145
+ api.registerTool?.({
146
+ name: 'a2a_discover_nearby',
147
+ description: 'Find A2A agents near a geographic location',
148
+ parameters: {
149
+ type: 'object',
150
+ properties: {
151
+ lat: {
152
+ type: 'number',
153
+ description: 'Latitude of search center',
154
+ },
155
+ lng: {
156
+ type: 'number',
157
+ description: 'Longitude of search center',
158
+ },
159
+ radius: {
160
+ type: 'number',
161
+ description: 'Search radius in kilometers (default: 10, max: 500)',
162
+ },
163
+ tag: {
164
+ type: 'string',
165
+ description: 'Filter by tag (e.g., "retail", "food")',
166
+ },
167
+ category: {
168
+ type: 'string',
169
+ description: 'Filter by category',
170
+ },
171
+ limit: {
172
+ type: 'number',
173
+ description: 'Maximum number of results (default: 20, max: 50)',
174
+ },
175
+ },
176
+ required: ['lat', 'lng'],
177
+ },
178
+ execute: async (_id, params) => {
179
+ const lat = params.lat;
180
+ const lng = params.lng;
181
+ const radius = params.radius;
182
+ const tag = params.tag;
183
+ const category = params.category;
184
+ const limit = params.limit;
185
+ const manager = getA2AConnectionManager();
186
+ if (!manager) {
187
+ return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: 'A2A channel not running' }) }] };
188
+ }
189
+ if (!manager.isGopherHoleConnected()) {
190
+ return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: 'Not connected to GopherHole' }) }] };
191
+ }
192
+ try {
193
+ const agents = await manager.discoverNearby({ lat, lng, radius, tag, category, limit });
194
+ return { content: [{ type: 'text', text: JSON.stringify({
195
+ status: 'ok',
196
+ center: { lat, lng },
197
+ radius: radius || 10,
198
+ count: agents.length,
199
+ agents
200
+ }) }] };
201
+ }
202
+ catch (err) {
203
+ return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: err.message }) }] };
204
+ }
205
+ },
206
+ });
144
207
  },
145
208
  };
146
209
  export default plugin;
@@ -93,6 +93,32 @@ export declare class A2AConnectionManager {
93
93
  tenantName?: string;
94
94
  avgRating?: number;
95
95
  }>>;
96
+ /**
97
+ * Discover agents near a geographic location
98
+ */
99
+ discoverNearby(options: {
100
+ lat: number;
101
+ lng: number;
102
+ radius?: number;
103
+ tag?: string;
104
+ category?: string;
105
+ limit?: number;
106
+ offset?: number;
107
+ }): Promise<Array<{
108
+ id: string;
109
+ name: string;
110
+ description?: string;
111
+ verified?: boolean;
112
+ tenantName?: string;
113
+ avgRating?: number;
114
+ location?: {
115
+ name: string;
116
+ lat: number;
117
+ lng: number;
118
+ country: string;
119
+ };
120
+ distance?: number;
121
+ }>>;
96
122
  /**
97
123
  * List connection status (for backward compatibility)
98
124
  */
@@ -333,6 +333,13 @@ export class A2AConnectionManager {
333
333
  const result = await this.a2aRpc('x-gopherhole/agents.discover', options);
334
334
  return result?.agents || [];
335
335
  }
336
+ /**
337
+ * Discover agents near a geographic location
338
+ */
339
+ async discoverNearby(options) {
340
+ const result = await this.a2aRpc('x-gopherhole/agents.discover.nearby', options);
341
+ return result?.agents || [];
342
+ }
336
343
  /**
337
344
  * List connection status (for backward compatibility)
338
345
  */
package/index.ts CHANGED
@@ -159,6 +159,72 @@ const plugin = {
159
159
  return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: `Unknown action: ${action}` }) }] };
160
160
  },
161
161
  });
162
+
163
+ // Register a tool for location-based agent discovery
164
+ api.registerTool?.({
165
+ name: 'a2a_discover_nearby',
166
+ description: 'Find A2A agents near a geographic location',
167
+ parameters: {
168
+ type: 'object',
169
+ properties: {
170
+ lat: {
171
+ type: 'number',
172
+ description: 'Latitude of search center',
173
+ },
174
+ lng: {
175
+ type: 'number',
176
+ description: 'Longitude of search center',
177
+ },
178
+ radius: {
179
+ type: 'number',
180
+ description: 'Search radius in kilometers (default: 10, max: 500)',
181
+ },
182
+ tag: {
183
+ type: 'string',
184
+ description: 'Filter by tag (e.g., "retail", "food")',
185
+ },
186
+ category: {
187
+ type: 'string',
188
+ description: 'Filter by category',
189
+ },
190
+ limit: {
191
+ type: 'number',
192
+ description: 'Maximum number of results (default: 20, max: 50)',
193
+ },
194
+ },
195
+ required: ['lat', 'lng'],
196
+ },
197
+ execute: async (_id, params) => {
198
+ const lat = params.lat as number;
199
+ const lng = params.lng as number;
200
+ const radius = params.radius as number | undefined;
201
+ const tag = params.tag as string | undefined;
202
+ const category = params.category as string | undefined;
203
+ const limit = params.limit as number | undefined;
204
+
205
+ const manager = getA2AConnectionManager();
206
+ if (!manager) {
207
+ return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: 'A2A channel not running' }) }] };
208
+ }
209
+
210
+ if (!manager.isGopherHoleConnected()) {
211
+ return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: 'Not connected to GopherHole' }) }] };
212
+ }
213
+
214
+ try {
215
+ const agents = await manager.discoverNearby({ lat, lng, radius, tag, category, limit });
216
+ return { content: [{ type: 'text', text: JSON.stringify({
217
+ status: 'ok',
218
+ center: { lat, lng },
219
+ radius: radius || 10,
220
+ count: agents.length,
221
+ agents
222
+ }) }] };
223
+ } catch (err) {
224
+ return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: (err as Error).message }) }] };
225
+ }
226
+ },
227
+ });
162
228
  },
163
229
  };
164
230
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gopherhole_openclaw_a2a",
3
- "version": "0.3.13",
3
+ "version": "0.3.14",
4
4
  "description": "GopherHole A2A plugin for OpenClaw - connect your AI agent to the GopherHole network",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/connection.ts CHANGED
@@ -452,6 +452,51 @@ export class A2AConnectionManager {
452
452
  return result?.agents || [];
453
453
  }
454
454
 
455
+ /**
456
+ * Discover agents near a geographic location
457
+ */
458
+ async discoverNearby(options: {
459
+ lat: number;
460
+ lng: number;
461
+ radius?: number;
462
+ tag?: string;
463
+ category?: string;
464
+ limit?: number;
465
+ offset?: number;
466
+ }): Promise<Array<{
467
+ id: string;
468
+ name: string;
469
+ description?: string;
470
+ verified?: boolean;
471
+ tenantName?: string;
472
+ avgRating?: number;
473
+ location?: {
474
+ name: string;
475
+ lat: number;
476
+ lng: number;
477
+ country: string;
478
+ };
479
+ distance?: number;
480
+ }>> {
481
+ const result = await this.a2aRpc<{ agents: Array<{
482
+ id: string;
483
+ name: string;
484
+ description?: string;
485
+ verified?: boolean;
486
+ tenantName?: string;
487
+ avgRating?: number;
488
+ location?: {
489
+ name: string;
490
+ lat: number;
491
+ lng: number;
492
+ country: string;
493
+ };
494
+ distance?: number;
495
+ }> }>('x-gopherhole/agents.discover.nearby', options);
496
+
497
+ return result?.agents || [];
498
+ }
499
+
455
500
  /**
456
501
  * List connection status (for backward compatibility)
457
502
  */