ocuclaw 1.2.4 → 1.3.1

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.
Files changed (60) hide show
  1. package/README.md +21 -6
  2. package/dist/config/runtime-config.js +84 -3
  3. package/dist/domain/activity-status-adapter.js +138 -605
  4. package/dist/domain/activity-status-arbiter.js +109 -0
  5. package/dist/domain/activity-status-labels.js +906 -0
  6. package/dist/domain/code-span-regions.js +103 -0
  7. package/dist/domain/conversation-state.js +14 -1
  8. package/dist/domain/debug-store.js +56 -182
  9. package/dist/domain/glasses-ui-content-summary.js +62 -0
  10. package/dist/domain/glasses-ui-system-prompt.js +28 -0
  11. package/dist/domain/message-emoji-allowlist.js +16 -0
  12. package/dist/domain/message-emoji-filter.js +33 -55
  13. package/dist/domain/neural-emoji-reactor-system-prompt.js +43 -0
  14. package/dist/domain/neural-emoji-reactor-tag-config.js +56 -0
  15. package/dist/domain/neural-pace-modulator-system-prompt.js +32 -0
  16. package/dist/domain/neural-pace-modulator-tag-config.js +51 -0
  17. package/dist/domain/tagged-span-parser.js +121 -0
  18. package/dist/domain/tagged-span-strip.js +38 -0
  19. package/dist/even-ai/even-ai-endpoint.js +91 -0
  20. package/dist/even-ai/even-ai-run-waiter.js +14 -0
  21. package/dist/even-ai/even-ai-settings-store.js +14 -0
  22. package/dist/gateway/gateway-bridge.js +14 -2
  23. package/dist/gateway/gateway-timing-ledger.js +457 -0
  24. package/dist/gateway/openclaw-client.js +462 -38
  25. package/dist/index.js +28 -1
  26. package/dist/runtime/downstream-handler.js +754 -83
  27. package/dist/runtime/ocuclaw-settings-store.js +74 -31
  28. package/dist/runtime/plugin-version-service.js +23 -0
  29. package/dist/runtime/protocol-adapter.js +9 -0
  30. package/dist/runtime/provider-usage-select.js +168 -0
  31. package/dist/runtime/relay-client-nudge-controller.js +553 -0
  32. package/dist/runtime/relay-core.js +1293 -225
  33. package/dist/runtime/relay-health-monitor.js +172 -0
  34. package/dist/runtime/relay-operation-registry.js +263 -0
  35. package/dist/runtime/relay-service.js +201 -1
  36. package/dist/runtime/relay-worker-approval-replay-cache.js +68 -0
  37. package/dist/runtime/relay-worker-entry.js +32 -0
  38. package/dist/runtime/relay-worker-health.js +272 -0
  39. package/dist/runtime/relay-worker-protocol.js +281 -0
  40. package/dist/runtime/relay-worker-queue.js +202 -0
  41. package/dist/runtime/relay-worker-supervisor.js +1004 -0
  42. package/dist/runtime/relay-worker-transport.js +1051 -0
  43. package/dist/runtime/session-context-service.js +189 -0
  44. package/dist/runtime/session-service.js +638 -27
  45. package/dist/runtime/upstream-runtime.js +1167 -60
  46. package/dist/tools/device-info-tool.js +242 -0
  47. package/dist/tools/glasses-ui-cron.js +427 -0
  48. package/dist/tools/glasses-ui-descriptors.js +261 -0
  49. package/dist/tools/glasses-ui-limits.js +21 -0
  50. package/dist/tools/glasses-ui-paint-floor.js +99 -0
  51. package/dist/tools/glasses-ui-recipes.js +581 -0
  52. package/dist/tools/glasses-ui-surfaces.js +278 -0
  53. package/dist/tools/glasses-ui-template.js +182 -0
  54. package/dist/tools/glasses-ui-tool.js +1111 -0
  55. package/dist/tools/session-title-tool.js +209 -0
  56. package/dist/version.js +2 -0
  57. package/openclaw.plugin.json +163 -15
  58. package/package.json +14 -5
  59. package/skills/glasses-ui/SKILL.md +156 -0
  60. package/dist/runtime/downstream-server.js +0 -1891
