@openagents-org/agent-connector 0.1.6 → 0.1.8

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/package.json +1 -1
  2. package/src/daemon.js +80 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagents-org/agent-connector",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Agent management CLI and library for OpenAgents — install, configure, and run AI coding agents",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/daemon.js CHANGED
@@ -471,13 +471,87 @@ class Daemon {
471
471
  }
472
472
  }
473
473
 
474
+ /**
475
+ * Build workspace context preamble for CLI agents.
476
+ * Teaches the agent about shared workspace APIs (browser, files).
477
+ */
478
+ /**
479
+ * On Windows, resolve a .cmd shim to the underlying node script
480
+ * so we can spawn directly with node (avoiding cmd.exe argument limits).
481
+ */
482
+ _resolveWindowsBinary(binary, env) {
483
+ const { execSync } = require('child_process');
484
+ try {
485
+ // Find the .cmd shim
486
+ const cmdPath = execSync(`where ${binary}`, {
487
+ encoding: 'utf-8', timeout: 5000, env,
488
+ }).split(/\r?\n/)[0].trim();
489
+
490
+ if (cmdPath.endsWith('.cmd')) {
491
+ // Read the .cmd file to find the target JS script
492
+ const cmdContent = fs.readFileSync(cmdPath, 'utf-8');
493
+ // npm .cmd shims have: "%~dp0\node_modules\...\bin\cli.js" %*
494
+ // or: @IF EXIST "%~dp0\node.exe" ... "%~dp0\node_modules\...\cli.js" %*
495
+ const match = cmdContent.match(/"([^"]+\.js)"/);
496
+ if (match) {
497
+ const jsPath = match[1].replace('%~dp0\\', path.dirname(cmdPath) + '\\');
498
+ return { binary: process.execPath, prefix: [jsPath] };
499
+ }
500
+ }
501
+ } catch {}
502
+
503
+ // Fallback: use cmd.exe /C (may truncate long args)
504
+ return { binary: process.env.COMSPEC || 'cmd.exe', prefix: ['/C', binary] };
505
+ }
506
+
507
+ _buildWorkspaceContext(agentCfg, network) {
508
+ const baseUrl = 'https://workspace-endpoint.openagents.org';
509
+ const h = `Authorization: Bearer ${network.token}`;
510
+ const wsId = network.id;
511
+ const name = agentCfg.name;
512
+
513
+ return [
514
+ '=== WORKSPACE CONTEXT ===',
515
+ `You are agent "${name}" in workspace "${network.slug}".`,
516
+ 'You have access to shared workspace tools via HTTP API. Use your exec tool to run curl commands.',
517
+ '',
518
+ '## Shared Browser',
519
+ 'The workspace has a shared browser visible to all users and agents.',
520
+ `Open tab: curl -s -X POST ${baseUrl}/v1/browser/tabs -H "${h}" -H "Content-Type: application/json" -d '{"url":"URL","network":"${wsId}","source":"openagents:${name}"}'`,
521
+ `Read page: curl -s -H "${h}" ${baseUrl}/v1/browser/tabs/TAB_ID/snapshot`,
522
+ `Screenshot: curl -s -H "${h}" ${baseUrl}/v1/browser/tabs/TAB_ID/screenshot`,
523
+ `Navigate: curl -s -X POST ${baseUrl}/v1/browser/tabs/TAB_ID/navigate -H "${h}" -H "Content-Type: application/json" -d '{"url":"URL"}'`,
524
+ `Click: curl -s -X POST ${baseUrl}/v1/browser/tabs/TAB_ID/click -H "${h}" -H "Content-Type: application/json" -d '{"selector":"CSS_SELECTOR"}'`,
525
+ `Type: curl -s -X POST ${baseUrl}/v1/browser/tabs/TAB_ID/type -H "${h}" -H "Content-Type: application/json" -d '{"selector":"CSS_SELECTOR","text":"TEXT"}'`,
526
+ `Close: curl -s -X DELETE -H "${h}" ${baseUrl}/v1/browser/tabs/TAB_ID`,
527
+ `List tabs: curl -s -H "${h}" ${baseUrl}/v1/browser/tabs?network=${wsId}`,
528
+ '(Replace TAB_ID with the id from the open response)',
529
+ '',
530
+ '## Workspace Files',
531
+ `List: curl -s -H "${h}" ${baseUrl}/v1/files?network=${wsId}`,
532
+ `Read: curl -s -H "${h}" ${baseUrl}/v1/files/FILE_PATH?network=${wsId}`,
533
+ `Write: curl -s -X PUT ${baseUrl}/v1/files/FILE_PATH -H "${h}" -H "Content-Type: application/json" -d '{"content":"...","network":"${wsId}"}'`,
534
+ '=== END WORKSPACE CONTEXT ===',
535
+ '',
536
+ ].join('\n');
537
+ }
538
+
474
539
  _runCliAgent(binary, message, channel, agentCfg, network, env) {
475
540
  return new Promise((resolve, reject) => {
476
541
  const sessionKey = `openagents-${network.id.slice(0, 8)}-${channel.slice(-8)}`;
477
542
  const agentId = agentCfg.openclaw_agent_id || 'main';
478
543
 
544
+ // Prepend workspace context on first message in a session
545
+ const contextKey = `${agentCfg.name}:${sessionKey}`;
546
+ let fullMessage = message;
547
+ if (!this._sessionContextSent) this._sessionContextSent = new Set();
548
+ if (!this._sessionContextSent.has(contextKey)) {
549
+ fullMessage = this._buildWorkspaceContext(agentCfg, network) + message;
550
+ this._sessionContextSent.add(contextKey);
551
+ }
552
+
479
553
  const args = ['agent', '--local', '--agent', agentId,
480
- '--session-id', sessionKey, '--message', message, '--json'];
554
+ '--session-id', sessionKey, '--message', fullMessage, '--json'];
481
555
 
482
556
  this._log(`${agentCfg.name} CLI: ${binary} ${args.slice(0, 5).join(' ')} ...`);
483
557
 
@@ -489,9 +563,6 @@ class Daemon {
489
563
  }
490
564
  }
491
565
 
492
- // On Windows, .cmd shims need shell:true but that breaks argument
493
- // quoting. Use execFileSync-style approach: resolve the .cmd to its
494
- // target and run directly, or use spawn without shell and full path.
495
566
  let spawnBinary = binary;
496
567
  let spawnArgs = args;
497
568
  const spawnOpts = {
@@ -501,11 +572,11 @@ class Daemon {
501
572
  };
502
573
 
503
574
  if (IS_WINDOWS) {
504
- // Find the actual .cmd shim and invoke via cmd.exe /C with proper quoting
505
- spawnBinary = process.env.COMSPEC || 'cmd.exe';
506
- // Wrap argument containing spaces in double quotes for cmd.exe
507
- const quotedArgs = args.map((a) => a.includes(' ') ? `"${a}"` : a);
508
- spawnArgs = ['/C', binary, ...quotedArgs];
575
+ // Resolve .cmd shim to actual node script to avoid cmd.exe
576
+ // argument mangling and length limits
577
+ const resolved = this._resolveWindowsBinary(binary, spawnEnv);
578
+ spawnBinary = resolved.binary;
579
+ spawnArgs = [...resolved.prefix, ...args];
509
580
  }
510
581
 
511
582
  const proc = spawn(spawnBinary, spawnArgs, spawnOpts);