Skip to content

feat(openclaw-plugin): bridge W2A sensors to OpenClaw via runEmbedded…#6

Merged
Nova-machinepulse merged 9 commits intomainfrom
feat/openclaw-plugin
Apr 29, 2026
Merged

feat(openclaw-plugin): bridge W2A sensors to OpenClaw via runEmbedded…#6
Nova-machinepulse merged 9 commits intomainfrom
feat/openclaw-plugin

Conversation

@daibor
Copy link
Copy Markdown
Collaborator

@daibor daibor commented Apr 28, 2026

…Agent

Native OpenClaw plugin that loads enabled sensors from ~/.world2agent/sensors.json in-process, queues each emitted signal per sensor session, and dispatches it through api.runtime.agent.runEmbeddedAgent so a fresh agent turn handles every signal. Verified end-to-end against a local OpenClaw 2026.4.15 gateway with @world2agent/sensor-hackernews + openrouter/moonshotai/kimi-k2.6.

Hard contracts enforced at register():

  • agents.defaults.contextInjection must equal "continuation-skip"; missing setting causes plugin start to throw with the exact field path to fix. Same check fires up front in openclaw world2agent sensor add so the install path fails before mutating manifest state.
  • api.runtime.agent.runEmbeddedAgent must be present; surfaces as an M0 spike message rather than a silent no-op.
  • register() stays synchronous; OpenClaw's plugin loader drops registers that return a Promise. Async startup work runs as fire-and-forget.

Other notable bits:

  • Resolves provider/model from agents.defaults.model.primary because runEmbeddedAgent itself ignores the operator default and falls back to openai/gpt-5.4 when nothing is passed.
  • Pins sessionId per sensor (w2a-<sensorId>, sanitised against SAFE_SESSION_ID_RE) so continuation turns reuse the same transcript; sessionKey carries the colon-namespaced lane for run serialisation.
  • HttpDispatcher (POST /w2a/ingest, HMAC + X-Request-ID dedup) and the IsolatedRunner skeleton are wired so out-of-process sensors can come online without re-architecting the plugin.
  • Skill-routing default is the dedicated W2A agent's agents.list[].skills allowlist; prompt-prefix Use skill: <id> is the M1 fallback when no allowlist is configured.

Tests: 9 vitest cases covering manifest read/write, dispatcher serialisation + prompt-prefix fallback, HttpDispatcher HMAC/dedup, contextInjection startup throw, and synchronous register.

daibo@machinepulse.ai and others added 2 commits April 29, 2026 16:38
…Agent

Native OpenClaw plugin that loads enabled sensors from
~/.world2agent/sensors.json in-process, queues each emitted signal per
sensor session, and dispatches it through api.runtime.agent.runEmbeddedAgent
so a fresh agent turn handles every signal. Verified end-to-end against a
local OpenClaw 2026.4.15 gateway with @world2agent/sensor-hackernews +
openrouter/moonshotai/kimi-k2.6.

Hard contracts enforced at register():
- agents.defaults.contextInjection must equal "continuation-skip"; missing
  setting causes plugin start to throw with the exact field path to fix.
  Same check fires up front in `openclaw world2agent sensor add` so the
  install path fails before mutating manifest state.
- api.runtime.agent.runEmbeddedAgent must be present; surfaces as an M0
  spike message rather than a silent no-op.
- register() stays synchronous; OpenClaw's plugin loader drops registers
  that return a Promise. Async startup work runs as fire-and-forget.

Other notable bits:
- Resolves provider/model from agents.defaults.model.primary because
  runEmbeddedAgent itself ignores the operator default and falls back to
  openai/gpt-5.4 when nothing is passed.
- Pins sessionId per sensor (`w2a-<sensorId>`, sanitised against
  SAFE_SESSION_ID_RE) so continuation turns reuse the same transcript;
  sessionKey carries the colon-namespaced lane for run serialisation.
- HttpDispatcher (POST /w2a/ingest, HMAC + X-Request-ID dedup) and the
  IsolatedRunner skeleton are wired so out-of-process sensors can come
  online without re-architecting the plugin.
- Skill-routing default is the dedicated W2A agent's
  agents.list[].skills allowlist; prompt-prefix `Use skill: <id>` is the
  M1 fallback when no allowlist is configured.

Tests: 9 vitest cases covering manifest read/write, dispatcher
serialisation + prompt-prefix fallback, HttpDispatcher HMAC/dedup,
contextInjection startup throw, and synchronous register.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nova-machinepulse and others added 4 commits April 29, 2026 16:52
- Root README: new openclaw-plugin row in the package table, a full
  "Quick start — OpenClaw" section modeled on the Claude / Hermes
  ones (contextInjection prereq, conversational install, gateway
  restart caveat, w2a-* session lane pointer), Repository layout
  entry, and an Updating section for the npm publish flow.
- openclaw-plugin SKILL.md: Step 7 now hands `openclaw gateway restart`
  back to the user instead of running it from inside the chat —
  running it there kills the gateway and truncates the agent's reply.
- openclaw-plugin README: "Where to view" section rewritten to match
  B-mode dispatch (runEmbeddedAgent + `# System Event` framing) and
  to tell users explicitly to switch to the `w2a-<sensor>` session
  lane in dashboard; main chat lane is intentionally untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The conversational-install docs (root README, openclaw-plugin README,
and the world2agent-manage SKILL.md) had a Chinese sample utterance and
a Chinese gateway-restart prompt that the agent was supposed to repeat
verbatim. Replace both with English so the docs stay consistent in one
language and so the SKILL.md sample reads as a template the agent
delivers in the user's actual language, not a prescribed Chinese reply.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…iver config

Add an optional `deliver: { channel, to, accountId?, threadId? }` block at
plugin-level (`~/.openclaw/openclaw.json`) and per-sensor (manifest entry +
`sensor add --deliver-channel/--deliver-to/...` CLI flags). When set, the
plugin (a) writes lastChannel/lastTo/deliveryContext onto the W2A session
entry and (b) dispatches via `runtime.subagent.run({ deliver: true })` so
OpenClaw's resolveAgentDeliveryPlan + deliverAgentCommandResult routes the
final assistant reply through the matching channel plugin (lark/feishu/
whatsapp/telegram/...) — no second LLM call, no plugin-side IM client.

Falls back to the prior `runtime.agent.runEmbeddedAgent` path when deliver
is absent OR when the runtime predates `subagent.run`, so existing
deployments are unaffected.

Drive-by fix: stop pinning `agentHarnessId: "claude-cli"` on the W2A
session entry. That field, once persisted, made OpenClaw refuse the run
on hosts where claude-cli isn't a registered harness ("Requested agent
harness 'claude-cli' is not registered"). Also strip a stale value from
existing entries on the next dispatch so users don't have to hand-edit
sessions.json after upgrading.

The `world2agent-manage` skill now runs `openclaw plugins list --json` at
install time to detect enabled inbound channels (channelIds non-empty) and
asks the user once whether to push that sensor's replies to one of them —
chat id is always asked from the user, never invented.

13 vitest tests cover plugin/per-sensor deliver wiring, deliveryContext
session persistence, the new subagent.run path, and the rejection of
provider/model overrides on subagent.run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Nova-machinepulse Nova-machinepulse marked this pull request as ready for review April 29, 2026 13:31
@Nova-machinepulse Nova-machinepulse merged commit 40b7003 into main Apr 29, 2026
1 check passed
@Nova-machinepulse Nova-machinepulse deleted the feat/openclaw-plugin branch April 29, 2026 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants