clawrelay 0.3.7 → 0.4.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawrelay",
3
- "version": "0.3.7",
3
+ "version": "0.4.0",
4
4
  "description": "Channel relay plugin for OpenClaw — receives messages from an always-on relay proxy",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -76,12 +76,12 @@ export function createRelayInboundHandler(api: any) {
76
76
  // Streaming mode: ack immediately, then send deltas via events
77
77
  respond(true, { messageId: message.messageId, streaming: true });
78
78
 
79
- const streamCallback = (text: string) => {
79
+ const onPartialText = (text: string) => {
80
80
  try {
81
81
  sendEventToClient('relay.stream.delta', {
82
82
  messageId: message.messageId,
83
83
  text,
84
- kind: 'deliver',
84
+ kind: 'partial',
85
85
  });
86
86
  } catch (err) {
87
87
  logger.debug(`[clawrelay] Failed to send stream delta: ${err}`);
@@ -94,7 +94,7 @@ export function createRelayInboundHandler(api: any) {
94
94
  account,
95
95
  config,
96
96
  log: logger,
97
- streamCallback,
97
+ onPartialText,
98
98
  });
99
99
 
100
100
  sendEventToClient('relay.stream.done', {
@@ -140,13 +140,6 @@ export function createRelayInboundHandler(api: any) {
140
140
 
141
141
  // --- Inbound message processing (extracted from channel.ts) ---
142
142
 
143
- function resolveSessionKey(message: RelayInboundMessage): string {
144
- if (message.chatType === 'direct') {
145
- return `relay:${message.platform}:dm:${message.senderId}`;
146
- }
147
- return `relay:${message.platform}:${message.guildId ?? 'unknown'}:${message.channelId}`;
148
- }
149
-
150
143
  function resolvePeerId(message: RelayInboundMessage): string {
151
144
  if (message.chatType === 'direct') {
152
145
  return `relay:${message.platform}:dm:${message.senderId}`;
@@ -159,9 +152,9 @@ async function processRelayMessage(params: {
159
152
  account: RelayAccount;
160
153
  config: any;
161
154
  log: any;
162
- streamCallback?: (text: string) => void;
155
+ onPartialText?: (text: string) => void;
163
156
  }): Promise<string> {
164
- const { message, account, config, log, streamCallback } = params;
157
+ const { message, account, config, log, onPartialText } = params;
165
158
 
166
159
  const core = getRelayRuntime();
167
160
  const peerId = resolvePeerId(message);
@@ -231,7 +224,7 @@ async function processRelayMessage(params: {
231
224
  },
232
225
  });
233
226
 
234
- // Dispatch reply — collect all deliver() calls into a single buffer
227
+ // Dispatch reply — collect final deliver() calls and stream partial text
235
228
  const parts: string[] = [];
236
229
 
237
230
  await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
@@ -242,13 +235,23 @@ async function processRelayMessage(params: {
242
235
  const text = payload.text ?? '';
243
236
  if (text.trim()) {
244
237
  parts.push(text);
245
- streamCallback?.(text);
246
238
  }
247
239
  },
248
240
  onError: (err: unknown, info: { kind: string }) => {
249
241
  log?.error(`[clawrelay] ${info.kind} reply failed: ${String(err)}`);
250
242
  },
251
243
  },
244
+ // Stream progressive text via onPartialReply (fires as tokens arrive)
245
+ replyOptions: onPartialText
246
+ ? {
247
+ onPartialReply: (payload: { text?: string }) => {
248
+ const text = payload.text ?? '';
249
+ if (text.trim()) {
250
+ onPartialText(text);
251
+ }
252
+ },
253
+ }
254
+ : undefined,
252
255
  });
253
256
 
254
257
  log?.info(`[clawrelay] Processed message ${message.messageId} from ${message.senderName}`);