@relaymessenger/openclaw-plugin 0.4.3-staging.6 → 0.4.3-staging.8

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 CHANGED
@@ -183,3 +183,11 @@ tarball, hashes it against the lock, and checks the installed SDK's version and
183
183
  types. Production publishes carry no npm attestation (Blacksmith runners), so
184
184
  the tarball bytes are the receipt. These are artifact compatibility checks,
185
185
  not a claim of a hosted Relay deployment test.
186
+
187
+ ## Add Relay with `openclaw channels add relay`
188
+
189
+ ```bash
190
+ openclaw channels add relay --token <RELAY_AGENT_TOKEN> --base-url https://api.relayapp.im
191
+ ```
192
+
193
+ OpenClaw prints: `Relay configured.`
@@ -1,4 +1,5 @@
1
1
  import { createChatChannelPlugin, } from "openclaw/plugin-sdk/channel-core";
2
+ import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
2
3
  import { createMessageReceiptFromOutboundResults, defineChannelMessageAdapter, } from "openclaw/plugin-sdk/channel-outbound";
3
4
  import { chunkText } from "openclaw/plugin-sdk/reply-chunking";
4
5
  import { DEFAULT_ACCOUNT_ID, listRelayAccountIds, resolveDefaultRelayAccountId, resolveRelayAccount, } from "./accounts.js";
@@ -128,6 +129,24 @@ export const relayMessageAdapter = defineChannelMessageAdapter({
128
129
  },
129
130
  },
130
131
  });
