open-agents-ai 0.103.30 → 0.103.32

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 +54 -31
  2. package/package.json +2 -2
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
- var riOutput = {
12406
- success: true,
12407
- model: riModel,
12408
- peer: riTargetPeer,
12409
- capability: riCapName,
12410
- result: riResult,
12411
- };
12412
- writeResp(id, { ok: true, output: JSON.stringify(riOutput, null, 2) });
12405
+ // Check if the invoke returned an error message instead of real data
12406
+ var riIsError = false;
12407
+ 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;
12413
+ }
12414
+ }
12415
+ if (riIsError) {
12416
+ writeResp(id, { ok: false, output: 'Remote peer error: ' + riResult });
12417
+ } else {
12418
+ var riOutput = {
12419
+ success: true,
12420
+ model: riModel,
12421
+ peer: riTargetPeer,
12422
+ capability: riCapName,
12423
+ result: riResult,
12424
+ };
12425
+ writeResp(id, { ok: true, output: JSON.stringify(riOutput, null, 2) });
12426
+ }
12413
12427
  break;
12414
12428
  }
12415
12429
  case 'store_content': {
@@ -12692,26 +12706,9 @@ async function handleCmd(cmd) {
12692
12706
  const logFile = join(invocationsDir, Date.now() + '-' + capName + '.json');
12693
12707
  try { writeFileSync(logFile, JSON.stringify(logEntry, null, 2)); } catch {}
12694
12708
 
12695
- // Auth key validation \u2014 if expose was started with auth_key, require it
12696
- if (exposeAuthKey) {
12697
- var reqAuthKey = '';
12698
- if (request.data && typeof request.data === 'object' && request.data.auth_key) {
12699
- reqAuthKey = request.data.auth_key;
12700
- } else if (request.metadata && request.metadata.auth_key) {
12701
- reqAuthKey = request.metadata.auth_key;
12702
- }
12703
- if (reqAuthKey !== exposeAuthKey) {
12704
- dlog('expose: auth REJECTED for ' + capName + ' from ' + (request.from || 'unknown'));
12705
- await stream.write({ type: 'invoke.accept', version: 1, requestId: request.requestId, accepted: false });
12706
- await stream.write({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'error', data: 'Unauthorized \u2014 invalid or missing auth key' });
12707
- await stream.write({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
12708
- stream.close();
12709
- return;
12710
- }
12711
- dlog('expose: auth OK for ' + capName);
12712
- }
12713
-
12714
12709
  // Collect input via stream data events
12710
+ // NOTE: auth_key arrives in invoke.chunk data, NOT in invoke.open (request).
12711
+ // We must accept + read data FIRST, then validate auth.
12715
12712
  let prompt = '';
12716
12713
  var dataChunks = [];
12717
12714
  var inputDone = false;
@@ -12725,7 +12722,7 @@ async function handleCmd(cmd) {
12725
12722
  }
12726
12723
  });
12727
12724
 
12728
- // Accept
12725
+ // Accept the invocation so the consumer sends data
12729
12726
  await stream.write({
12730
12727
  type: 'invoke.accept', version: 1,
12731
12728
  requestId: request.requestId, accepted: true,
@@ -12740,6 +12737,31 @@ async function handleCmd(cmd) {
12740
12737
  prompt = dataChunks.join('');
12741
12738
  dlog('expose: received ' + dataChunks.length + ' chunks, prompt_len=' + prompt.length + ' inputDone=' + inputDone);
12742
12739
 
12740
+ // Auth key validation \u2014 check AFTER data is received.
12741
+ // Auth key is in the invoke.chunk data payload, not in invoke.open.
12742
+ if (exposeAuthKey) {
12743
+ var reqAuthKey = '';
12744
+ // Try extracting auth_key from parsed data payload
12745
+ try {
12746
+ var authCheckData = JSON.parse(prompt);
12747
+ if (authCheckData && typeof authCheckData === 'object' && authCheckData.auth_key) {
12748
+ reqAuthKey = authCheckData.auth_key;
12749
+ }
12750
+ } catch (authParseErr) { /* not JSON or no auth_key field */ }
12751
+ // Fallback: check invoke.open metadata (future-proofing)
12752
+ if (!reqAuthKey && request.metadata && request.metadata.auth_key) {
12753
+ reqAuthKey = request.metadata.auth_key;
12754
+ }
12755
+ if (reqAuthKey !== exposeAuthKey) {
12756
+ dlog('expose: auth REJECTED for ' + capName + ' from ' + (request.from || 'unknown'));
12757
+ await stream.write({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'error', data: 'Unauthorized \u2014 invalid or missing auth key' });
12758
+ await stream.write({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
12759
+ stream.close();
12760
+ return;
12761
+ }
12762
+ dlog('expose: auth OK for ' + capName);
12763
+ }
12764
+
12743
12765
  // Forward to Ollama \u2014 supports both flat prompt and structured messages
12744
12766
  try {
12745
12767
  var parsedReq = null;
@@ -29911,7 +29933,7 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
29911
29933
  parameterSize: m.owned_by ?? void 0
29912
29934
  })).sort((a, b) => a.name.localeCompare(b.name));
29913
29935
  }
29914
- async function fetchPeerModels(peerId) {
29936
+ async function fetchPeerModels(peerId, authKey) {
29915
29937
  try {
29916
29938
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
29917
29939
  const { existsSync: existsSync42, readFileSync: readFileSync31 } = await import("node:fs");
@@ -29969,7 +29991,8 @@ async function fetchPeerModels(peerId) {
29969
29991
  try {
29970
29992
  const capsResult = await nexusTool.execute({
29971
29993
  action: "query_peer_caps",
29972
- peer_id: peerId
29994
+ peer_id: peerId,
29995
+ ...authKey ? { auth_key: authKey } : {}
29973
29996
  });
29974
29997
  if (capsResult.success && capsResult.output) {
29975
29998
  let capsData = null;
@@ -30086,7 +30109,7 @@ async function fetchPeerModels(peerId) {
30086
30109
  }
30087
30110
  async function fetchModels(baseUrl, apiKey) {
30088
30111
  if (baseUrl.startsWith("peer://")) {
30089
- return fetchPeerModels(baseUrl.slice(7));
30112
+ return fetchPeerModels(baseUrl.slice(7), apiKey);
30090
30113
  }
30091
30114
  const provider = detectProvider(baseUrl);
30092
30115
  if (provider.id === "ollama") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.103.30",
3
+ "version": "0.103.32",
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",
@@ -81,7 +81,7 @@
81
81
  },
82
82
  "optionalDependencies": {
83
83
  "moondream": "^0.2.0",
84
- "open-agents-nexus": "^1.5.6",
84
+ "open-agents-nexus": "^1.5.8",
85
85
  "viem": "^2.47.4"
86
86
  }
87
87
  }