open-agents-ai 0.103.77 → 0.103.79

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.
Files changed (2) hide show
  1. package/dist/index.js +77 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12224,6 +12224,21 @@ async function handleCmd(cmd) {
12224
12224
  const room = rooms.get(args.room_id);
12225
12225
  if (!room) { writeResp(id, { ok: false, output: 'Not in room: ' + args.room_id + '. Join it first.' }); return; }
12226
12226
  const msgId = await room.send(args.message, { format: 'text/plain' });
12227
+ // Relay to NATS for frontend visibility (public room messages)
12228
+ if (_natsConn && _natsCodec) {
12229
+ try {
12230
+ _natsConn.publish('nexus.rooms.chat', _natsCodec.encode(JSON.stringify({
12231
+ type: 'nexus.room.message',
12232
+ roomId: args.room_id,
12233
+ peerId: nexus.peerId,
12234
+ agentName: agentName,
12235
+ content: String(args.message).slice(0, 500),
12236
+ timestamp: Date.now(),
12237
+ })));
12238
+ } catch (natsRelayErr) {
12239
+ dlog('NATS chat relay error: ' + (natsRelayErr.message || natsRelayErr));
12240
+ }
12241
+ }
12227
12242
  writeResp(id, { ok: true, output: 'Message sent (id: ' + msgId + ')' });
12228
12243
  break;
12229
12244
  }
@@ -13478,6 +13493,24 @@ process.on('unhandledRejection', (reason) => {
13478
13493
  nexus.on('message', ({ roomId, message }) => {
13479
13494
  // Already handled by per-room listener, but log globally
13480
13495
  console.log('[msg] ' + roomId + ' from ' + (message?.sender || '?').slice(0, 16));
13496
+ // Relay received messages to NATS for frontend visibility
13497
+ if (_natsConn && _natsCodec && message && message.sender !== nexus.peerId) {
13498
+ try {
13499
+ var _msgContent = '';
13500
+ if (message.payload && message.payload.content) _msgContent = String(message.payload.content).slice(0, 500);
13501
+ else if (typeof message.content === 'string') _msgContent = message.content.slice(0, 500);
13502
+ if (_msgContent) {
13503
+ _natsConn.publish('nexus.rooms.chat', _natsCodec.encode(JSON.stringify({
13504
+ type: 'nexus.room.message',
13505
+ roomId: roomId,
13506
+ peerId: message.sender || '',
13507
+ agentName: message.senderName || (message.sender ? message.sender.slice(0, 12) : 'anon'),
13508
+ content: _msgContent,
13509
+ timestamp: message.timestamp || Date.now(),
13510
+ })));
13511
+ }
13512
+ } catch {}
13513
+ }
13481
13514
  });
13482
13515
  nexus.on('dm', ({ from, content, format, messageId }) => {
13483
13516
  // Log DMs to inbox/dm/
@@ -30673,7 +30706,8 @@ async function fetchOllamaModels(baseUrl) {
30673
30706
  sizeBytes: m.size,
30674
30707
  modified: formatRelativeTime(m.modified_at),
30675
30708
  parameterSize: m.details?.parameter_size,
30676
- contextLength: void 0
30709
+ contextLength: void 0,
30710
+ caps: void 0
30677
30711
  })).sort((a, b) => b.sizeBytes - a.sizeBytes);
30678
30712
  const normalized = normalizeBaseUrl(baseUrl);
30679
30713
  const showResults = await Promise.allSettled(result.map((m) => fetch(`${normalized}/api/show`, {
@@ -30702,6 +30736,34 @@ async function fetchOllamaModels(baseUrl) {
30702
30736
  }
30703
30737
  }
30704
30738
  }
30739
+ const modelCaps = { vision: false, toolUse: false, thinking: false };
30740
+ const nameLower = result[i].name.toLowerCase();
30741
+ if (Array.isArray(show.capabilities)) {
30742
+ if (show.capabilities.includes("vision"))
30743
+ modelCaps.vision = true;
30744
+ if (show.capabilities.includes("tools"))
30745
+ modelCaps.toolUse = true;
30746
+ if (show.capabilities.includes("thinking"))
30747
+ modelCaps.thinking = true;
30748
+ }
30749
+ if (show.model_info) {
30750
+ for (const key of Object.keys(show.model_info)) {
30751
+ const k = key.toLowerCase();
30752
+ if (k.includes("vision.block_count") || k.includes("clip.") || k.includes("image_token_id") || k.includes("projector")) {
30753
+ const val = show.model_info[key];
30754
+ if (val !== null && val !== void 0 && val !== 0 && val !== "") {
30755
+ modelCaps.vision = true;
30756
+ }
30757
+ }
30758
+ }
30759
+ }
30760
+ if (/qwen3|qwen2\.5|llama3\.[13]|mistral|mixtral|command-r|gemma3|devstral|deepseek/.test(nameLower)) {
30761
+ modelCaps.toolUse = true;
30762
+ }
30763
+ if (show.template && (show.template.includes("<think>") || show.template.includes("thinking"))) {
30764
+ modelCaps.thinking = true;
30765
+ }
30766
+ result[i].caps = modelCaps;
30705
30767
  }
30706
30768
  return result;
30707
30769
  }
@@ -31074,6 +31136,16 @@ function formatContextLength(tokens) {
31074
31136
  return `${Math.round(tokens / 1024)}K ctx`;
31075
31137
  return `${tokens} ctx`;
31076
31138
  }
31139
+ function formatCaps(caps) {
31140
+ const tags = [];
31141
+ if (caps.vision)
31142
+ tags.push("vision");
31143
+ if (caps.toolUse)
31144
+ tags.push("tools");
31145
+ if (caps.thinking)
31146
+ tags.push("think");
31147
+ return tags.join("+");
31148
+ }
31077
31149
  function formatRelativeTime(iso) {
31078
31150
  const now = Date.now();
31079
31151
  const then = new Date(iso).getTime();
@@ -35207,10 +35279,11 @@ async function showModelPicker(ctx, local = false) {
35207
35279
  const available = liveModelNames.has(h.value) ? "" : c2.yellow(" [offline]");
35208
35280
  const meta = modelMap.get(h.value);
35209
35281
  const ctx2 = meta?.contextLength ? ` ${formatContextLength(meta.contextLength)}` : "";
35282
+ const capStr = meta?.caps ? ` ${formatCaps(meta.caps)}` : "";
35210
35283
  items.push({
35211
35284
  key: h.value,
35212
35285
  label: h.value,
35213
- detail: `${uses}${ctx2}${available}`
35286
+ detail: `${uses}${ctx2}${capStr}${available}`
35214
35287
  });
35215
35288
  }
35216
35289
  items.push({ key: "__header_available__", label: c2.dim("\u2500\u2500 Available \u2500\u2500"), detail: "" });
@@ -35220,10 +35293,11 @@ async function showModelPicker(ctx, local = false) {
35220
35293
  if (history.length > 0 && historyKeys.has(m.name))
35221
35294
  continue;
35222
35295
  const ctx2 = m.contextLength ? formatContextLength(m.contextLength) : "";
35296
+ const capStr = m.caps ? formatCaps(m.caps) : "";
35223
35297
  items.push({
35224
35298
  key: m.name,
35225
35299
  label: m.name,
35226
- detail: [m.parameterSize, ctx2, m.size, m.modified].filter(Boolean).join(" ")
35300
+ detail: [m.parameterSize, ctx2, capStr, m.modified].filter(Boolean).join(" ")
35227
35301
  });
35228
35302
  }
35229
35303
  const result = await tuiSelect({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.103.77",
3
+ "version": "0.103.79",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",