open-agents-ai 0.103.66 → 0.103.67

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 +55 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12402,14 +12402,28 @@ async function handleCmd(cmd) {
12402
12402
  }
12403
12403
 
12404
12404
  // riResult and riTargetPeer are available from either path above
12405
- // Check if the invoke returned an error message instead of real data
12405
+ // Check if the invoke returned an error message instead of real data.
12406
+ // IMPORTANT: Only flag short non-JSON strings as errors. Valid inference
12407
+ // responses are JSON with model/response/choices \u2014 the model's natural
12408
+ // language output often contains words like "error" or "not found" which
12409
+ // would cause false positives if we checked the entire JSON string.
12406
12410
  var riIsError = false;
12407
12411
  if (typeof riResult === 'string') {
12408
- var riLower = riResult.toLowerCase();
12409
- if (riLower.includes('unauthorized') || riLower.includes('forbidden') ||
12410
- riLower.includes('not found') || riLower.includes('error') ||
12411
- riLower.includes('payment') || riLower.includes('rejected')) {
12412
- riIsError = true;
12412
+ // Try to parse as JSON \u2014 if it has model+response or choices, it's valid
12413
+ var riParsedCheck = null;
12414
+ try { riParsedCheck = JSON.parse(riResult); } catch {}
12415
+ if (riParsedCheck && typeof riParsedCheck === 'object' &&
12416
+ (riParsedCheck.model || riParsedCheck.choices || riParsedCheck.response !== undefined)) {
12417
+ // Valid inference response \u2014 NOT an error
12418
+ riIsError = false;
12419
+ } else {
12420
+ // Non-JSON or unstructured response \u2014 check for error keywords
12421
+ var riLower = riResult.toLowerCase();
12422
+ if (riLower.includes('unauthorized') || riLower.includes('forbidden') ||
12423
+ riLower.includes('not found') || riLower.includes('error') ||
12424
+ riLower.includes('payment') || riLower.includes('rejected')) {
12425
+ riIsError = true;
12426
+ }
12413
12427
  }
12414
12428
  }
12415
12429
  if (riIsError) {
@@ -12993,22 +13007,51 @@ async function handleCmd(cmd) {
12993
13007
  // Register system_metrics capability \u2014 returns CPU/GPU/memory utilization
12994
13008
  if (typeof nexus.registerCapability === 'function') {
12995
13009
  nexus.registerCapability('system_metrics', async (request, stream) => {
12996
- // Auth check for system_metrics too
13010
+ // Collect input via stream data events (auth_key arrives in invoke.chunk, NOT invoke.open)
13011
+ var smDataChunks = [];
13012
+ var smInputDone = false;
13013
+ stream.onData(function(msg) {
13014
+ if (msg.type === 'invoke.chunk') {
13015
+ smDataChunks.push(typeof msg.data === 'string' ? msg.data : JSON.stringify(msg.data));
13016
+ }
13017
+ if (msg.type === 'invoke.done' || msg.type === 'invoke.end') {
13018
+ smInputDone = true;
13019
+ }
13020
+ });
13021
+
13022
+ // Accept invocation so consumer sends data
13023
+ await stream.write({ type: 'invoke.accept', version: 1, requestId: request.requestId, accepted: true });
13024
+
13025
+ // Wait briefly for data (auth key arrives in chunk)
13026
+ var smWait = 0;
13027
+ while (!smInputDone && smDataChunks.length === 0 && smWait < 2000) {
13028
+ await new Promise(function(r) { setTimeout(r, 10); });
13029
+ smWait += 10;
13030
+ }
13031
+
13032
+ // Auth check \u2014 extract auth_key from chunk data
12997
13033
  if (exposeAuthKey) {
12998
13034
  var smAuthKey = '';
12999
- if (request.data && typeof request.data === 'object' && request.data.auth_key) {
13000
- smAuthKey = request.data.auth_key;
13001
- } else if (request.metadata && request.metadata.auth_key) {
13035
+ var smPayload = smDataChunks.join('');
13036
+ try {
13037
+ var smParsed = JSON.parse(smPayload);
13038
+ if (smParsed && typeof smParsed === 'object' && smParsed.auth_key) {
13039
+ smAuthKey = smParsed.auth_key;
13040
+ }
13041
+ } catch {}
13042
+ // Fallback: check invoke.open metadata (future-proofing)
13043
+ if (!smAuthKey && request.metadata && request.metadata.auth_key) {
13002
13044
  smAuthKey = request.metadata.auth_key;
13003
13045
  }
13004
13046
  if (smAuthKey !== exposeAuthKey) {
13005
- await stream.write({ type: 'invoke.accept', version: 1, requestId: request.requestId, accepted: false });
13047
+ dlog('system_metrics: auth REJECTED from ' + (request.from || 'unknown'));
13048
+ await stream.write({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'error', data: 'Unauthorized' });
13006
13049
  await stream.write({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
13007
13050
  stream.close();
13008
13051
  return;
13009
13052
  }
13053
+ dlog('system_metrics: auth OK');
13010
13054
  }
13011
- await stream.write({ type: 'invoke.accept', version: 1, requestId: request.requestId, accepted: true });
13012
13055
  try {
13013
13056
  var os = require('os');
13014
13057
  var loads = os.loadavg();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.103.66",
3
+ "version": "0.103.67",
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",