agentgui 1.0.422 → 1.0.424

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.
@@ -60,6 +60,14 @@ function checkAgentAuth(agent) {
60
60
  return s;
61
61
  }
62
62
 
63
+ async function acpFetch(port, path, body = null) {
64
+ const opts = { headers: { 'Content-Type': 'application/json' }, signal: AbortSignal.timeout(3000) };
65
+ if (body !== null) { opts.method = 'POST'; opts.body = JSON.stringify(body); }
66
+ const res = await fetch(`http://localhost:${port}${path}`, opts);
67
+ if (!res.ok) return null;
68
+ return res.json();
69
+ }
70
+
63
71
  export function register(router, deps) {
64
72
  const { db, discoveredAgents, getModelsForAgent, modelCache,
65
73
  getAgentDescriptor, activeScripts, broadcastSync, startGeminiOAuth,
@@ -88,51 +96,24 @@ export function register(router, deps) {
88
96
  router.handle('sess.exec', (p) => {
89
97
  const limit = Math.min(parseInt(p.limit || '1000'), 5000);
90
98
  const offset = Math.max(parseInt(p.offset || '0'), 0);
91
- const filterType = p.filterType || null;
92
- const data = {
93
- sessionId: p.id, events: [], total: 0, limit, offset, hasMore: false,
94
- metadata: { status: 'pending', startTime: Date.now(), duration: 0, eventCount: 0 }
95
- };
96
- if (filterType) data.events = data.events.filter(e => e.type === filterType);
97
- return data;
99
+ return { sessionId: p.id, events: [], total: 0, limit, offset, hasMore: false, metadata: { status: 'pending', startTime: Date.now(), duration: 0, eventCount: 0 } };
98
100
  });
99
101
 
100
- router.handle('agent.ls', () => {
101
- // Get local agents only (avoid external HTTP calls in WebSocket to prevent recursion)
102
- const localAgents = discoveredAgents.map(agent => ({
103
- id: agent.id,
104
- name: agent.name,
105
- icon: agent.icon,
106
- path: agent.path,
107
- protocol: agent.protocol || 'unknown',
108
- description: agent.description || '',
109
- status: 'available'
110
- }));
111
-
112
- return { agents: localAgents };
113
- });
102
+ router.handle('agent.ls', () => ({
103
+ agents: discoveredAgents.map(a => ({
104
+ id: a.id, name: a.name, icon: a.icon, path: a.path,
105
+ protocol: a.protocol || 'unknown', description: a.description || '', status: 'available'
106
+ }))
107
+ }));
114
108
 
115
109
  router.handle('agent.subagents', async (p) => {
116
110
  const agent = discoveredAgents.find(x => x.id === p.id);
117
- if (!agent) return { subAgents: [] };
111
+ if (!agent || agent.protocol !== 'acp') return { subAgents: [] };
118
112
  try {
119
- const port = agent.acpPort || 8080;
120
- const res = await fetch(`http://localhost:${port}/agents/search`, {
121
- method: 'POST',
122
- headers: { 'Content-Type': 'application/json' },
123
- body: JSON.stringify({}),
124
- signal: AbortSignal.timeout(3000)
125
- });
126
- if (!res.ok) return { subAgents: [] };
127
- const data = await res.json();
128
- const subAgents = (data.agents || []).map(a => ({
129
- id: a.agent_id || a.id,
130
- name: a.metadata?.ref?.name || a.name || a.agent_id || a.id
131
- }));
132
- return { subAgents };
133
- } catch (_) {
134
- return { subAgents: [] };
135
- }
113
+ const data = await acpFetch(agent.acpPort || 8080, '/agents/search', {});
114
+ const list = Array.isArray(data) ? data : (data?.agents || []);
115
+ return { subAgents: list.map(a => ({ id: a.agent_id || a.id, name: a.metadata?.ref?.name || a.name || a.agent_id || a.id })) };
116
+ } catch (_) { return { subAgents: [] }; }
136
117
  });
137
118
 
138
119
  router.handle('agent.get', (p) => {
@@ -150,6 +131,59 @@ export function register(router, deps) {
150
131
  router.handle('agent.models', async (p) => {
151
132
  const cached = modelCache.get(p.id);
152
133
  if (cached && (Date.now() - cached.ts) < 300000) return { models: cached.models };
134
+ const agent = discoveredAgents.find(x => x.id === p.id);
135
+ if (agent?.protocol === 'acp') {
136
+ const port = agent.acpPort || 8080;
137
+ try {
138
+ const data = await acpFetch(port, '/v1/models');
139
+ const models = (data?.data || data?.models || []).map(m => ({
140
+ id: m.id || m.model_id,
141
+ label: m.name || m.display_name || m.id || m.model_id
142
+ })).filter(m => m.id);
143
+ if (models.length > 0) { modelCache.set(p.id, { models, ts: Date.now() }); return { models }; }
144
+ } catch (_) {}
145
+ try {
146
+ const data = await acpFetch(port, '/agents/search', {});
147
+ const list = Array.isArray(data) ? data : (data?.agents || []);
148
+ const allModels = new Map();
149
+ for (const a of list) {
150
+ const agentId = a.agent_id || a.id;
151
+ const name = a.metadata?.ref?.name || a.name || agentId;
152
+ if (agentId && name) allModels.set(agentId, name);
153
+ for (const m of (a.metadata?.models || a.specs?.models || [])) {
154
+ const id = m.id || m;
155
+ if (id) allModels.set(id, m.name || m.label || id);
156
+ }
157
+ try {
158
+ const desc = await acpFetch(port, `/agents/${agentId}/descriptor`);
159
+ const enumVals = desc?.specs?.config?.properties?.model?.enum || desc?.specs?.input?.properties?.model?.enum || [];
160
+ for (const v of enumVals) allModels.set(v, v);
161
+ } catch (_) {}
162
+ }
163
+ if (allModels.size > 0) {
164
+ const models = Array.from(allModels.entries()).map(([id, label]) => ({ id, label }));
165
+ modelCache.set(p.id, { models, ts: Date.now() });
166
+ return { models };
167
+ }
168
+ } catch (_) {}
169
+ }
170
+ const acpAgents = discoveredAgents.filter(x => x.protocol === 'acp');
171
+ for (const acpAgent of acpAgents) {
172
+ const port = acpAgent.acpPort || 8080;
173
+ try {
174
+ const desc = await acpFetch(port, `/agents/${p.id}/descriptor`);
175
+ if (desc) {
176
+ const enumVals = desc?.specs?.config?.properties?.model?.enum || desc?.specs?.input?.properties?.model?.enum || [];
177
+ if (enumVals.length > 0) {
178
+ const models = enumVals.map(v => ({ id: v, label: v }));
179
+ modelCache.set(p.id, { models, ts: Date.now() });
180
+ return { models };
181
+ }
182
+ const name = desc?.metadata?.ref?.name;
183
+ if (name) { const models = [{ id: p.id, label: name }]; modelCache.set(p.id, { models, ts: Date.now() }); return { models }; }
184
+ }
185
+ } catch (_) {}
186
+ }
153
187
  try {
154
188
  const models = await getModelsForAgent(p.id);
155
189
  modelCache.set(p.id, { models, ts: Date.now() });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.422",
3
+ "version": "1.0.424",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
@@ -363,6 +363,7 @@ class AgentGUIClient {
363
363
  this.ui.cliSelector.addEventListener('change', () => {
364
364
  if (!this._agentLocked) {
365
365
  this.loadSubAgentsForCli(this.ui.cliSelector.value);
366
+ this.loadModelsForAgent(this.ui.cliSelector.value);
366
367
  this.saveAgentAndModelToConversation();
367
368
  }
368
369
  });
@@ -1874,6 +1875,7 @@ class AgentGUIClient {
1874
1875
  .map(a => `<option value="${a.id}">${a.name}</option>`)
1875
1876
  .join('');
1876
1877
  this.ui.agentSelector.style.display = 'inline-block';
1878
+ this.loadModelsForAgent(this.getEffectiveAgentId());
1877
1879
  }
1878
1880
  } catch (_) {
1879
1881
  // No sub-agents available for this CLI tool — keep hidden