132
+ const RELAY_MISSING_TOKEN = `relay: account "default" has no Relay Agent Token`;
133
+ const baseRelaySetupContract = defineChannelSetupContract({
134
+ adapter: {
135
+ applyAccountConfig: ({ cfg, accountId, input }) => {
136
+ const core = cfg;
137
+ const section = { ...core.channels?.relay };
138
+ const patch = input;
139
+ const relay = accountId === DEFAULT_ACCOUNT_ID ? { ...section, ...patch } : { ...section, accounts: { ...section.accounts, [accountId]: { ...section.accounts?.[accountId], ...patch } } };
140
+ return { ...cfg, channels: { ...core.channels, relay } };
141
+ },
142
+ },
143
+ fields: {
144
+ token: { kind: "string", sensitive: true, cli: { flags: "--token <token>", description: "Relay Agent Token" } },
145
+ baseUrl: { kind: "string", cli: { flags: "--base-url <url>", description: "Relay API origin" } },
146
+ },
147
+ });
148
+ export const relaySetupContract = { ...baseRelaySetupContract, parseInput: (input) => { const result = baseRelaySetupContract.parseInput(input); if (!result.ok || typeof result.value.token !== "string" || !result.value.token.trim())
149
+ return { ok: false, error: RELAY_MISSING_TOKEN }; return result; } };
131
150
  export const relayChannelPlugin = createChatChannelPlugin({
132
151
  base: {
133
152
  id: RELAY_CHANNEL_ID,
@@ -144,32 +163,7 @@ export const relayChannelPlugin = createChatChannelPlugin({
144
163
  blockStreaming: false,
145
164
  },
146
165
  reload: { configPrefixes: ["channels.relay"] },
147
- setup: {
148
- applyAccountConfig: ({ cfg, accountId, input }) => {
149
- const core = cfg;
150
- const section = { ...core.channels?.relay };
151
- const patch = input;
152
- const relay = !accountId || accountId === DEFAULT_ACCOUNT_ID
153
- ? { ...section, ...patch }
154
- : {
155
- ...section,
156
- accounts: {
157
- ...section.accounts,
158
- [accountId]: {
159
- ...section.accounts?.[accountId],
160
- ...patch,
161
- },
162
- },
163
- };
164
- return {
165
- ...cfg,
166
- channels: {
167
- ...core.channels,
168
- relay,
169
- },
170
- };
171
- },
172
- },
166
+ setupContract: relaySetupContract,
173
167
  config: {
174
168
  listAccountIds: (cfg) => listRelayAccountIds(cfg),
175
169
  resolveAccount: (cfg, accountId) => resolveRelayAccount({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relaymessenger/openclaw-plugin",
3
- "version": "0.4.3-staging.6",
3
+ "version": "0.4.3-staging.8",
4
4
  "description": "Native Relay channel plugin for OpenClaw",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/channel.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  type ChannelPlugin,
7
7
  type OpenClawConfig,
8
8
  } from "openclaw/plugin-sdk/channel-core";
9
+ import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
9
10
  import {
10
11
  createMessageReceiptFromOutboundResults,
11
12
  defineChannelMessageAdapter,
@@ -187,6 +188,26 @@ export const relayMessageAdapter = defineChannelMessageAdapter({
187
188
  },
188
189
  });
189
190
 
191
+ const RELAY_MISSING_TOKEN = `relay: account "default" has no Relay Agent Token`;
192
+
193
+ const baseRelaySetupContract = defineChannelSetupContract({
194
+ adapter: {
195
+ applyAccountConfig: ({ cfg, accountId, input }: { cfg: OpenClawConfig; accountId: string; input: unknown }) => {
196
+ const core = cfg as RelayCoreConfig;
197
+ const section = { ...core.channels?.relay };
198
+ const patch = input as Record<string, unknown>;
199
+ const relay = accountId === DEFAULT_ACCOUNT_ID ? { ...section, ...patch } : { ...section, accounts: { ...section.accounts, [accountId]: { ...section.accounts?.[accountId], ...patch } } };
200
+ return { ...cfg, channels: { ...core.channels, relay } } as OpenClawConfig;
201
+ },
202
+ },
203
+ fields: {
204
+ token: { kind: "string", sensitive: true, cli: { flags: "--token <token>", description: "Relay Agent Token" } },
205
+ baseUrl: { kind: "string", cli: { flags: "--base-url <url>", description: "Relay API origin" } },
206
+ },
207
+ });
208
+
209
+ export const relaySetupContract = { ...baseRelaySetupContract, parseInput: (input: unknown) => { const result = baseRelaySetupContract.parseInput(input); if (!result.ok || typeof (result.value as Record<string, unknown>).token !== "string" || !((result.value as Record<string, unknown>).token as string).trim()) return { ok: false as const, error: RELAY_MISSING_TOKEN }; return result; } };
210
+
190
211
  export const relayChannelPlugin: ChannelPlugin<ResolvedRelayAccount> =
191
212
  createChatChannelPlugin({
192
213
  base: {
@@ -204,33 +225,7 @@ export const relayChannelPlugin: ChannelPlugin<ResolvedRelayAccount> =
204
225
  blockStreaming: false,
205
226
  },
206
227
  reload: { configPrefixes: ["channels.relay"] },
207
- setup: {
208
- applyAccountConfig: ({ cfg, accountId, input }) => {
209
- const core = cfg as RelayCoreConfig;
210
- const section = { ...core.channels?.relay };
211
- const patch = input as Record<string, unknown>;
212
- const relay =
213
- !accountId || accountId === DEFAULT_ACCOUNT_ID
214
- ? { ...section, ...patch }
215
- : {
216
- ...section,
217
- accounts: {
218
- ...section.accounts,
219
- [accountId]: {
220
- ...section.accounts?.[accountId],
221
- ...patch,
222
- },
223
- },
224
- };
225
- return {
226
- ...cfg,
227
- channels: {
228
- ...core.channels,
229
- relay,
230
- },
231
- } as OpenClawConfig;
232
- },
233
- },
228
+ setupContract: relaySetupContract,
234
229
  config: {
235
230
  listAccountIds: (cfg) =>
236
231
  listRelayAccountIds(cfg as RelayCoreConfig),