@virtue-ai/gateway-connect 0.3.0 → 0.3.2

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
@@ -26,12 +26,6 @@ openclaw models auth paste-token --provider openai
26
26
  npx @virtue-ai/gateway-connect --gateway-url https://virtueai-agent-gtw-xxxx.ngrok.io
27
27
  ```
28
28
 
29
- To use a specific model:
30
-
31
- ```bash
32
- npx @virtue-ai/gateway-connect --gateway-url https://virtueai-agent-gtw-xxxx.ngrok.io --model openai/gpt-4o
33
- ```
34
-
35
29
  This will:
36
30
 
37
31
  1. Open your browser for OAuth login
@@ -52,7 +46,7 @@ Interactive TUI mode:
52
46
 
53
47
  ```bash
54
48
  # Terminal 1: start the OpenClaw gateway
55
- openclaw gateway
49
+ openclaw gateway --allow-unconfigured
56
50
 
57
51
  # Terminal 2: open the TUI
58
52
  openclaw tui
@@ -69,7 +63,7 @@ openclaw gateway stop
69
63
  In TUI mode, use slash commands to switch models on the fly:
70
64
 
71
65
  ```
72
- /model openai/gpt-4o
66
+ /model openai/gpt-5.2
73
67
  /model anthropic/claude-opus-4-6
74
68
  /models # opens model picker
75
69
  ```
package/dist/index.js CHANGED
@@ -34,6 +34,8 @@ const OPENCLAW_CONFIG_PATH = path.join(OPENCLAW_DIR, 'openclaw.json');
34
34
  const TOOLS_PLUGIN_ID = 'virtueai-mcp-tools';
35
35
  const TOOLS_PLUGIN_DIR = path.join(OPENCLAW_DIR, 'extensions', TOOLS_PLUGIN_ID);
36
36
  const DEFAULT_GATEWAY_URL = 'https://virtueai-agent-gtw-l3phon63.ngrok.io';
37
+ const DEFAULT_API_URL = 'https://agentgateway1.virtueai.io';
38
+ const DEFAULT_GATEWAY_ID = 'gtw_L3pHOn63';
37
39
  // ---------------------------------------------------------------------------
38
40
  // Helpers
39
41
  // ---------------------------------------------------------------------------
@@ -340,11 +342,13 @@ ${toolRegistrations.join('\n')}
340
342
  // ---------------------------------------------------------------------------
341
343
  // Step 3: Write config & patch openclaw.json
342
344
  // ---------------------------------------------------------------------------
