robot-resources 1.2.4 → 1.2.5
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/lib/tool-config.js +16 -138
- package/package.json +1 -1
package/lib/tool-config.js
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, copyFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
2
|
-
import { execSync } from 'node:child_process';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { homedir } from 'node:os';
|
|
5
1
|
import { isOpenClawInstalled } from './detect.js';
|
|
6
2
|
|
|
7
|
-
const ROUTER_URL = 'http://localhost:3838';
|
|
8
|
-
|
|
9
3
|
/**
|
|
10
4
|
* Strip JSON5 features (comments + trailing commas) to produce valid JSON.
|
|
11
5
|
* Handles single-line comments (//), multi-line comments, and trailing
|
|
@@ -24,135 +18,23 @@ function stripJson5(text) {
|
|
|
24
18
|
}
|
|
25
19
|
|
|
26
20
|
/**
|
|
27
|
-
*
|
|
28
|
-
* Strips comments and trailing commas before parsing.
|
|
29
|
-
*/
|
|
30
|
-
function readJsonSafe(filePath) {
|
|
31
|
-
try {
|
|
32
|
-
const raw = readFileSync(filePath, 'utf-8');
|
|
33
|
-
return JSON.parse(stripJson5(raw));
|
|
34
|
-
} catch {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Write JSON with backup.
|
|
41
|
-
*/
|
|
42
|
-
function writeJsonSafe(filePath, data) {
|
|
43
|
-
const dir = join(filePath, '..');
|
|
44
|
-
mkdirSync(dir, { recursive: true });
|
|
45
|
-
if (existsSync(filePath)) {
|
|
46
|
-
copyFileSync(filePath, `${filePath}.bak`);
|
|
47
|
-
}
|
|
48
|
-
writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Configure OpenClaw to route through the Router.
|
|
53
|
-
*
|
|
54
|
-
* Writes to TWO files (both required for OpenClaw to honor the override):
|
|
55
|
-
*
|
|
56
|
-
* 1. openclaw.json — config-level override. Needs baseUrl + models[] array
|
|
57
|
-
* or OpenClaw rejects the config as invalid.
|
|
58
|
-
*
|
|
59
|
-
* 2. models.json (~/.openclaw/agents/main/agent/models.json) — runtime file
|
|
60
|
-
* that OpenClaw actually reads. The baseUrl here is what gets used for
|
|
61
|
-
* API calls. openclaw.json alone is not enough.
|
|
21
|
+
* Detect OpenClaw and report status.
|
|
62
22
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
23
|
+
* OpenClaw integration is pending — requires a plugin hook
|
|
24
|
+
* (openclaw/openclaw#9402) that hasn't shipped yet. Until then,
|
|
25
|
+
* we detect OpenClaw and return instructions instead of writing
|
|
26
|
+
* config that gets clobbered on gateway restart.
|
|
66
27
|
*/
|
|
67
28
|
function configureOpenClaw() {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
// Ensure models.providers.anthropic path
|
|
79
|
-
config.models = config.models || {};
|
|
80
|
-
config.models.providers = config.models.providers || {};
|
|
81
|
-
config.models.providers.anthropic = config.models.providers.anthropic || {};
|
|
82
|
-
|
|
83
|
-
const anthropic = config.models.providers.anthropic;
|
|
84
|
-
|
|
85
|
-
// Check if already proxied through Router
|
|
86
|
-
if (anthropic.baseUrl === `${ROUTER_URL}/v1`) {
|
|
87
|
-
// Also verify models.json is in sync
|
|
88
|
-
const modelsJsonPath = join(home, '.openclaw', 'agents', 'main', 'agent', 'models.json');
|
|
89
|
-
const modelsJson = readJsonSafe(modelsJsonPath);
|
|
90
|
-
const runtimeUrl = modelsJson?.providers?.anthropic?.baseUrl;
|
|
91
|
-
if (runtimeUrl === `${ROUTER_URL}/v1`) {
|
|
92
|
-
return { name: 'OpenClaw', action: 'already_configured' };
|
|
93
|
-
}
|
|
94
|
-
// openclaw.json is set but models.json is not — fall through to fix it
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Save original baseUrl for rollback
|
|
98
|
-
if (anthropic.baseUrl && anthropic.baseUrl !== `${ROUTER_URL}/v1`) {
|
|
99
|
-
anthropic._originalBaseUrl = anthropic.baseUrl;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Point Anthropic provider at Router
|
|
103
|
-
anthropic.baseUrl = `${ROUTER_URL}/v1`;
|
|
104
|
-
|
|
105
|
-
// OpenClaw requires models array on provider entries
|
|
106
|
-
if (!Array.isArray(anthropic.models)) {
|
|
107
|
-
anthropic.models = [];
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Clean up stale "robot-resources" provider from previous wizard versions
|
|
111
|
-
delete config.models.providers['robot-resources'];
|
|
112
|
-
|
|
113
|
-
writeJsonSafe(configPath, config);
|
|
114
|
-
|
|
115
|
-
// ── 2. Update models.json (runtime file) ────────────────────
|
|
116
|
-
const modelsJsonPath = join(home, '.openclaw', 'agents', 'main', 'agent', 'models.json');
|
|
117
|
-
let modelsJson = readJsonSafe(modelsJsonPath) || {};
|
|
118
|
-
|
|
119
|
-
modelsJson.providers = modelsJson.providers || {};
|
|
120
|
-
modelsJson.providers.anthropic = modelsJson.providers.anthropic || {};
|
|
121
|
-
|
|
122
|
-
// Save original for rollback
|
|
123
|
-
const runtimeUrl = modelsJson.providers.anthropic.baseUrl;
|
|
124
|
-
if (runtimeUrl && runtimeUrl !== `${ROUTER_URL}/v1`) {
|
|
125
|
-
modelsJson.providers.anthropic._originalBaseUrl = runtimeUrl;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
modelsJson.providers.anthropic.baseUrl = `${ROUTER_URL}/v1`;
|
|
129
|
-
|
|
130
|
-
// Clean up stale robot-resources provider
|
|
131
|
-
delete modelsJson.providers['robot-resources'];
|
|
132
|
-
|
|
133
|
-
writeJsonSafe(modelsJsonPath, modelsJson);
|
|
134
|
-
|
|
135
|
-
// ── 3. Restart gateway ──────────────────────────────────────
|
|
136
|
-
// SIGUSR1 doesn't reload config on OpenClaw. Full restart needed.
|
|
137
|
-
// systemctl --user restart is preferred (auto-reconnects).
|
|
138
|
-
// Falls back to openclaw gateway restart, then kill+start.
|
|
139
|
-
try {
|
|
140
|
-
execSync('systemctl --user restart openclaw-gateway', {
|
|
141
|
-
stdio: 'ignore',
|
|
142
|
-
timeout: 10_000,
|
|
143
|
-
});
|
|
144
|
-
} catch {
|
|
145
|
-
try {
|
|
146
|
-
execSync('openclaw gateway restart', {
|
|
147
|
-
stdio: 'ignore',
|
|
148
|
-
timeout: 10_000,
|
|
149
|
-
});
|
|
150
|
-
} catch {
|
|
151
|
-
// Gateway not running or not installed as service — not fatal
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return { name: 'OpenClaw', action: 'configured' };
|
|
29
|
+
return {
|
|
30
|
+
name: 'OpenClaw',
|
|
31
|
+
action: 'instructions',
|
|
32
|
+
instructions: [
|
|
33
|
+
'OpenClaw detected — Router integration coming soon.',
|
|
34
|
+
'Track progress: https://github.com/openclaw/openclaw/issues/9402',
|
|
35
|
+
'Router works now with Claude Desktop, Cursor, and any OpenAI SDK app.',
|
|
36
|
+
],
|
|
37
|
+
};
|
|
156
38
|
}
|
|
157
39
|
|
|
158
40
|
/**
|
|
@@ -165,15 +47,11 @@ export function configureToolRouting() {
|
|
|
165
47
|
|
|
166
48
|
// OpenClaw
|
|
167
49
|
if (isOpenClawInstalled()) {
|
|
168
|
-
|
|
169
|
-
results.push(configureOpenClaw());
|
|
170
|
-
} catch (err) {
|
|
171
|
-
results.push({ name: 'OpenClaw', action: 'error', reason: err.message });
|
|
172
|
-
}
|
|
50
|
+
results.push(configureOpenClaw());
|
|
173
51
|
}
|
|
174
52
|
|
|
175
53
|
return results;
|
|
176
54
|
}
|
|
177
55
|
|
|
178
56
|
// Exported for testing
|
|
179
|
-
export { stripJson5,
|
|
57
|
+
export { stripJson5, configureOpenClaw };
|