package/README.md CHANGED
@@ -2,13 +2,16 @@
2
2
 
3
3
  OcuClaw is an OpenClaw plugin for Even G2 smart glasses. Use the OcuClaw application within Even Hub App Store to connect the client side.
4
4
 
5
+ ## Requirements
6
+
7
+ OpenClaw `>= 2026.5.20` (older versions have a known plugin-install bug). Upgrade with `npm install -g openclaw@latest`.
8
+
5
9
  ## Install
6
10
 
7
11
  Install the plugin from the OpenClaw CLI:
8
12
 
9
13
  ```bash
10
14
  openclaw plugins install ocuclaw
11
- openclaw plugins enable ocuclaw
12
15
  ```
13
16
 
14
17
  ## Configure
@@ -18,7 +21,7 @@ Required:
18
21
  Set the OcuClaw relay token. This is a user-created password that must match the relay server token field in the OcuClaw application within Even Hub App Store.
19
22
 
20
23
  ```bash
21
- openclaw config set plugins.entries.ocuclaw.config.relayToken "<relay-token>"
24
+ openclaw config set plugins.entries.ocuclaw.config.relayToken "your-relay-token"
22
25
  ```
23
26
 
24
27
  Recommended:
@@ -26,7 +29,7 @@ Recommended:
26
29
  - `sonioxApiKey`: Enables Soniox speech-to-text for voice input.
27
30
 
28
31
  ```bash
29
- openclaw config set plugins.entries.ocuclaw.config.sonioxApiKey "<soniox-api-key>"
32
+ openclaw config set plugins.entries.ocuclaw.config.sonioxApiKey "your-soniox-api-key"
30
33
  ```
31
34
 
32
35
  - `evenAiEnabled`: Enables Even AI integration for OcuClaw.
@@ -38,18 +41,30 @@ openclaw config set plugins.entries.ocuclaw.config.evenAiEnabled true --strict-j
38
41
  - `evenAiToken`: Sets the user-created password for Even AI requests. This must match the password set in the Even AI Agent Configure section within the Even Realities app.
39
42
 
40
43
  ```bash
41
- openclaw config set plugins.entries.ocuclaw.config.evenAiToken "<even-ai-token>"
44
+ openclaw config set plugins.entries.ocuclaw.config.evenAiToken "your-even-ai-token"
42
45
  ```
43
46
 
47
+ > **Note:** When `evenAiEnabled` is `true`, `evenAiToken` is required. Config validation will reject the change if you enable Even AI without setting the token.
48
+
44
49
  Advanced optional settings:
45
50
 
46
51
  ```bash
47
52
  openclaw config set plugins.entries.ocuclaw.config.wsBind "127.0.0.1"
48
- openclaw config set plugins.entries.ocuclaw.config.wsPort 9000 --strict-json
53
+ # wsPort default is 9000; on Windows that port is often reserved by WinNAT, so the
54
+ # setup assistant uses 47800. Pick any free port in 30000-49151 if you override it.
55
+ openclaw config set plugins.entries.ocuclaw.config.wsPort 47800 --strict-json
49
56
  openclaw config set plugins.entries.ocuclaw.config.sessionLimit 10 --strict-json
50
57
  openclaw config set plugins.entries.ocuclaw.config.externalDebugToolsEnabled true --strict-json
51
58
  ```
52
59
 
60
+ Run `openclaw plugins inspect ocuclaw` to see all settings with their descriptions and defaults.
61
+
62
+ ## Enable
63
+
64
+ ```bash
65
+ openclaw plugins enable ocuclaw
66
+ ```
67
+
53
68
  ## Restart
