@lingyao037/openclaw-lingyao-cli 0.9.6 → 0.9.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.
@@ -1,4 +1,4 @@
1
- import { L as LingyaoRuntime, g as LingyaoAccount, c as DeviceToken, D as DeviceInfo } from './types-LFC6Wpqo.js';
1
+ import { L as LingyaoRuntime, g as LingyaoAccount, c as DeviceToken, D as DeviceInfo } from './types-D3SmE-b0.js';
2
2
 
3
3
  /**
4
4
  * Account storage and management
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { L as LingyaoRuntime, H as HealthStatus } from './types-LFC6Wpqo.js';
2
- import { A as AccountManager } from './accounts-BykE02r0.js';
1
+ import { L as LingyaoRuntime, H as HealthStatus } from './types-D3SmE-b0.js';
2
+ import { A as AccountManager } from './accounts-t-QtF58y.js';
3
3
 
4
4
  /**
5
5
  * Probe status levels
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { R as ResolvedAccount, L as LingyaoProbeResult } from './status-CVwSoPKi.js';
1
+ import { R as ResolvedAccount, L as LingyaoProbeResult } from './status-BaZOYVZY.js';
2
2
  import * as openclaw_plugin_sdk from 'openclaw/plugin-sdk';
3
3
  import { PluginRuntime, ChannelPlugin } from 'openclaw/plugin-sdk';
4
- import { L as LingyaoRuntime, S as SyncRequest, a as SyncResponse, b as LingyaoMessage, D as DeviceInfo, c as DeviceToken, d as LingyaoConfig, N as NotifyPayload, H as HealthStatus } from './types-LFC6Wpqo.js';
5
- export { A as AckRequest, e as DiarySyncPayload, F as FailedEntry, f as LINGYAO_SERVER_URL, g as LingyaoAccount, h as LingyaoAccountConfig, M as MemorySyncPayload, i as MessageType, j as NotifyAction, k as NotifyRequest, P as PairingCode, l as PairingConfirmRequest, m as PairingConfirmResponse, n as PollRequest, o as PollResponse, Q as QueuedMessage, T as TokenRefreshRequest, p as TokenRefreshResponse, W as WebSocketConnection, q as getLingyaoGatewayWsUrl } from './types-LFC6Wpqo.js';
6
- import { A as AccountManager } from './accounts-BykE02r0.js';
4
+ import { L as LingyaoRuntime, S as SyncRequest, a as SyncResponse, b as LingyaoMessage, D as DeviceInfo, c as DeviceToken, d as LingyaoConfig, N as NotifyPayload, H as HealthStatus } from './types-D3SmE-b0.js';
5
+ export { A as AckRequest, e as DiarySyncPayload, F as FailedEntry, f as LINGYAO_SERVER_URL, g as LingyaoAccount, h as LingyaoAccountConfig, M as MemorySyncPayload, i as MessageType, j as NotifyAction, k as NotifyRequest, P as PairingCode, l as PairingConfirmRequest, m as PairingConfirmResponse, n as PollRequest, o as PollResponse, Q as QueuedMessage, T as TokenRefreshRequest, p as TokenRefreshResponse, W as WebSocketConnection, q as getLingyaoGatewayWsUrl } from './types-D3SmE-b0.js';
6
+ import { A as AccountManager } from './accounts-t-QtF58y.js';
7
7
 
8
8
  /**
9
9
  * 灵爻服务器 HTTP 客户端
@@ -126,6 +126,10 @@ declare class ServerHttpClient {
126
126
  * 获取 Gateway Token
127
127
  */
128
128
  getGatewayToken(): string | null;
129
+ /**
130
+ * HTTP 注册/恢复后由 `serverConfig.heartbeatInterval` 写入(毫秒),用于与 WebSocket `gateway_heartbeat` 对齐。
131
+ */
132
+ getHeartbeatIntervalMs(): number;
129
133
  /**
130
134
  * 检查 Token 是否即将过期
131
135
  */
