@virtue-ai/gateway-connect 0.3.4 → 0.3.6

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.
package/README.md CHANGED
@@ -23,7 +23,11 @@ openclaw models auth paste-token --provider openai
23
23
  ### Step 3: Connect to VirtueAI MCP Gateway
24
24
 
25
25
  ```bash
26
+ # Standalone gateway
26
27
  npx @virtue-ai/gateway-connect --gateway-url https://virtueai-agent-gtw-xxxx.ngrok.io
28
+
29
+ # Platform-hosted gateway
30
+ npx @virtue-ai/gateway-connect --gateway-url https://your-domain.ngrok.app/api/gateways/gtw_xxxx
27
31
  ```
28
32
 
29
33
  This will:
@@ -39,7 +43,7 @@ This will:
39
43
  One-shot mode:
40
44
 
41
45
  ```bash
42
- openclaw agent --local --message "What tools do you have?"
46
+ openclaw agent --local --agent main --message "What tools do you have?"
43
47
  ```
44
48
 
45
49
  Interactive TUI mode:
@@ -91,7 +95,9 @@ This approach works with any embedded model provider (not just Claude CLI), beca
91
95
  npx @virtue-ai/gateway-connect [options]
92
96
 
93
97
  Options:
94
- --gateway-url <url> Gateway URL (default: https://virtueai-agent-gtw-l3phon63.ngrok.io)
98
+ --gateway-url <url> Gateway URL (standalone or platform-hosted)
99
+ --api-url <url> Prompt-guard API URL (default: https://agentgateway1.virtueai.io)
100
+ --gateway-id <id> Gateway ID for trajectory recording
95
101
  --model <model> Model to use (e.g. openai/gpt-4o, anthropic/claude-sonnet-4-5)
96
102
  --guard-uuid <uuid> Guard UUID for trajectory recording (or set VIRTUEAI_GUARD_UUID)
97
103
  --help Show help message
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ import { generateTrajectoryPlugin, enableTrajectoryPlugin } from './trajectory-p
27
27
  const CALLBACK_PORT = 19876;
28
28
  const CALLBACK_PATH = '/callback';
29
29
  const REDIRECT_URI = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
30
- const SCOPES = 'claudeai copilot mcp:read mcp:execute mcp:access';
30
+ const DEFAULT_SCOPES = 'claudeai copilot mcp:read mcp:execute mcp:access';
31
31
  const OPENCLAW_DIR = path.join(os.homedir(), '.openclaw');
32
32
  const MCP_CONFIG_PATH = path.join(OPENCLAW_DIR, 'mcp-gateway.json');
33
33
  const OPENCLAW_CONFIG_PATH = path.join(OPENCLAW_DIR, 'openclaw.json');
@@ -102,7 +102,7 @@ function openBrowser(url) {
102
102
  // ---------------------------------------------------------------------------
103
103
  async function authenticate(gatewayUrl) {
104
104
  console.log(' Discovering OAuth endpoints...');
105
- const { data: metadata } = await fetchJson(`${gatewayUrl}/.well-known/oauth-authorization-server`, { method: 'GET' });
105
+ const { data: metadata } = await fetchJson(`${gatewayUrl}/.well-known/oauth-authorization-server`, { method: 'GET', headers: { Accept: 'application/json' } });
106
106
  if (!metadata.authorization_endpoint || !metadata.token_endpoint) {
107
107
  console.error('Error: Could not discover OAuth endpoints from gateway.');
108
108
  console.error('Response:', JSON.stringify(metadata, null, 2));
@@ -111,8 +111,12 @@ async function authenticate(gatewayUrl) {
111
111
  const authEndpoint = metadata.authorization_endpoint;
112
112
  const tokenEndpoint = metadata.token_endpoint;
113
113
  const registerEndpoint = metadata.registration_endpoint;
114
+ const scopes = metadata.scopes_supported
115
+ ? metadata.scopes_supported.join(' ')
116
+ : DEFAULT_SCOPES;
114
117
  console.log(` Auth endpoint: ${authEndpoint}`);
115
118
  console.log(` Token endpoint: ${tokenEndpoint}`);
119
+ console.log(` Scopes: ${scopes}`);
116
120
  console.log(' Registering OAuth client...');
117
121
  const { status: regStatus, data: clientInfo } = await fetchJson(registerEndpoint, {
118
122
  method: 'POST',
@@ -121,7 +125,7 @@ async function authenticate(gatewayUrl) {
121
125
  client_name: 'openclaw-gateway-connect',
122
126
  grant_types: ['authorization_code', 'refresh_token'],
123
127
  redirect_uris: [REDIRECT_URI],
124
- scope: SCOPES,
128
+ scope: scopes,
125
129
  token_endpoint_auth_method: 'none',
126
130
  }),
127
131
  });
@@ -139,7 +143,7 @@ async function authenticate(gatewayUrl) {
139
143
  authUrl.searchParams.set('client_id', clientId);
140
144
  authUrl.searchParams.set('redirect_uri', REDIRECT_URI);
141
145
  authUrl.searchParams.set('response_type', 'code');
142
- authUrl.searchParams.set('scope', SCOPES);
146
+ authUrl.searchParams.set('scope', scopes);
143
147
  authUrl.searchParams.set('state', state);
144
148
  authUrl.searchParams.set('code_challenge', codeChallenge);
145
149
  authUrl.searchParams.set('code_challenge_method', 'S256');
@@ -347,7 +351,7 @@ function writeGatewayConfig(gatewayUrl, accessToken, guardUuid, apiUrl, gatewayI
347
351
  const config = {
348
352
  trajectory: {
349
353
  gatewayUrl,
350
- apiUrl: apiUrl || DEFAULT_API_URL,
354
+ apiUrl: apiUrl || '',
351
355
  gatewayId: gatewayId || DEFAULT_GATEWAY_ID,
352
356
  guardUuid: guardUuid || process.env.VIRTUEAI_GUARD_UUID || '',
353
357
  },
@@ -501,7 +505,7 @@ Supported models:
501
505
  ${TOOLS_PLUGIN_DIR}
502
506
 
503
507
  Start using it:
504
- openclaw agent --local --message "What tools do you have?"
508
+ openclaw agent --local --agent main --message "What tools do you have?"
505
509
 
506
510
  To use a different model:
507
511
  npx @virtue-ai/gateway-connect --gateway-url ${gatewayUrl} --model openai/gpt-4o
@@ -50,7 +50,7 @@ function loadConfig() {
50
50
  const cfg = JSON.parse(raw);
51
51
 
52
52
  const gatewayUrl = cfg._auth?.gatewayUrl ?? cfg.trajectory?.gatewayUrl ?? "";
53
- const apiUrl = cfg.trajectory?.apiUrl ?? gatewayUrl;
53
+ const apiUrl = cfg.trajectory?.apiUrl ?? "";
54
54
  const gatewayId = cfg.trajectory?.gatewayId ?? "";
55
55
  const token = cfg._auth?.accessToken ?? "";
56
56
 
@@ -59,8 +59,13 @@ function loadConfig() {
59
59
  process.env.VIRTUEAI_GUARD_UUID ||
60
60
  DEFAULT_GUARD_UUID;
61
61
 
62
- if (!apiUrl || !token) return null;
63
- return { gatewayUrl, apiUrl, gatewayId, token, guardUuid };
62
+ // If explicit apiUrl is set, use old path; otherwise derive from gatewayUrl
63
+ const trajectoryEndpoint = apiUrl
64
+ ? apiUrl + "/api/prompt-guard/topic_guard"
65
+ : gatewayUrl + "/prompt-guard/topic_guard";
66
+
67
+ if (!gatewayUrl || !token) return null;
68
+ return { gatewayUrl, gatewayId, token, guardUuid, trajectoryEndpoint };
64
69
  } catch {
65
70
  return null;
66
71
  }
@@ -100,7 +105,7 @@ const plugin = {
100
105
 
101
106
  let gatewaySessionId = null;
102
107
  let endpointDisabled = false;
103
- const endpoint = config.apiUrl + "/api/prompt-guard/topic_guard";
108
+ const endpoint = config.trajectoryEndpoint;
104
109
  const localSessionId = "local_" + Date.now().toString(36);
105
110
 
106
111
  try { mkdirSync(TRAJECTORY_LOG_DIR, { recursive: true }); } catch {}
@@ -113,7 +118,7 @@ const plugin = {
113
118
  } catch {}
114
119
  }
115
120
 
116
- api.logger.info("[virtueai-trajectory] Plugin registered, sending to " + config.apiUrl);
121
+ api.logger.info("[virtueai-trajectory] Plugin registered, endpoint: " + endpoint);
117
122
 
118
123
  async function sendStep(role, content) {
119
124
  if (endpointDisabled) return;
@@ -138,9 +143,9 @@ const plugin = {
138
143
  body: JSON.stringify(body),
139
144
  });
140
145
 
141
- if (res.status === 404) {
146
+ if (res.status === 404 || res.status === 401 || res.status === 403) {
142
147
  endpointDisabled = true;
143
- api.logger.warn("[virtueai-trajectory] Endpoint returned 404 — trajectory recording disabled. Is the prompt-guard API deployed on the gateway?");
148
+ api.logger.warn("[virtueai-trajectory] HTTP " + res.status + " — trajectory recording disabled");
144
149
  return;
145
150
  }
146
151
  if (!res.ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@virtue-ai/gateway-connect",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "One-command setup to connect OpenClaw to VirtueAI MCP gateway",
5
5
  "type": "module",
6
6
  "files": [