54
69
 
55
70
  Restart the gateway so the plugin and config changes take effect:
@@ -61,7 +76,7 @@ openclaw gateway restart
61
76
  ## Verify
62
77
 
63
78
  ```bash
64
- openclaw plugins inspect ocuclaw
79
+ openclaw plugins inspect ocuclaw --runtime
65
80
  openclaw plugins doctor
66
81
  openclaw gateway status
67
82
  ```
@@ -97,6 +97,59 @@ function resolveDebugNoisyPolicies(pluginValue, envValue) {
97
97
  return parseJsonOrUndefined(envValue, "debugNoisyPolicies");
98
98
  }
99
99
 
100
+ // Supported live-refresh LLM backends — both are HTTP API backends. The two
101
+ // CLI-spawn backends were removed: codex-cli because Codex's read-only sandbox
102
+ // still permits filesystem reads (an agent prompt could exfil ~/.aws/credentials,
103
+ // ~/.ssh/*, etc. via stdout into the glasses surface), and claude-cli to remove
104
+ // the plugin's last child_process spawn so the OpenClaw installer's static
105
+ // dangerous-code scanner passes without --dangerously-force-unsafe-install. (The
106
+ // scanner can't see that --tools "" made the CLI tool-less; it just sees a spawn.
107
+ // This is not an exploit claim about claude-cli — it removes spawn surface and
108
+ // clears the static block.) The proper agentic tier — delegating ticks to the
109
+ // native OpenClaw runtime instead of spawning a CLI — is tracked separately (the
110
+ // glasses-ui L1/L2 delegation redesign) and blocked on request-scoped
111
+ // api.runtime.subagent.run. Operators who want Claude/Codex point an *-api
112
+ // backend at the provider endpoint (key resolved via the host modelAuth).
113
+ const GLASSES_UI_LIVE_BACKENDS = new Set([
114
+ "anthropic-api",
115
+ "openai-compat",
116
+ ]);
117
+
118
+ const GLASSES_UI_LIVE_DEFAULT_MODEL = {
119
+ "anthropic-api": "anthropic/claude-haiku-4-5-20251001",
120
+ "openai-compat": "gpt-4o-mini",
121
+ };
122
+
123
+ function resolveGlassesUiLive(value) {
124
+ const raw = isObject(value) ? value : {};
125
+ // Unknown/removed backends (incl. a stale tickBackend: "claude-cli" or
126
+ // "codex-cli" from an operator's pre-removal config) coerce to this default.
127
+ const tickBackend = GLASSES_UI_LIVE_BACKENDS.has(raw.tickBackend)
128
+ ? raw.tickBackend
129
+ : "anthropic-api";
130
+ const tickModel = pickString(raw.tickModel) || GLASSES_UI_LIVE_DEFAULT_MODEL[tickBackend];
131
+ const tickApiBaseUrl = pickString(raw.tickApiBaseUrl) || "https://api.openai.com";
132
+ return {
133
+ enabled: parseBool(raw.enabled, true),
134
+ tickBackend,
135
+ tickModel,
136
+ tickApiBaseUrl,
137
+ allowAgentModelOverride: parseBool(raw.allowAgentModelOverride, false),
138
+ tickMaxOutputTokens: parseIntOrDefault(raw.tickMaxOutputTokens, 200),
139
+ // http recipes issue agent-influenced outbound network requests on a
140
+ // schedule. The recipe executor blocks loopback/RFC1918/link-local
141
+ // destinations and resolves hostnames through an SSRF-safe dispatcher,
142
+ // but the capability — "the plugin's gateway host can fetch arbitrary
143
+ // public URLs the agent chooses" — is itself worth an operator opt-in.
144
+ // Default to disabled; set
145
+ // plugins.entries.ocuclaw.config.glassesUiLive.httpEnabled = true to
146
+ // enable. The dispatcher protection still applies once enabled.
147
+ httpEnabled: parseBool(raw.httpEnabled, false),
148
+ llmEnabled: parseBool(raw.llmEnabled, true),
149
+ maxConcurrentSurfacesPerHost: parseIntOrDefault(raw.maxConcurrentSurfacesPerHost, 4),
150
+ };
151
+ }
152
+
100
153
  export function createRuntimeConfig(opts = {}) {
101
154
  const pluginConfig = isObject(opts.pluginConfig) ? opts.pluginConfig : {};
102
155
  const openclawConfig = isObject(opts.openclawConfig) ? opts.openclawConfig : {};
@@ -106,7 +159,13 @@ export function createRuntimeConfig(opts = {}) {
106
159
 
107
160
  if (!relayToken) {
108
161
  throw new Error(
109
- "OcuClaw relayToken is required. Set plugins.entries.ocuclaw.config.relayToken.",
162
+ [
163
+ "OcuClaw relayToken is required.",
164
+ "Set the plugin config with:",
165
+ ' openclaw config set plugins.entries.ocuclaw.config.relayToken "your-token"',
166
+ "The same token must be entered in the OcuClaw app's relay server token field within Even Hub.",
167
+ "Then restart the gateway: openclaw gateway restart",
168
+ ].join("\n"),
110
169
  );
111
170
  }
112
171
  if (!gatewayUrl) {
@@ -120,6 +179,22 @@ export function createRuntimeConfig(opts = {}) {
120
179
  );
121
180
  }
122
181
 
182
+ const evenAiEnabled = parseBool(pluginConfig.evenAiEnabled, false);
183
+ const evenAiToken = pickString(pluginConfig.evenAiToken);
184
+ if (evenAiEnabled && !evenAiToken) {
185
+ throw new Error(
186
+ [
187
+ "OcuClaw evenAiToken is required when evenAiEnabled is true.",
188
+ "Set the plugin config with:",
189
+ ' openclaw config set plugins.entries.ocuclaw.config.evenAiToken "your-token"',
190
+ "The same token must be entered as the password in the Even AI Agent Configure section of the Even Realities app.",
191
+ "To disable Even AI instead, run:",
192
+ " openclaw config set plugins.entries.ocuclaw.config.evenAiEnabled false --strict-json",
193
+ "Then restart the gateway: openclaw gateway restart",
194
+ ].join("\n"),
195
+ );
196
+ }
197
+
123
198
  return {
124
199
  gatewayUrl,
125
200
  gatewayToken,
@@ -140,8 +215,8 @@ export function createRuntimeConfig(opts = {}) {
140
215
  pluginConfig.externalDebugToolsEnabled,
141
216
  false,
142
217
  ),
143
- evenAiEnabled: parseBool(pluginConfig.evenAiEnabled, false),
144
- evenAiToken: pickString(pluginConfig.evenAiToken),
218
+ evenAiEnabled,
219
+ evenAiToken,
145
220
  evenAiSystemPrompt: pickString(pluginConfig.evenAiSystemPrompt),
146
221
  evenAiRequestTimeoutMs: parseIntOrDefault(
147
222
  pluginConfig.evenAiRequestTimeoutMs,
@@ -159,6 +234,12 @@ export function createRuntimeConfig(opts = {}) {
159
234
  evenAiDedicatedSessionKey: parseEvenAiDedicatedSessionKey(
160
235
  pluginConfig.evenAiDedicatedSessionKey,
161
236
  ),
237
+ renderGlassesUiTimeoutMs: parseIntOrDefault(
238
+ pluginConfig.renderGlassesUiTimeoutMs,
239
+ 30 * 60 * 1000,
240
+ ),
241
+ glassesUiLive: resolveGlassesUiLive(pluginConfig.glassesUiLive),
242
+ freshnessWindowMs: parseIntOrDefault(pluginConfig.freshnessWindowMs, 5000),
162
243
  };
163
244
  }
164
245