agentgui 1.0.988 → 1.0.990

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.
@@ -66,57 +66,6 @@ export function findCommand(cmd, rootDir) {
66
66
  return null;
67
67
  }
68
68
 
69
- export async function queryACPServerAgents(baseUrl) {
70
- const endpoint = baseUrl.endsWith('/') ? baseUrl + 'agents/search' : baseUrl + '/agents/search';
71
- try {
72
- const response = await fetch(endpoint, {
73
- method: 'POST',
74
- headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
75
- body: JSON.stringify({}),
76
- signal: AbortSignal.timeout(5000)
77
- });
78
- if (!response.ok) {
79
- console.error(`Failed to query ACP agents from ${baseUrl}: ${response.status}`);
80
- return [];
81
- }
82
- const data = await response.json();
83
- if (!data?.agents || !Array.isArray(data.agents)) {
84
- console.error(`Invalid agents response from ${baseUrl}`);
85
- return [];
86
- }
87
- return data.agents.map(agent => ({
88
- id: agent.agent_id || agent.id,
89
- name: agent.metadata?.ref?.name || agent.name || 'Unknown Agent',
90
- metadata: {
91
- ref: {
92
- name: agent.metadata?.ref?.name,
93
- version: agent.metadata?.ref?.version,
94
- url: agent.metadata?.ref?.url,
95
- tags: agent.metadata?.ref?.tags
96
- },
97
- description: agent.metadata?.description,
98
- author: agent.metadata?.author,
99
- license: agent.metadata?.license
100
- },
101
- specs: agent.specs ? {
102
- capabilities: agent.specs.capabilities,
103
- input_schema: agent.specs.input_schema || agent.specs.input,
104
- output_schema: agent.specs.output_schema || agent.specs.output,
105
- thread_state_schema: agent.specs.thread_state_schema || agent.specs.thread_state,
106
- config_schema: agent.specs.config_schema || agent.specs.config,
107
- custom_streaming_update_schema: agent.specs.custom_streaming_update_schema || agent.specs.custom_streaming_update
108
- } : null,
109
- custom_data: agent.custom_data,
110
- icon: agent.metadata?.ref?.name?.charAt(0) || 'A',
111
- protocol: 'acp',
112
- path: baseUrl
113
- }));
114
- } catch (error) {
115
- console.error(`ACP agents query failed for ${baseUrl}: ${error.message}`);
116
- return [];
117
- }
118
- }
119
-
120
69
  export function discoverAgents(rootDir) {
121
70
  const agents = [];
122
71
  for (const bin of BINARIES) {
@@ -145,17 +94,6 @@ export function discoverAgents(rootDir) {
145
94
  return filtered;
146
95
  }
147
96
 
148
- export async function discoverExternalACPServers(discoveredAgents) {
149
- const externalAgents = [];
150
- for (const agent of discoveredAgents.filter(a => a.protocol === 'acp' && a.acpPort)) {
151
- try {
152
- const agents = await queryACPServerAgents(`http://localhost:${agent.acpPort}`);
153
- externalAgents.push(...agents);
154
- } catch (_) {}
155
- }
156
- return externalAgents;
157
- }
158
-
159
97
  export async function initializeAgentDiscovery(discoveredAgents, rootDir, logError) {
160
98
  try {
161
99
  const agents = discoverAgents(rootDir);
@@ -41,7 +41,6 @@ export function createOnServerReady({ queries, broadcastSync, warmAssetCache, st
41
41
  console.log('[ACP] On-demand startup enabled (ACP tools start when first used)');
42
42
  setTimeout(() => {
43
43
  const acpStatus = getACPStatus();
44
- for (const s of acpStatus) { if (s.healthy) { const agent = discoveredAgents.find(a => a.id === s.id); if (agent) agent.acpPort = s.port; } }
45
44
  if (acpStatus.length > 0) console.log(`[ACP] Tools ready: ${acpStatus.filter(s => s.healthy).map(s => s.id + ':' + s.port).join(', ') || 'none healthy yet'}`);
46
45
  }, 6000);
47
46
  }).catch(err => console.error('[ACP] Startup error:', err.message));
@@ -45,7 +45,12 @@ export function makeGetModelsForAgent(deps) {
45
45
  { id: 'opus', label: 'Opus' }
46
46
  ];
47
47
  } else {
48
- const agent = discoveredAgents.find(a => a.id === agentId);
48
+ // The client sends canonical registry ids ('opencode', 'kilo', 'codex'),
49
+ // but discoverAgents() replaces each found ACP agent with its cli-wrapper
50
+ // entry whose own id is prefixed ('cli-opencode') and whose acpId carries
51
+ // the original id. Match on acpId too so model discovery resolves the
52
+ // wrapper instead of finding nothing and silently returning [] models.
53
+ const agent = discoveredAgents.find(a => a.id === agentId || a.acpId === agentId);
49
54
  if (agent?.protocol === 'acp') {
50
55
  await ensureRunning(agentId);
51
56
  try { models = await queryACPModels(agentId); } catch (_) {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.988",
3
+ "version": "1.0.990",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "electron/main.js",
package/server.js CHANGED
@@ -9,7 +9,7 @@ import { createHistoryRouter } from 'ccsniff';
9
9
  import { queries } from './database.js';
10
10
  import { runClaudeWithStreaming } from './lib/claude-runner-run.js';
11
11
  import { initializeDescriptors, getAgentDescriptor } from './lib/agent-descriptors.js';
12
- import { discoverExternalACPServers, initializeAgentDiscovery } from './lib/agent-discovery.js';
12
+ import { initializeAgentDiscovery } from './lib/agent-discovery.js';
13
13
  import { register as registerWsHandlers } from './lib/ws-handlers-util.js';
14
14
  import { BROADCAST_TYPES } from './lib/broadcast.js';
15
15
  import { WSOptimizer } from './lib/ws-optimizer.js';
package/test.js CHANGED
@@ -340,6 +340,25 @@ await ok('cross-tab-storage: "updated in another tab" banner on stale load', ()
340
340
  }
341
341
  });
342
342
 
343
+ await ok('agents.models: resolves cli-wrapper by acpId (registry id, not wrapper id)', async () => {
344
+ // The client picker sends canonical registry ids ('opencode'), but
345
+ // discoverAgents() stores only the cli-wrapper entry ('cli-opencode',
346
+ // acpId:'opencode'). getModelsForAgent must resolve via acpId, else model
347
+ // discovery silently returns [] for every ACP agent (witnessed regression).
348
+ const { makeGetModelsForAgent } = await import('./lib/server-utils.js');
349
+ const discoveredAgents = [{ id: 'cli-opencode', protocol: 'cli-wrapper', acpId: 'opencode' }];
350
+ const calls = [];
351
+ const getModels = makeGetModelsForAgent({
352
+ modelCache: new Map(),
353
+ discoveredAgents,
354
+ ensureRunning: async (id) => { calls.push(['ensure', id]); return 18100; },
355
+ queryACPModels: async (id) => { calls.push(['query', id]); return [{ id: 'm1', label: 'M1' }]; },
356
+ });
357
+ const models = await getModels('opencode');
358
+ assert.deepEqual(calls, [['ensure', 'opencode'], ['query', 'opencode']], 'should ensureRunning + query with acpId');
359
+ assert.equal(models.length, 1, 'should return the ACP-provided models, not an empty list');
360
+ });
361
+
343
362
  console.log(`\n${passed} passed, ${failed} failed, ${skipped} skipped`);
344
363
  process.exit(failed === 0 ? 0 : 1);
345
364
  }; run();