@virtue-ai/gateway-connect 0.3.1 → 0.3.3

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
  ```
@@ -26,7 +26,7 @@ const DEFAULT_GUARD_UUID = '3a2389709528a539a12ba6239e402ef159ecffa88f99af6e1323
26
26
  // ---------------------------------------------------------------------------
27
27
  function buildPluginSource() {
28
28
  return `\
29
- import { readFileSync } from "fs";
29
+ import { readFileSync, appendFileSync, mkdirSync } from "fs";
30
30
  import { join } from "path";
31
31
  import { homedir } from "os";
32
32
 
@@ -40,6 +40,7 @@ import { homedir } from "os";
40
40
  */
41
41
 
42
42
  const MCP_CONFIG_PATH = join(homedir(), ".openclaw", "mcp-gateway.json");
43
+ const TRAJECTORY_LOG_DIR = join(homedir(), ".openclaw", "logs", "trajectory");
43
44
  const DEFAULT_GUARD_UUID =
44
45
  "${DEFAULT_GUARD_UUID}";
45
46
 
@@ -72,6 +73,19 @@ function truncate(s, max = 2000) {
72
73
  return s.length > max ? s.slice(0, max) + "..." : s;
73
74
  }
74
75
 
76
+ /**
77
+ * Strip OpenClaw's sender metadata prefix from the raw prompt.
78
+ * The prompt arrives as:
79
+ * Sender (untrusted metadata):\\n{json}\\n\\n[timestamp] actual message
80
+ * We want just "actual message".
81
+ */
82
+ function stripSenderMetadata(prompt) {
83
+ if (!prompt || typeof prompt !== "string") return prompt;
84
+ // Match the "Sender (untrusted metadata):" block + JSON + timestamp prefix
85
+ const match = prompt.match(/^Sender \\(untrusted metadata\\):[\\s\\S]*?\\n\\n(?:\\[.*?\\]\\s*)?(.*)$/s);
86
+ return match ? match[1].trim() : prompt.trim();
87
+ }
88
+
75
89
  const plugin = {
76
90
  id: "${PLUGIN_ID}",
77
91
  name: "VirtueAI Trajectory",
@@ -87,8 +101,19 @@ const plugin = {
87
101
  let gatewaySessionId = null;
88
102
  let endpointDisabled = false;
89
103
  const endpoint = config.apiUrl + "/api/prompt-guard/topic_guard";
104
+ const localSessionId = "local_" + Date.now().toString(36);
105
+
106
+ try { mkdirSync(TRAJECTORY_LOG_DIR, { recursive: true }); } catch {}
90
107
 
91
- api.logger.info("[virtueai-trajectory] Plugin registered, sending to " + config.gatewayUrl);
108
+ function writeLocal(role, content) {
109
+ try {
110
+ const entry = { timestamp: new Date().toISOString(), session_id: gatewaySessionId || localSessionId, role, content };
111
+ const logFile = join(TRAJECTORY_LOG_DIR, (gatewaySessionId || localSessionId) + ".jsonl");
112
+ appendFileSync(logFile, JSON.stringify(entry) + "\\n");
113
+ } catch {}
114
+ }
115
+
116
+ api.logger.info("[virtueai-trajectory] Plugin registered, sending to " + config.apiUrl);
92
117
 
93
118
  async function sendStep(role, content) {
94
119
  if (endpointDisabled) return;
@@ -133,34 +158,46 @@ const plugin = {
133
158
  }
134
159
  }
135
160
 
136
- // Hook: user prompt sent to LLM
137
161
  api.on("llm_input", (event) => {
138
- if (event.prompt) {
139
- sendStep("user", event.prompt);
162
+ if (event.systemPrompt) {
163
+ writeLocal("system", event.systemPrompt);
164
+ }
165
+ const cleaned = stripSenderMetadata(event.prompt);
166
+ api.logger.info("[virtueai-trajectory] llm_input fired, prompt=" + (cleaned ?? "").slice(0, 80));
167
+ if (cleaned) {
168
+ writeLocal("user", cleaned);
169
+ sendStep("user", cleaned);
140
170
  }
141
171
  });
142
172
 
143
- // Hook: LLM response received
144
173
  api.on("llm_output", (event) => {
174
+ api.logger.info("[virtueai-trajectory] llm_output fired, assistantTexts.length=" + (event.assistantTexts?.length ?? "undefined") + ", keys=" + Object.keys(event).join(","));
145
175
  const text = (event.assistantTexts ?? []).join("\\n").trim();
146
176
  if (text) {
177
+ api.logger.info("[virtueai-trajectory] llm_output sending agent text, len=" + text.length);
178
+ writeLocal("agent", text);
147
179
  sendStep("agent", text);
180
+ } else {
181
+ api.logger.warn("[virtueai-trajectory] llm_output fired but assistantTexts empty");
148
182
  }
149
183
  });
150
184
 
151
- // Hook: tool call completed
152
185
  api.on("after_tool_call", (event) => {
153
- const params = event.params
186
+ api.logger.info("[virtueai-trajectory] after_tool_call fired, tool=" + event.toolName);
187
+ const toolParams = event.params
154
188
  ? Object.entries(event.params)
155
189
  .map(([k, v]) => k + "=" + JSON.stringify(v))
156
190
  .join(", ")
157
191
  : "";
158
- const callStr = event.toolName + "(" + params + ")";
192
+ const callStr = event.toolName + "(" + toolParams + ")";
159
193
  const resultStr = event.result != null ? truncate(event.result, 500) : (event.error ?? "no result");
194
+ writeLocal("tool", callStr + " → " + resultStr);
160
195
  sendStep("agent", callStr + " → " + resultStr);
161
196
  });
162
197
 
163
- api.logger.info("[virtueai-trajectory] Plugin registered, sending to " + config.gatewayUrl);
198
+ api.on("agent_end", (event) => {
199
+ api.logger.info("[virtueai-trajectory] agent_end fired, success=" + event.success + ", durationMs=" + event.durationMs);
200
+ });
164
201
  },
165
202
  };
166
203
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@virtue-ai/gateway-connect",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "One-command setup to connect OpenClaw to VirtueAI MCP gateway",
5
5
  "type": "module",
6
6
  "files": [