@shadowob/connector 1.1.3-dev.251
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/LICENSE +661 -0
- package/README.md +157 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +477 -0
- package/dist/index.cjs +293 -0
- package/dist/index.d.cts +35 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +267 -0
- package/hermes-shadowob-plugin/README.md +176 -0
- package/hermes-shadowob-plugin/__init__.py +8 -0
- package/hermes-shadowob-plugin/adapter.py +1572 -0
- package/hermes-shadowob-plugin/plugin.yaml +84 -0
- package/hermes-shadowob-plugin/requirements.txt +2 -0
- package/hermes-shadowob-plugin/shadow_sdk.py +479 -0
- package/hermes-shadowob-plugin/tests/test_adapter_env.py +159 -0
- package/hermes-shadowob-plugin/tests/test_shadow_sdk_helpers.py +25 -0
- package/package.json +57 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Hermes Shadow/OpenClaw Buddy Platform Plugin
|
|
2
|
+
|
|
3
|
+
This is a first-pass Hermes gateway platform adapter for Shadow/OpenClaw Buddy. It is packaged as a user plugin directory named `shadowob`.
|
|
4
|
+
|
|
5
|
+
It focuses on the messaging path:
|
|
6
|
+
|
|
7
|
+
- Shadow channel/direct/thread inbound messages to Hermes `MessageEvent`
|
|
8
|
+
- Hermes outbound text replies to Shadow messages
|
|
9
|
+
- `threadId` and `replyToId` routing via Hermes metadata
|
|
10
|
+
- Socket.IO realtime receive with REST polling fallback
|
|
11
|
+
- Optional REST-only polling mode
|
|
12
|
+
- Startup catch-up window
|
|
13
|
+
- Typing/activity emit over Socket.IO
|
|
14
|
+
- Inbound attachment download into Hermes media/document cache
|
|
15
|
+
- Outbound image/document/video/audio upload through Shadow media API
|
|
16
|
+
- Message edit/delete support for Hermes streaming/fresh-final cleanup
|
|
17
|
+
- Reaction helpers exposed on the adapter class
|
|
18
|
+
- Agent heartbeat/online status after resolving the Buddy agent id from `/api/auth/me`
|
|
19
|
+
- Dynamic channel and policy discovery through `/api/agents/:id/config`
|
|
20
|
+
- Optional slash command registration and slash-command prompt handling through `SHADOW_SLASH_COMMANDS_JSON`
|
|
21
|
+
- Interactive component sends via Shadow message metadata and interactive response forwarding to Hermes
|
|
22
|
+
- Cron/send_message standalone delivery through `SHADOW_HOME_CHANNEL`
|
|
23
|
+
|
|
24
|
+
It deliberately does not implement the whole Shadow product surface. Workspace, commerce, wallet, cloud sandbox, marketplace, OAuth and dashboard stats should be added as Hermes tools or an MCP server, not as platform-adapter logic.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
Unzip this package into your Hermes plugins directory:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
mkdir -p ~/.hermes/plugins
|
|
32
|
+
unzip hermes-shadowob-plugin.zip -d ~/.hermes/plugins
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
You should end up with:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
~/.hermes/plugins/shadowob/
|
|
39
|
+
__init__.py
|
|
40
|
+
adapter.py
|
|
41
|
+
shadow_sdk.py
|
|
42
|
+
plugin.yaml
|
|
43
|
+
requirements.txt
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Install plugin dependencies in the Python environment where Hermes runs:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install -r ~/.hermes/plugins/shadowob/requirements.txt
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Enable the plugin if your Hermes build gates user plugins through `plugins.enabled`:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
hermes plugins enable shadowob
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Then configure environment variables or put equivalent values in `~/.hermes/config.yaml`.
|
|
59
|
+
|
|
60
|
+
## Environment variables
|
|
61
|
+
|
|
62
|
+
Required:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
export SHADOW_BASE_URL="https://your-shadow.example.com"
|
|
66
|
+
export SHADOW_TOKEN="shadow_access_token"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The plugin resolves the Buddy agent id and channel policy dynamically from Shadow. Static channel ids are not required.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
export SHADOW_HEARTBEAT_INTERVAL_SECONDS=30
|
|
73
|
+
|
|
74
|
+
# Optional slash commands registered at startup
|
|
75
|
+
export SHADOW_SLASH_COMMANDS_JSON='[{"name":"audit","description":"Run an audit"}]'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Common optional settings:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
export SHADOW_ALLOWED_USERS="user_id_or_username_1,user_id_or_username_2"
|
|
82
|
+
export SHADOW_ALLOW_ALL_USERS=false
|
|
83
|
+
export SHADOW_BOT_USER_ID="bot_user_id" # optional; otherwise /api/auth/me is called
|
|
84
|
+
export SHADOW_BOT_USERNAME="bot_username" # optional; used by mention-only filter
|
|
85
|
+
export SHADOW_MENTION_ONLY=false # group/channel messages require @bot when true
|
|
86
|
+
export SHADOW_REPLY_TO_BOTS=false # loop guard
|
|
87
|
+
export SHADOW_REST_ONLY=false # true disables Socket.IO and uses polling
|
|
88
|
+
export SHADOW_POLL_INTERVAL_SECONDS=3
|
|
89
|
+
export SHADOW_CATCHUP_MINUTES=0 # set >0 to process recent messages on startup
|
|
90
|
+
export SHADOW_DOWNLOAD_MEDIA=true
|
|
91
|
+
|
|
92
|
+
# Advanced compatibility overrides; normally leave these unset so Shadow policy drives routing.
|
|
93
|
+
export SHADOW_CHANNEL_IDS="channel_id_1,channel_id_2"
|
|
94
|
+
export SHADOW_HOME_CHANNEL="channel_id_1"
|
|
95
|
+
export SHADOW_AGENT_ID="agent_id_1"
|
|
96
|
+
export SHADOW_SERVER_IDS="server_id_or_slug_1,server_id_or_slug_2"
|
|
97
|
+
export SHADOW_AUTO_DISCOVER_CHANNELS=true
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Example Hermes config.yaml fragment
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
plugins:
|
|
104
|
+
enabled:
|
|
105
|
+
- shadowob
|
|
106
|
+
|
|
107
|
+
platforms:
|
|
108
|
+
shadowob:
|
|
109
|
+
enabled: true
|
|
110
|
+
token: "${SHADOW_TOKEN}"
|
|
111
|
+
extra:
|
|
112
|
+
base_url: "${SHADOW_BASE_URL}"
|
|
113
|
+
slash_commands:
|
|
114
|
+
- name: "audit"
|
|
115
|
+
description: "Run an audit"
|
|
116
|
+
mention_only: false
|
|
117
|
+
rest_only: false
|
|
118
|
+
catchup_minutes: 0
|
|
119
|
+
download_media: true
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Metadata routing for outbound sends
|
|
123
|
+
|
|
124
|
+
The adapter accepts these Hermes send metadata keys:
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
metadata={
|
|
128
|
+
"thread_id": "shadow_thread_id", # or threadId / shadow_thread_id
|
|
129
|
+
"reply_to_message_id": "message_id", # or replyToId / reply_to / shadow_reply_to_id
|
|
130
|
+
"shadow_metadata": {...}, # forwarded as Shadow message metadata
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
For thread replies, Hermes generally supplies `source.thread_id` through its normal gateway dispatch path. For custom tool calls, pass the keys above.
|
|
135
|
+
|
|
136
|
+
## Files
|
|
137
|
+
|
|
138
|
+
- `adapter.py`: Hermes `BasePlatformAdapter` implementation and plugin `register(ctx)` entrypoint.
|
|
139
|
+
- `shadow_sdk.py`: small async REST + Socket.IO client matching the subset of Shadow TS SDK used by the adapter.
|
|
140
|
+
- `plugin.yaml` / `PLUGIN.yaml`: plugin manifest and configuration prompts.
|
|
141
|
+
- `requirements.txt`: runtime dependencies.
|
|
142
|
+
- `tests/`: offline unit tests for small parsing helpers.
|
|
143
|
+
|
|
144
|
+
## v0.2.0 checks and fixes
|
|
145
|
+
|
|
146
|
+
This iteration fixes issues found during static review against the uploaded Shadow project and the current Hermes plugin contract:
|
|
147
|
+
|
|
148
|
+
- Corrected `pytest` import path handling so offline tests run from the plugin directory and from an extracted zip.
|
|
149
|
+
- Registered both Shadow event naming variants: current server broadcasts `message:updated` / `message:deleted`, while shared constants also define `message:update` / `message:delete`.
|
|
150
|
+
- Fixed REST polling shutdown condition so the polling loop stops when the adapter is disconnected.
|
|
151
|
+
- Fixed `env_enablement_fn` to return a flat seed dict, because Hermes merges all non-`home_channel` keys directly into `PlatformConfig.extra`.
|
|
152
|
+
- Changed env auto-enable and connector setup to require only Shadow endpoint/token; Buddy id and channel policy are now resolved dynamically from Shadow.
|
|
153
|
+
- Added dynamic handling for `channel:member-added` and `channel:member-removed` events.
|
|
154
|
+
- Added dynamic handling for `server:joined` and `agent:policy-changed` events.
|
|
155
|
+
- Updated standalone media delivery to support local paths, `MEDIA:` refs, relative paths, Shadow private URLs and remote URLs through the SDK helper.
|
|
156
|
+
|
|
157
|
+
## Known limits in this first version
|
|
158
|
+
|
|
159
|
+
- Shadow interactive cards and commerce cards can be forwarded as `shadow_metadata` in outbound messages, but there is no LLM-facing Hermes tool schema in this package yet.
|
|
160
|
+
- Slash commands can be registered from JSON and routed into Hermes context; automatic discovery from Hermes skills/packs is not implemented yet.
|
|
161
|
+
- Buddy-chain rules are still simplified compared with `packages/openclaw-shadowob/src/monitor/preflight.ts`.
|
|
162
|
+
- REST polling uses recent message timestamps and an in-memory de-duplication set. It is not a persistent watermark store.
|
|
163
|
+
- External edits/deletes from Shadow are observed but not converted into Hermes conversation turns.
|
|
164
|
+
|
|
165
|
+
## Suggested next step
|
|
166
|
+
|
|
167
|
+
Add a separate Shadow tools plugin or MCP server for:
|
|
168
|
+
|
|
169
|
+
- `shadow_send_interactive`
|
|
170
|
+
- `shadow_send_commerce_card`
|
|
171
|
+
- `shadow_react_message`
|
|
172
|
+
- `shadow_edit_message`
|
|
173
|
+
- `shadow_delete_message`
|
|
174
|
+
- workspace/cloud/wallet/marketplace operations
|
|
175
|
+
|
|
176
|
+
Keeping these as tools avoids turning the platform adapter into business logic.
|