agentgui 1.0.436 → 1.0.437

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.
@@ -68,71 +68,6 @@ async function acpFetch(port, pth, body = null) {
68
68
  return res.json();
69
69
  }
70
70
 
71
- function getApiKey(name) {
72
- const envMap = {
73
- anthropic: 'ANTHROPIC_API_KEY',
74
- google: 'GOOGLE_GENAI_API_KEY',
75
- openai: 'OPENAI_API_KEY'
76
- };
77
- if (process.env[envMap[name]]) return process.env[envMap[name]];
78
- const configPaths = {
79
- anthropic: [
80
- path.join(os.homedir(), '.claude.json'),
81
- path.join(os.homedir(), '.anthropic.json')
82
- ],
83
- google: [
84
- path.join(os.homedir(), '.gemini.json'),
85
- path.join(os.homedir(), '.config', 'gemini', 'credentials.json')
86
- ],
87
- openai: [
88
- path.join(os.homedir(), '.openai.json')
89
- ]
90
- };
91
- for (const p of (configPaths[name] || [])) {
92
- const data = readJson(p);
93
- if (data) {
94
- const key = data.api_key || data.apiKey || data.github_token;
95
- if (key) return key;
96
- }
97
- }
98
- return null;
99
- }
100
-
101
- async function fetchModelsFromAPI(agentId) {
102
- if (agentId === 'claude-code') {
103
- const apiKey = getApiKey('anthropic');
104
- if (!apiKey) return null;
105
- try {
106
- const res = await fetch('https://api.anthropic.com/v1/models', {
107
- headers: { 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' },
108
- signal: AbortSignal.timeout(8000)
109
- });
110
- if (!res.ok) return null;
111
- const data = await res.json();
112
- const items = (data.data || []).filter(m => m.id && m.id.startsWith('claude-'));
113
- if (items.length === 0) return null;
114
- return items.map(m => ({ id: m.id, label: m.display_name || m.id.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()) }));
115
- } catch { return null; }
116
- }
117
- if (agentId === 'gemini') {
118
- const apiKey = getApiKey('google');
119
- if (!apiKey) return null;
120
- try {
121
- const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`, {
122
- signal: AbortSignal.timeout(8000)
123
- });
124
- if (!res.ok) return null;
125
- const data = await res.json();
126
- const items = (data.models || []).filter(m => m.name && m.name.includes('gemini'));
127
- if (items.length === 0) return null;
128
- return items.map(m => {
129
- const id = m.name.replace(/^models\//, '');
130
- return { id, label: id.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()) };
131
- });
132
- } catch { return null; }
133
- }
134
- return null;
135
- }
136
71
 
137
72
  export function register(router, deps) {
138
73
  const { db, discoveredAgents, modelCache,
@@ -194,69 +129,29 @@ export function register(router, deps) {
194
129
  return d;
195
130
  });
196
131
 
197
- router.handle('agent.models', async (p) => {
198
- const cached = modelCache.get(p.id);
199
- if (cached && (Date.now() - cached.ts) < 300000) return { models: cached.models };
200
- const agent = discoveredAgents.find(x => x.id === p.id);
201
- if (agent?.protocol === 'acp' && agent.acpPort) {
202
- const port = agent.acpPort;
203
- try {
204
- const data = await acpFetch(port, '/v1/models');
205
- const models = (data?.data || data?.models || []).map(m => ({
206
- id: m.id || m.model_id,
207
- label: m.name || m.display_name || m.id || m.model_id
208
- })).filter(m => m.id);
209
- if (models.length > 0) { modelCache.set(p.id, { models, ts: Date.now() }); return { models }; }
210
- } catch (_) {}
211
- try {
212
- const data = await acpFetch(port, '/agents/search', {});
213
- const list = Array.isArray(data) ? data : (data?.agents || []);
214
- const allModels = new Map();
215
- for (const a of list) {
216
- const agentId = a.agent_id || a.id;
217
- const name = a.metadata?.ref?.name || a.name || agentId;
218
- if (agentId && name) allModels.set(agentId, name);
219
- for (const m of (a.metadata?.models || a.specs?.models || [])) {
220
- const id = m.id || m;
221
- if (id) allModels.set(id, m.name || m.label || id);
222
- }
223
- try {
224
- const desc = await acpFetch(port, `/agents/${agentId}/descriptor`);
225
- const enumVals = desc?.specs?.config?.properties?.model?.enum || desc?.specs?.input?.properties?.model?.enum || [];
226
- for (const v of enumVals) allModels.set(v, v);
227
- } catch (_) {}
228
- }
229
- if (allModels.size > 0) {
230
- const models = Array.from(allModels.entries()).map(([id, label]) => ({ id, label }));
231
- modelCache.set(p.id, { models, ts: Date.now() });
232
- return { models };
233
- }
234
- } catch (_) {}
235
- }
236
- const acpAgents = discoveredAgents.filter(x => x.protocol === 'acp' && x.acpPort);
237
- for (const acpAgent of acpAgents) {
238
- const port = acpAgent.acpPort;
239
- try {
240
- const desc = await acpFetch(port, `/agents/${p.id}/descriptor`);
241
- if (desc) {
242
- const enumVals = desc?.specs?.config?.properties?.model?.enum || desc?.specs?.input?.properties?.model?.enum || [];
243
- if (enumVals.length > 0) {
244
- const models = enumVals.map(v => ({ id: v, label: v }));
245
- modelCache.set(p.id, { models, ts: Date.now() });
246
- return { models };
247
- }
248
- const name = desc?.metadata?.ref?.name;
249
- if (name) { const models = [{ id: p.id, label: name }]; modelCache.set(p.id, { models, ts: Date.now() }); return { models }; }
250
- }
251
- } catch (_) {}
252
- }
253
- const apiModels = await fetchModelsFromAPI(p.id);
254
- if (apiModels && apiModels.length > 0) {
255
- modelCache.set(p.id, { models: apiModels, ts: Date.now() });
256
- return { models: apiModels };
257
- }
258
- return { models: [] };
259
- });
132
+ router.handle('agent.models', async (p) => {
133
+ const cached = modelCache.get(p.id);
134
+ if (cached && (Date.now() - cached.ts) < 300000) return { models: cached.models };
135
+ let models = [];
136
+ if (p.id === 'claude-code') {
137
+ models = [
138
+ { id: 'claude-haiku', label: 'Haiku' },
139
+ { id: 'claude-sonnet', label: 'Sonnet' },
140
+ { id: 'claude-opus', label: 'Opus' }
141
+ ];
142
+ } else {
143
+ const agent = discoveredAgents.find(x => x.id === p.id);
144
+ if (agent?.protocol === 'acp' && agent.acpPort) {
145
+ try {
146
+ const data = await acpFetch(agent.acpPort, '/models');
147
+ const list = data?.data || data?.models || (Array.isArray(data) ? data : []);
148
+ models = list.map(m => ({ id: m.id || m.model_id, label: m.name || m.display_name || m.id || m.model_id })).filter(m => m.id);
149
+ } catch (_) {}
150
+ }
151
+ }
152
+ if (models.length > 0) modelCache.set(p.id, { models, ts: Date.now() });
153
+ return { models };
154
+ });
260
155
 
261
156
  router.handle('agent.search', (p) => db.searchAgents(discoveredAgents, p.query || p));
262
157
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.436",
3
+ "version": "1.0.437",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -411,22 +411,13 @@ function discoverAgents() {
411
411
 
412
412
  // Function to discover agents from external ACP servers
413
413
  async function discoverExternalACPServers() {
414
- // Default ACP servers to query (excluding local server to prevent recursion)
415
- const acpServers = [
416
- 'http://localhost:8080', // Common default ACP port
417
- ];
418
-
419
414
  const externalAgents = [];
420
- for (const serverUrl of acpServers) {
415
+ for (const agent of discoveredAgents.filter(a => a.protocol === 'acp' && a.acpPort)) {
421
416
  try {
422
- console.log(`Querying ACP agents from: ${serverUrl}`);
423
- const agents = await queryACPServerAgents(serverUrl);
417
+ const agents = await queryACPServerAgents(`http://localhost:${agent.acpPort}`);
424
418
  externalAgents.push(...agents);
425
- } catch (error) {
426
- console.error(`Failed to query ${serverUrl}:`, error.message);
427
- }
419
+ } catch (_) {}
428
420
  }
429
-
430
421
  return externalAgents;
431
422
  }
432
423
 
@@ -435,53 +426,34 @@ initializeDescriptors(discoveredAgents);
435
426
 
436
427
  const modelCache = new Map();
437
428
 
438
- function modelIdToLabel(id) {
439
- const base = id.replace(/^claude-/, '').replace(/-\d{8}$/, '');
440
- const m = base.match(/^(\w+)-(\d+)(?:-(\d+))?$/);
441
- if (m) return `${m[1].charAt(0).toUpperCase() + m[1].slice(1)} ${m[3] ? m[2] + '.' + m[3] : m[2]}`;
442
- return base.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
443
- }
444
-
445
429
  async function getModelsForAgent(agentId) {
446
430
  const cached = modelCache.get(agentId);
447
- if (cached && Date.now() - cached.timestamp < 3600000) return cached.models;
448
- let models = null;
431
+ if (cached && Date.now() - cached.timestamp < 300000) return cached.models;
432
+ let models = [];
449
433
  if (agentId === 'claude-code') {
450
- const apiKey = process.env.ANTHROPIC_API_KEY;
451
- if (apiKey) {
452
- try {
453
- const res = await fetch('https://api.anthropic.com/v1/models', {
454
- headers: { 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' },
455
- signal: AbortSignal.timeout(8000)
456
- });
457
- if (res.ok) {
458
- const data = await res.json();
459
- const items = (data.data || []).filter(m => m.id && m.id.startsWith('claude-'));
460
- if (items.length > 0) models = items.map(m => ({ id: m.id, label: m.display_name || modelIdToLabel(m.id) }));
461
- }
462
- } catch (_) {}
463
- }
464
- } else if (agentId === 'gemini') {
465
- const apiKey = process.env.GOOGLE_GENAI_API_KEY;
466
- if (apiKey) {
434
+ models = [
435
+ { id: 'claude-haiku', label: 'Haiku' },
436
+ { id: 'claude-sonnet', label: 'Sonnet' },
437
+ { id: 'claude-opus', label: 'Opus' }
438
+ ];
439
+ } else {
440
+ const agent = discoveredAgents.find(a => a.id === agentId);
441
+ if (agent?.protocol === 'acp' && agent.acpPort) {
467
442
  try {
468
- const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`, {
469
- signal: AbortSignal.timeout(8000)
443
+ const res = await fetch(`http://localhost:${agent.acpPort}/models`, {
444
+ headers: { 'Content-Type': 'application/json' },
445
+ signal: AbortSignal.timeout(3000)
470
446
  });
471
447
  if (res.ok) {
472
448
  const data = await res.json();
473
- const items = (data.models || []).filter(m => m.name && m.name.includes('gemini'));
474
- if (items.length > 0) models = items.map(m => {
475
- const id = m.name.replace(/^models\//, '');
476
- return { id, label: id.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()) };
477
- });
449
+ const list = data?.data || data?.models || (Array.isArray(data) ? data : []);
450
+ models = list.map(m => ({ id: m.id || m.model_id, label: m.name || m.display_name || m.id || m.model_id })).filter(m => m.id);
478
451
  }
479
452
  } catch (_) {}
480
453
  }
481
454
  }
482
- const result = models || [];
483
- modelCache.set(agentId, { models: result, timestamp: Date.now() });
484
- return result;
455
+ modelCache.set(agentId, { models, timestamp: Date.now() });
456
+ return models;
485
457
  }
486
458
 
487
459
  const GEMINI_SCOPES = [
@@ -3851,7 +3823,7 @@ registerConvHandlers(wsRouter, {
3851
3823
  });
3852
3824
 
3853
3825
  registerSessionHandlers(wsRouter, {
3854
- db: queries, discoveredAgents, getModelsForAgent, modelCache,
3826
+ db: queries, discoveredAgents, modelCache,
3855
3827
  getAgentDescriptor, activeScripts, broadcastSync,
3856
3828
  startGeminiOAuth, geminiOAuthState: () => geminiOAuthState
3857
3829
  });