343
- function writeGatewayConfig(gatewayUrl, accessToken, guardUuid) {
345
+ function writeGatewayConfig(gatewayUrl, accessToken, guardUuid, apiUrl, gatewayId) {
344
346
  fs.mkdirSync(OPENCLAW_DIR, { recursive: true });
345
347
  const config = {
346
348
  trajectory: {
347
349
  gatewayUrl,
350
+ apiUrl: apiUrl || DEFAULT_API_URL,
351
+ gatewayId: gatewayId || DEFAULT_GATEWAY_ID,
348
352
  guardUuid: guardUuid || process.env.VIRTUEAI_GUARD_UUID || '',
349
353
  },
350
354
  _auth: {
@@ -435,7 +439,9 @@ Usage:
435
439
  npx @virtue-ai/gateway-connect [options]
436
440
 
437
441
  Options:
438
- --gateway-url <url> Gateway URL (default: ${DEFAULT_GATEWAY_URL})
442
+ --gateway-url <url> MCP gateway URL (default: ${DEFAULT_GATEWAY_URL})
443
+ --api-url <url> Prompt-guard API URL (default: ${DEFAULT_API_URL})
444
+ --gateway-id <id> Gateway ID for trajectory (default: ${DEFAULT_GATEWAY_ID})
439
445
  --model <model> Model to use (e.g. openai/gpt-4o, anthropic/claude-sonnet-4-5)
440
446
  --guard-uuid <uuid> Guard UUID for trajectory recording (or set VIRTUEAI_GUARD_UUID)
441
447
  --help Show this help message
@@ -456,6 +462,8 @@ Supported models:
456
462
  let gatewayUrl = getArg('gateway-url') || DEFAULT_GATEWAY_URL;
457
463
  const model = getArg('model');
458
464
  const guardUuid = getArg('guard-uuid') || process.env.VIRTUEAI_GUARD_UUID;
465
+ const apiUrl = getArg('api-url') || DEFAULT_API_URL;
466
+ const gatewayId = getArg('gateway-id') || DEFAULT_GATEWAY_ID;
459
467
  gatewayUrl = gatewayUrl.replace(/\/mcp\/?$/, '').toLowerCase();
460
468
  console.log('\n VirtueAI Gateway Connect\n');
461
469
  console.log(` Gateway: ${gatewayUrl}`);
@@ -472,7 +480,7 @@ Supported models:
472
480
  }
473
481
  generateMcpToolsPlugin(gatewayUrl, accessToken, tools);
474
482
  // Step 3: Write gateway config (for trajectory plugin)
475
- writeGatewayConfig(gatewayUrl, accessToken, guardUuid);
483
+ writeGatewayConfig(gatewayUrl, accessToken, guardUuid, apiUrl, gatewayId);
476
484
  // Step 4: Patch openclaw.json (enable tools plugin + set model)
477
485
  patchOpenClawConfig(model);
478
486
  // Step 5: Install trajectory plugin
@@ -49,6 +49,8 @@ function loadConfig() {
49
49
  const cfg = JSON.parse(raw);
50
50
 
51
51
  const gatewayUrl = cfg._auth?.gatewayUrl ?? cfg.trajectory?.gatewayUrl ?? "";
52
+ const apiUrl = cfg.trajectory?.apiUrl ?? gatewayUrl;
53
+ const gatewayId = cfg.trajectory?.gatewayId ?? "";
52
54
  const token = cfg._auth?.accessToken ?? "";
53
55
 
54
56
  const guardUuid =
@@ -56,8 +58,8 @@ function loadConfig() {
56
58
  process.env.VIRTUEAI_GUARD_UUID ||
57
59
  DEFAULT_GUARD_UUID;
58
60
 
59
- if (!gatewayUrl || !token) return null;
60
- return { gatewayUrl, token, guardUuid };
61
+ if (!apiUrl || !token) return null;
62
+ return { gatewayUrl, apiUrl, gatewayId, token, guardUuid };
61
63
  } catch {
62
64
  return null;
63
65
  }
@@ -70,6 +72,19 @@ function truncate(s, max = 2000) {
70
72
  return s.length > max ? s.slice(0, max) + "..." : s;
71
73
  }
72
74
 
75
+ /**
76
+ * Strip OpenClaw's sender metadata prefix from the raw prompt.
77
+ * The prompt arrives as:
78
+ * Sender (untrusted metadata):\\n{json}\\n\\n[timestamp] actual message
79
+ * We want just "actual message".
80
+ */
81
+ function stripSenderMetadata(prompt) {
82
+ if (!prompt || typeof prompt !== "string") return prompt;
83
+ // Match the "Sender (untrusted metadata):" block + JSON + timestamp prefix
84
+ const match = prompt.match(/^Sender \\(untrusted metadata\\):[\\s\\S]*?\\n\\n(?:\\[.*?\\]\\s*)?(.*)$/s);
85
+ return match ? match[1].trim() : prompt.trim();
86
+ }
87
+
73
88
  const plugin = {
74
89
  id: "${PLUGIN_ID}",
75
90
  name: "VirtueAI Trajectory",
@@ -84,7 +99,7 @@ const plugin = {
84
99
 
85
100
  let gatewaySessionId = null;
86
101
  let endpointDisabled = false;
87
- const endpoint = config.gatewayUrl + "/api/prompt-guard/topic_guard";
102
+ const endpoint = config.apiUrl + "/api/prompt-guard/topic_guard";
88
103
 
89
104
  api.logger.info("[virtueai-trajectory] Plugin registered, sending to " + config.gatewayUrl);
90
105
 
@@ -94,6 +109,7 @@ const plugin = {
94
109
  const body = {
95
110
  user_prompt: truncate(content),
96
111
  guard_uuid: config.guardUuid,
112
+ gateway_id: config.gatewayId,
97
113
  role,
98
114
  };
99
115
  if (gatewaySessionId) {
@@ -130,34 +146,40 @@ const plugin = {
130
146
  }
131
147
  }
132
148
 
133
- // Hook: user prompt sent to LLM
134
149
  api.on("llm_input", (event) => {
135
- if (event.prompt) {
136
- sendStep("user", event.prompt);
150
+ const cleaned = stripSenderMetadata(event.prompt);
151
+ api.logger.info("[virtueai-trajectory] llm_input fired, prompt=" + (cleaned ?? "").slice(0, 80));
152
+ if (cleaned) {
153
+ sendStep("user", cleaned);
137
154
  }
138
155
  });
139
156
 
140
- // Hook: LLM response received
141
157
  api.on("llm_output", (event) => {
158
+ api.logger.info("[virtueai-trajectory] llm_output fired, assistantTexts.length=" + (event.assistantTexts?.length ?? "undefined") + ", keys=" + Object.keys(event).join(","));
142
159
  const text = (event.assistantTexts ?? []).join("\\n").trim();
143
160
  if (text) {
161
+ api.logger.info("[virtueai-trajectory] llm_output sending agent text, len=" + text.length);
144
162
  sendStep("agent", text);
163
+ } else {
164
+ api.logger.warn("[virtueai-trajectory] llm_output fired but assistantTexts empty");
145
165
  }
146
166
  });
147
167
 
148
- // Hook: tool call completed
149
168
  api.on("after_tool_call", (event) => {
150
- const params = event.params
169
+ api.logger.info("[virtueai-trajectory] after_tool_call fired, tool=" + event.toolName);
170
+ const toolParams = event.params
151
171
  ? Object.entries(event.params)
152
172
  .map(([k, v]) => k + "=" + JSON.stringify(v))
153
173
  .join(", ")
154
174
  : "";
155
- const callStr = event.toolName + "(" + params + ")";
175
+ const callStr = event.toolName + "(" + toolParams + ")";
156
176
  const resultStr = event.result != null ? truncate(event.result, 500) : (event.error ?? "no result");
157
177
  sendStep("agent", callStr + " → " + resultStr);
158
178
  });
159
179
 
160
- api.logger.info("[virtueai-trajectory] Plugin registered, sending to " + config.gatewayUrl);
180
+ api.on("agent_end", (event) => {
181
+ api.logger.info("[virtueai-trajectory] agent_end fired, success=" + event.success + ", durationMs=" + event.durationMs);
182
+ });
161
183
  },
162
184
  };
163
185
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@virtue-ai/gateway-connect",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "One-command setup to connect OpenClaw to VirtueAI MCP gateway",
5
5
  "type": "module",
6
6
  "files": [