@moltenbot/openclaw-plugin-statocyst 0.1.0 → 0.1.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 +38 -6
- package/dist/plugin.js +2 -2
- package/dist/statocyst-client.js +37 -8
- package/openclaw.plugin.json +6 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,13 +26,13 @@ openclaw gateway restart
|
|
|
26
26
|
|
|
27
27
|
## Configure
|
|
28
28
|
|
|
29
|
-
Set plugin config under `plugins.entries.statocyst
|
|
29
|
+
Set plugin config under `plugins.entries.openclaw-plugin-statocyst.config`:
|
|
30
30
|
|
|
31
31
|
```json
|
|
32
32
|
{
|
|
33
33
|
"plugins": {
|
|
34
34
|
"entries": {
|
|
35
|
-
"statocyst
|
|
35
|
+
"openclaw-plugin-statocyst": {
|
|
36
36
|
"enabled": true,
|
|
37
37
|
"config": {
|
|
38
38
|
"baseUrl": "https://hub.example.com/v1",
|
|
@@ -48,17 +48,49 @@ Set plugin config under `plugins.entries.statocyst-openclaw.config`:
|
|
|
48
48
|
|
|
49
49
|
Config fields:
|
|
50
50
|
|
|
51
|
-
- `
|
|
52
|
-
- `
|
|
51
|
+
- `configFile` (optional): path to a JSON file with plugin config values
|
|
52
|
+
- `baseUrl` (required unless `configFile` is provided): Statocyst API base, including `/v1`
|
|
53
|
+
- `token` (required unless `configFile` is provided): Statocyst bearer token for the current OpenClaw agent
|
|
53
54
|
- `sessionKey` (optional, default `main`): dedicated realtime session key
|
|
54
55
|
- `timeoutMs` (optional, default `20000`, max `60000`): tool request timeout
|
|
55
56
|
|
|
57
|
+
File-based config example:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"plugins": {
|
|
62
|
+
"entries": {
|
|
63
|
+
"openclaw-plugin-statocyst": {
|
|
64
|
+
"enabled": true,
|
|
65
|
+
"config": {
|
|
66
|
+
"configFile": "/etc/molten/openclaw-plugin-statocyst.json"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`/etc/molten/openclaw-plugin-statocyst.json`:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"baseUrl": "https://hub.example.com/v1",
|
|
79
|
+
"token": "statocyst-agent-bearer-token",
|
|
80
|
+
"sessionKey": "main",
|
|
81
|
+
"timeoutMs": 20000
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
You can also set `STATOCYST_CONFIG_FILE=/path/to/openclaw-plugin-statocyst.json` in the OpenClaw runtime environment.
|
|
86
|
+
When both inline config and `configFile` are present, inline values take precedence.
|
|
87
|
+
|
|
56
88
|
## Statocyst usage registration
|
|
57
89
|
|
|
58
90
|
This plugin actively records usage in Statocyst:
|
|
59
91
|
|
|
60
92
|
- `POST /v1/openclaw/messages/register-plugin` is called before session checks and skill requests.
|
|
61
|
-
- Statocyst stores plugin metadata on the agent profile under `metadata.plugins.statocyst
|
|
93
|
+
- Statocyst stores plugin metadata on the agent profile under `metadata.plugins.openclaw-plugin-statocyst`.
|
|
62
94
|
- Statocyst appends agent activity entries for:
|
|
63
95
|
- plugin registration (`openclaw_plugin`)
|
|
64
96
|
- OpenClaw adapter usage (`openclaw_adapter` events across publish/pull/ack/nack/status/ws)
|
|
@@ -68,7 +100,7 @@ You can inspect this data via `GET /v1/agents/me`.
|
|
|
68
100
|
## OpenClaw onboarding flow
|
|
69
101
|
|
|
70
102
|
1. Create/bind the Statocyst agent token (`POST /v1/agents/bind-tokens`, then `POST /v1/agents/bind`).
|
|
71
|
-
2. Configure plugin entry in OpenClaw (`plugins.entries.statocyst
|
|
103
|
+
2. Configure plugin entry in OpenClaw (`plugins.entries.openclaw-plugin-statocyst.config`).
|
|
72
104
|
3. Ensure your tool policy allows plugin tools:
|
|
73
105
|
- allow `statocyst_skill_request` and `statocyst_session_status` (or allow the plugin id).
|
|
74
106
|
4. Restart OpenClaw gateway.
|
package/dist/plugin.js
CHANGED
|
@@ -130,10 +130,10 @@ function buildClient(api, factory) {
|
|
|
130
130
|
export function createStatocystOpenClawPlugin(deps) {
|
|
131
131
|
const factory = deps?.createClient ?? ((config) => new StatocystClient(config));
|
|
132
132
|
return {
|
|
133
|
-
id: "statocyst
|
|
133
|
+
id: "openclaw-plugin-statocyst",
|
|
134
134
|
name: "Statocyst Realtime",
|
|
135
135
|
description: "Molten AI maintained plugin for realtime skill request/result exchange via Statocyst.",
|
|
136
|
-
version: "0.1.
|
|
136
|
+
version: "0.1.2",
|
|
137
137
|
register: (api) => {
|
|
138
138
|
const client = buildClient(api, factory);
|
|
139
139
|
api.registerTool(skillRequestTool(() => client));
|
package/dist/statocyst-client.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { resolve as resolvePath } from "node:path";
|
|
2
4
|
import WebSocket from "ws";
|
|
3
5
|
const defaultTimeoutMs = 20_000;
|
|
4
|
-
const defaultPluginID = "statocyst
|
|
6
|
+
const defaultPluginID = "openclaw-plugin-statocyst";
|
|
5
7
|
const defaultPluginPackage = "@moltenbot/openclaw-plugin-statocyst";
|
|
6
|
-
const defaultPluginVersion = "0.1.
|
|
8
|
+
const defaultPluginVersion = "0.1.2";
|
|
7
9
|
const defaultDeps = {
|
|
8
10
|
fetchImpl: fetch,
|
|
9
11
|
wsFactory: (url, headers) => new WebSocket(url, { headers }),
|
|
@@ -290,17 +292,21 @@ export class StatocystClient {
|
|
|
290
292
|
export function resolveConfig(context) {
|
|
291
293
|
const config = context.config ?? {};
|
|
292
294
|
const env = context.env ?? {};
|
|
295
|
+
const configFilePath = trimOrEmpty(asString(config.configFile) || env.STATOCYST_CONFIG_FILE || "");
|
|
296
|
+
const fileConfig = readConfigFile(configFilePath);
|
|
293
297
|
const baseUrl = normalizeBaseURL(asString(config.baseUrl) ||
|
|
294
298
|
asString(config.baseURL) ||
|
|
299
|
+
asString(fileConfig.baseUrl) ||
|
|
300
|
+
asString(fileConfig.baseURL) ||
|
|
295
301
|
env.STATOCYST_BASE_URL ||
|
|
296
302
|
env.STATOCYST_API_BASE ||
|
|
297
303
|
"");
|
|
298
|
-
const token = trimOrEmpty(asString(config.token) || env.STATOCYST_AGENT_TOKEN || "");
|
|
299
|
-
const sessionKey = trimOrEmpty(asString(config.sessionKey) || env.STATOCYST_SESSION_KEY || "main");
|
|
300
|
-
const timeoutMs = normalizeTimeout(asNumber(config.timeoutMs) ?? asNumber(env.STATOCYST_TIMEOUT_MS) ?? defaultTimeoutMs);
|
|
301
|
-
const pluginId = trimOrEmpty(asString(config.pluginId) || defaultPluginID);
|
|
302
|
-
const pluginPackage = trimOrEmpty(asString(config.pluginPackage) || defaultPluginPackage);
|
|
303
|
-
const pluginVersion = trimOrEmpty(asString(config.pluginVersion) || defaultPluginVersion);
|
|
304
|
+
const token = trimOrEmpty(asString(config.token) || asString(fileConfig.token) || env.STATOCYST_AGENT_TOKEN || "");
|
|
305
|
+
const sessionKey = trimOrEmpty(asString(config.sessionKey) || asString(fileConfig.sessionKey) || env.STATOCYST_SESSION_KEY || "main");
|
|
306
|
+
const timeoutMs = normalizeTimeout(asNumber(config.timeoutMs) ?? asNumber(fileConfig.timeoutMs) ?? asNumber(env.STATOCYST_TIMEOUT_MS) ?? defaultTimeoutMs);
|
|
307
|
+
const pluginId = trimOrEmpty(asString(config.pluginId) || asString(fileConfig.pluginId) || defaultPluginID);
|
|
308
|
+
const pluginPackage = trimOrEmpty(asString(config.pluginPackage) || asString(fileConfig.pluginPackage) || defaultPluginPackage);
|
|
309
|
+
const pluginVersion = trimOrEmpty(asString(config.pluginVersion) || asString(fileConfig.pluginVersion) || defaultPluginVersion);
|
|
304
310
|
if (!baseUrl) {
|
|
305
311
|
throw new Error("Statocyst plugin configuration requires baseUrl");
|
|
306
312
|
}
|
|
@@ -371,6 +377,29 @@ function normalizeBaseURL(raw) {
|
|
|
371
377
|
}
|
|
372
378
|
return trimmed.replace(/\/+$/, "");
|
|
373
379
|
}
|
|
380
|
+
function readConfigFile(configPath) {
|
|
381
|
+
if (!configPath) {
|
|
382
|
+
return {};
|
|
383
|
+
}
|
|
384
|
+
const absolutePath = resolvePath(configPath);
|
|
385
|
+
let rawContent = "";
|
|
386
|
+
try {
|
|
387
|
+
rawContent = readFileSync(absolutePath, "utf8");
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
throw new Error(`failed reading Statocyst plugin config file (${absolutePath}): ${String(error)}`);
|
|
391
|
+
}
|
|
392
|
+
try {
|
|
393
|
+
const parsed = JSON.parse(rawContent.replace(/^\uFEFF/, ""));
|
|
394
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
395
|
+
throw new Error("config file must contain a JSON object");
|
|
396
|
+
}
|
|
397
|
+
return parsed;
|
|
398
|
+
}
|
|
399
|
+
catch (error) {
|
|
400
|
+
throw new Error(`invalid Statocyst plugin config file (${absolutePath}): ${String(error)}`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
374
403
|
function normalizeTimeout(raw) {
|
|
375
404
|
if (!Number.isFinite(raw) || raw <= 0) {
|
|
376
405
|
return defaultTimeoutMs;
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
|
-
"id": "statocyst
|
|
2
|
+
"id": "openclaw-plugin-statocyst",
|
|
3
3
|
"name": "Statocyst Realtime",
|
|
4
4
|
"description": "Realtime Statocyst messaging and skill request/result tools for OpenClaw.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.2",
|
|
6
6
|
"contracts": {
|
|
7
7
|
"tools": ["statocyst_skill_request", "statocyst_session_status"]
|
|
8
8
|
},
|
|
9
9
|
"configSchema": {
|
|
10
10
|
"type": "object",
|
|
11
11
|
"additionalProperties": false,
|
|
12
|
-
"required": ["baseUrl", "token"],
|
|
13
12
|
"properties": {
|
|
13
|
+
"configFile": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "Optional path to a JSON file containing plugin configuration"
|
|
16
|
+
},
|
|
14
17
|
"baseUrl": {
|
|
15
18
|
"type": "string",
|
|
16
19
|
"description": "Statocyst API base URL, for example https://hub.example.com/v1"
|
package/package.json
CHANGED