@@ -169,18 +173,17 @@ declare class ServerHttpClient {
169
173
  */
170
174
  type ConnectionState = "connecting" | "connected" | "disconnected" | "error";
171
175
  /**
172
- * WebSocket 消息类型
176
+ * WebSocket 消息类型(与 `lingyao/server/src/server.ts` 中 Gateway 协议一致)
173
177
  */
174
178
  declare enum WSMessageType {
175
- REGISTER = "register",
176
- HEARTBEAT = "heartbeat",
177
- SEND_MESSAGE = "send_message",
178
- ACK = "ack",
179
- REGISTERED = "registered",
180
- HEARTBEAT_ACK = "heartbeat_ack",
179
+ GATEWAY_REGISTER = "gateway_register",
180
+ GATEWAY_HEARTBEAT = "gateway_heartbeat",
181
+ GATEWAY_SEND_MESSAGE = "gateway_send_message",
182
+ GATEWAY_REGISTERED = "gateway_registered",
183
+ GATEWAY_HEARTBEAT_ACK = "gateway_heartbeat_ack",
181
184
  MESSAGE_DELIVERED = "message_delivered",
182
185
  MESSAGE_FAILED = "message_failed",
183
- APP_MESSAGE = "app_message",// 来自 App 的消息
186
+ APP_MESSAGE = "app_message",
184
187
  DEVICE_ONLINE = "device_online",
185
188
  PAIRING_COMPLETED = "pairing_completed",
186
189
  ERROR = "error"
@@ -340,6 +343,10 @@ declare class LingyaoWSClient {
340
343
  * 处理消息发送成功
341
344
  */
342
345
  private handleMessageDelivered;
346
+ /**
347
+ * 设备上线(服务器可选推送)
348
+ */
349
+ private handleDeviceOnline;
343
350
  /**
344
351
  * 处理配对完成通知(来自 lingyao.live 服务器)
345
352
  */
package/dist/index.js CHANGED
@@ -91,7 +91,8 @@ function extractAccounts(cfg) {
91
91
  allowFrom: Array.isArray(lingyao.allowFrom) ? lingyao.allowFrom : [],
92
92
  maxOfflineMessages: lingyao.maxOfflineMessages,
93
93
  tokenExpiryDays: lingyao.tokenExpiryDays,
94
- gatewayId: lingyao.gatewayId
94
+ gatewayId: lingyao.gatewayId,
95
+ websocketHeartbeatIntervalMs: lingyao.websocketHeartbeatIntervalMs
95
96
  };
96
97
  if (!accounts || Object.keys(accounts).length === 0) {
97
98
  return { default: baseConfig };
@@ -424,6 +425,25 @@ var MessageType = /* @__PURE__ */ ((MessageType2) => {
424
425
  return MessageType2;
425
426
  })(MessageType || {});
426
427
 
428
+ // src/ws-heartbeat-interval.ts
429
+ var MIN_MS = 5e3;
430
+ var MAX_MS = 55e3;
431
+ var FALLBACK_MS = 3e4;
432
+ function resolveLingyaoWsHeartbeatIntervalMs(account, httpClient) {
433
+ const fromServer = httpClient.getHeartbeatIntervalMs();
434
+ const fromCfg = account.rawConfig?.websocketHeartbeatIntervalMs;
435
+ let ms = typeof fromCfg === "number" && Number.isFinite(fromCfg) && fromCfg > 0 ? fromCfg : fromServer;
436
+ if (!Number.isFinite(ms) || ms <= 0) {
437
+ ms = FALLBACK_MS;
438
+ }
439
+ return Math.max(MIN_MS, Math.min(ms, MAX_MS));
440
+ }
441
+ function resolveLingyaoWsHeartbeatIntervalMsFromHttp(httpClient) {
442
+ const ms = httpClient.getHeartbeatIntervalMs();
443
+ const base = Number.isFinite(ms) && ms > 0 ? ms : FALLBACK_MS;
444
+ return Math.max(MIN_MS, Math.min(base, MAX_MS));
445
+ }
446
+
427
447
  // src/server-client.ts
428
448
  import axios from "axios";
429
449
  function isAxiosError(error) {
@@ -655,6 +675,12 @@ var ServerHttpClient = class {
655
675
  getGatewayToken() {
656
676
  return this.gatewayToken;
657
677
  }
678
+ /**
679
+ * HTTP 注册/恢复后由 `serverConfig.heartbeatInterval` 写入(毫秒),用于与 WebSocket `gateway_heartbeat` 对齐。
680
+ */
681
+ getHeartbeatIntervalMs() {
682
+ return this.heartbeatInterval > 0 ? this.heartbeatInterval : 3e4;
683
+ }
658
684
  /**
659
685
  * 检查 Token 是否即将过期
660
686
  */
@@ -736,6 +762,20 @@ import WebSocket from "ws";
736
762
  function isWebsocketUpgradeNotFoundError(message) {
737
763
  return /Unexpected server response:\s*404/i.test(message) || /\b404\b/.test(message);
738
764
  }
765
+ function normalizeIncomingGatewayMessageType(type) {
766
+ switch (type) {
767
+ case "registered":
768
+ return "gateway_registered" /* GATEWAY_REGISTERED */;
769
+ case "heartbeat_ack":
770
+ return "gateway_heartbeat_ack" /* GATEWAY_HEARTBEAT_ACK */;
771
+ case "gateway_registered":
772
+ return "gateway_registered" /* GATEWAY_REGISTERED */;
773
+ case "gateway_heartbeat_ack":
774
+ return "gateway_heartbeat_ack" /* GATEWAY_HEARTBEAT_ACK */;
775
+ default:
776
+ return type;
777
+ }
778
+ }
739
779
  var LingyaoWSClient = class {
740
780
  config;
741
781
  ws = null;
@@ -750,11 +790,12 @@ var LingyaoWSClient = class {
750
790
  constructor(runtime, config) {
751
791
  this.logger = runtime.logger;
752
792
  this.config = { ...config };
753
- this.registerMessageHandler("registered" /* REGISTERED */, this.handleRegistered.bind(this));
754
- this.registerMessageHandler("heartbeat_ack" /* HEARTBEAT_ACK */, this.handleHeartbeatAck.bind(this));
793
+ this.registerMessageHandler("gateway_registered" /* GATEWAY_REGISTERED */, this.handleRegistered.bind(this));
794
+ this.registerMessageHandler("gateway_heartbeat_ack" /* GATEWAY_HEARTBEAT_ACK */, this.handleHeartbeatAck.bind(this));
755
795
  this.registerMessageHandler("message_delivered" /* MESSAGE_DELIVERED */, this.handleMessageDelivered.bind(this));
756
796
  this.registerMessageHandler("message_failed" /* MESSAGE_FAILED */, this.handleMessageFailed.bind(this));
757
797
  this.registerMessageHandler("app_message" /* APP_MESSAGE */, this.handleAppMessage.bind(this));
798
+ this.registerMessageHandler("device_online" /* DEVICE_ONLINE */, this.handleDeviceOnline.bind(this));
758
799
  this.registerMessageHandler("pairing_completed" /* PAIRING_COMPLETED */, this.handlePairingCompleted.bind(this));
759
800
  this.registerMessageHandler("error" /* ERROR */, this.handleError.bind(this));
760
801
  }
@@ -828,12 +869,14 @@ var LingyaoWSClient = class {
828
869
  async handleMessage(data) {
829
870
  try {
830
871
  const message = JSON.parse(data.toString());
831
- this.logger.debug("Received message from server", { type: message.type });
832
- const handler = this.messageHandlers.get(message.type);
872
+ const rawType = String(message.type);
873
+ const handlerKey = normalizeIncomingGatewayMessageType(rawType);
874
+ this.logger.debug("Received message from server", { type: rawType, handlerKey });
875
+ const handler = this.messageHandlers.get(handlerKey);
833
876
  if (handler) {
834
877
  handler(message);
835
878
  } else {
836
- this.logger.warn("No handler for message type", { type: message.type });
879
+ this.logger.warn("No handler for message type", { type: rawType });
837
880
  }
838
881
  this.emitEvent({ type: "message", message });
839
882
  } catch (error) {
@@ -884,7 +927,7 @@ var LingyaoWSClient = class {
884
927
  */
885
928
  sendRegister() {
886
929
  const message = {
887
- type: "register" /* REGISTER */,
930
+ type: "gateway_register" /* GATEWAY_REGISTER */,
888
931
  id: this.generateMessageId(),
889
932
  timestamp: Date.now(),
890
933
  payload: {
@@ -913,7 +956,7 @@ var LingyaoWSClient = class {
913
956
  */
914
957
  sendHeartbeat() {
915
958
  const message = {
916
- type: "heartbeat" /* HEARTBEAT */,
959
+ type: "gateway_heartbeat" /* GATEWAY_HEARTBEAT */,
917
960
  id: this.generateMessageId(),
918
961
  timestamp: Date.now(),
919
962
  payload: {
@@ -984,7 +1027,7 @@ var LingyaoWSClient = class {
984
1027
  */
985
1028
  sendNotification(deviceId, notification) {
986
1029
  const message = {
987
- type: "send_message" /* SEND_MESSAGE */,
1030
+ type: "gateway_send_message" /* GATEWAY_SEND_MESSAGE */,
988
1031
  id: this.generateMessageId(),
989
1032
  timestamp: Date.now(),
990
1033
  payload: {
@@ -1023,6 +1066,14 @@ var LingyaoWSClient = class {
1023
1066
  messageId: message.id
1024
1067
  });
1025
1068
  }
1069
+ /**
1070
+ * 设备上线(服务器可选推送)
1071
+ */
1072
+ handleDeviceOnline(message) {
1073
+ this.logger.debug("Device online (server push)", {
1074
+ payload: message.payload
1075
+ });
1076
+ }
1026
1077
  /**
1027
1078
  * 处理配对完成通知(来自 lingyao.live 服务器)
1028
1079
  */
@@ -2730,12 +2781,14 @@ var MultiAccountOrchestrator = class {
2730
2781
  messageProcessor.setMessageHandler(this.messageHandler);
2731
2782
  }
2732
2783
  await this.registerToServer(state);
2784
+ const wsHeartbeatMs = resolveLingyaoWsHeartbeatIntervalMs(account, httpClient);
2785
+ this.runtime.logger.info(`Lingyao WebSocket heartbeat interval: ${wsHeartbeatMs}ms (relay serverConfig / config)`);
2733
2786
  const wsClient = new LingyaoWSClient(this.runtime, {
2734
2787
  url: getLingyaoGatewayWsUrl(),
2735
2788
  gatewayId,
2736
2789
  token: httpClient.getGatewayToken() ?? void 0,
2737
2790
  reconnectInterval: 5e3,
2738
- heartbeatInterval: 3e4,
2791
+ heartbeatInterval: wsHeartbeatMs,
2739
2792
  messageHandler: this.createMessageHandler(state),
2740
2793
  eventHandler: this.createEventHandler(state)
2741
2794
  });
@@ -3224,8 +3277,7 @@ var LingyaoChannel = class {
3224
3277
  this.monitor = new Monitor(runtime);
3225
3278
  this.errorHandler = new ErrorHandler(runtime);
3226
3279
  this.serverClient = new ServerHttpClient(runtime, this.gatewayId, {
3227
- baseURL: LINGYAO_SERVER_URL,
3228
- apiBase: "/v1"
3280
+ baseURL: LINGYAO_SERVER_URL
3229
3281
  });
3230
3282
  }
3231
3283
  /**
@@ -3255,12 +3307,13 @@ var LingyaoChannel = class {
3255
3307
  this.runtime.logger.info("Starting Lingyao Channel...");
3256
3308
  try {
3257
3309
  await this.registerToServer();
3310
+ const wsHeartbeatMs = this.serverClient ? resolveLingyaoWsHeartbeatIntervalMsFromHttp(this.serverClient) : 3e4;
3258
3311
  this.wsClient = new LingyaoWSClient(this.runtime, {
3259
3312
  url: getLingyaoGatewayWsUrl(),
3260
3313
  gatewayId: this.gatewayId,
3261
3314
  token: this.serverClient?.getGatewayToken() ?? void 0,
3262
3315
  reconnectInterval: 5e3,
3263
- heartbeatInterval: 3e4,
3316
+ heartbeatInterval: wsHeartbeatMs,
3264
3317
  messageHandler: this.handleAppMessage.bind(this),
3265
3318
  eventHandler: this.handleClientEvent.bind(this)
3266
3319
  });
@@ -3607,7 +3660,8 @@ var lingyaoAccountConfigSchema = z.object({
3607
3660
  allowFrom: allowFromSchema,
3608
3661
  maxOfflineMessages: z.number().int().min(1).max(1e3).optional(),
3609
3662
  tokenExpiryDays: z.number().int().min(1).max(365).optional(),
3610
- gatewayId: z.string().min(1).optional()
3663
+ gatewayId: z.string().min(1).optional(),
3664
+ websocketHeartbeatIntervalMs: z.number().int().min(5e3).max(12e4).optional()
3611
3665
  });
3612
3666
  var lingyaoConfigSchema = z.object({
3613
3667
  enabled: z.boolean().default(true),
@@ -3615,6 +3669,7 @@ var lingyaoConfigSchema = z.object({
3615
3669
  allowFrom: allowFromSchema.default([]),
3616
3670
  maxOfflineMessages: z.number().int().min(1).max(1e3).optional().default(100),
3617
3671
  tokenExpiryDays: z.number().int().min(1).max(365).optional().default(30),
3672
+ websocketHeartbeatIntervalMs: z.number().int().min(5e3).max(12e4).optional(),
3618
3673
  defaultAccount: z.string().min(1).optional(),
3619
3674
  accounts: z.record(lingyaoAccountConfigSchema).optional()
3620
3675
  });
@@ -3652,6 +3707,12 @@ var lingyaoChannelConfigSchema = {
3652
3707
  defaultAccount: {
3653
3708
  type: "string"
3654
3709
  },
3710
+ websocketHeartbeatIntervalMs: {
3711
+ type: "integer",
3712
+ minimum: 5e3,
3713
+ maximum: 12e4,
3714
+ description: "WebSocket gateway_heartbeat interval in ms (default: server register response). Use 5000\u201355000 for typical relay timeout."
3715
+ },
3655
3716
  accounts: {
3656
3717
  type: "object",
3657
3718
  additionalProperties: {
@@ -3681,6 +3742,11 @@ var lingyaoChannelConfigSchema = {
3681
3742
  },
3682
3743
  gatewayId: {
3683
3744
  type: "string"
3745
+ },
3746
+ websocketHeartbeatIntervalMs: {
3747
+ type: "integer",
3748
+ minimum: 5e3,
3749
+ maximum: 12e4
3684
3750
  }
3685
3751
  }
3686
3752
  },
@@ -3799,7 +3865,7 @@ async function createPlugin(runtime, config = {}) {
3799
3865
  }
3800
3866
  var pluginMetadata = {
3801
3867
  name: "lingyao",
3802
- version: "0.9.6",
3868
+ version: "0.9.8",
3803
3869
  description: "Lingyao Channel Plugin - bidirectional sync via lingyao.live server relay",
3804
3870
  type: "channel",
3805
3871
  capabilities: {