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

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,25 @@ export const relayMessageAdapter = defineChannelMessageAdapter({
128
129
  },
129
130
  },
130
131
  });
132
+ const relaySetupAdapter = {
133
+ applyAccountConfig: ({ cfg, accountId, input }) => {
134
+ const core = cfg;
135
+ const patch = input;
136
+ const section = { ...core.channels?.relay };
137
+ const relay = accountId === DEFAULT_ACCOUNT_ID ? { ...section, ...patch } : { ...section, accounts: { ...section.accounts, [accountId]: { ...section.accounts?.[accountId], ...patch } } };
138
+ return { ...cfg, channels: { ...core.channels, relay } };
139
+ },
140
+ };
141
+ const RELAY_MISSING_TOKEN = `relay: account "default" has no Relay Agent Token`;
142
+ const baseRelaySetupContract = defineChannelSetupContract({
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
+ legacyAdapter: relaySetupAdapter,
148
+ });
149
+ export const relaySetupContract = { ...baseRelaySetupContract, parseInput: (input) => { const result = baseRelaySetupContract.parseInput(input); if (!result.ok || typeof result.value.token !== "string" || !result.value.token.trim())
150
+ return { ok: false, error: RELAY_MISSING_TOKEN }; return result; } };
131
151
  export const relayChannelPlugin = createChatChannelPlugin({
132
152
  base: {
133
153
  id: RELAY_CHANNEL_ID,
@@ -144,6 +164,7 @@ export const relayChannelPlugin = createChatChannelPlugin({
144
164
  blockStreaming: false,
145
165
  },
146
166
  reload: { configPrefixes: ["channels.relay"] },
167
+ setupContract: relaySetupContract,
147
168
  setup: {
148
169
  applyAccountConfig: ({ cfg, accountId, input }) => {
149
170
  const core = cfg;
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.7",
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,28 @@ export const relayMessageAdapter = defineChannelMessageAdapter({
187
188
  },
188
189
  });
189
190
 
191
+ const relaySetupAdapter = {
192
+ applyAccountConfig: ({ cfg, accountId, input }: { cfg: OpenClawConfig; accountId: string; input: unknown }) => {
193
+ const core = cfg as RelayCoreConfig;
194
+ const patch = input as Record<string, unknown>;
195
+ const section = { ...core.channels?.relay };
196
+ const relay = accountId === DEFAULT_ACCOUNT_ID ? { ...section, ...patch } : { ...section, accounts: { ...section.accounts, [accountId]: { ...section.accounts?.[accountId], ...patch } } };
197
+ return { ...cfg, channels: { ...core.channels, relay } } as OpenClawConfig;
198
+ },
199
+ };
200
+
201
+ const RELAY_MISSING_TOKEN = `relay: account "default" has no Relay Agent Token`;
202
+
203
+ const baseRelaySetupContract = defineChannelSetupContract({
204
+ fields: {
205
+ token: { kind: "string", sensitive: true, cli: { flags: "--token <token>", description: "Relay Agent Token" } },
206
+ baseUrl: { kind: "string", cli: { flags: "--base-url <url>", description: "Relay API origin" } },
207
+ },
208
+ legacyAdapter: relaySetupAdapter,
209
+ });
210
+
211
+ 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; } };
212
+
190
213
  export const relayChannelPlugin: ChannelPlugin<ResolvedRelayAccount> =
191
214
  createChatChannelPlugin({
192
215
  base: {
@@ -204,6 +227,7 @@ export const relayChannelPlugin: ChannelPlugin<ResolvedRelayAccount> =
204
227
  blockStreaming: false,
205
228
  },
206
229
  reload: { configPrefixes: ["channels.relay"] },
230
+ setupContract: relaySetupContract,
207
231
  setup: {
208
232
  applyAccountConfig: ({ cfg, accountId, input }) => {
209
233
  const core = cfg as RelayCoreConfig;