ylib-syim 0.0.29 → 0.0.31

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.
Files changed (2) hide show
  1. package/bridges/main.ts +146 -88
  2. package/package.json +4 -4
package/bridges/main.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { formatBeijingLogTimestamp, setupBridgeLogger } from "./logger.ts";
2
2
  import fs from "node:fs";
3
3
  import http from "node:http";
4
+ import { createRequire } from "node:module";
4
5
  import os from "node:os";
5
6
  import path from "node:path";
6
7
  import { fileURLToPath } from "node:url";
@@ -30,6 +31,7 @@ process.env.TZ = "Asia/Shanghai";
30
31
  // 3) 提供内部控制 API(status/config/apply/bot control/restart)。
31
32
  const bridgeDir = path.dirname(fileURLToPath(import.meta.url));
32
33
  const packageRoot = path.resolve(bridgeDir, "..");
34
+ const requireAtBridge = createRequire(import.meta.url);
33
35
 
34
36
  // 当前进程运行实例 ID,会在 restart-all 成功后旋转。
35
37
  let runtimeInstanceId = `bridges-${process.pid}-${Date.now()}`;
@@ -7097,103 +7099,159 @@ function resolveRawSchema(
7097
7099
  return {};
7098
7100
  }
7099
7101
 
7102
+ type PluginSchemaDescriptor = {
7103
+ pluginId: "dingtalk-connector" | "openclaw-lark" | "openclaw-weixin";
7104
+ channel: "dingtalk" | "feishu" | "weixin";
7105
+ packageName: string;
7106
+ dynamicLoader: () => Promise<Record<string, unknown>>;
7107
+ };
7108
+
7109
+ const pluginSchemaDescriptors: PluginSchemaDescriptor[] = [
7110
+ {
7111
+ pluginId: "dingtalk-connector",
7112
+ channel: "dingtalk",
7113
+ packageName: "ylib-dingtalk-connector",
7114
+ dynamicLoader: async () =>
7115
+ (await import("ylib-dingtalk-connector")) as Record<string, unknown>,
7116
+ },
7117
+ {
7118
+ pluginId: "openclaw-lark",
7119
+ channel: "feishu",
7120
+ packageName: "ylib-openclaw-lark",
7121
+ dynamicLoader: async () =>
7122
+ (await import("ylib-openclaw-lark")) as Record<string, unknown>,
7123
+ },
7124
+ {
7125
+ pluginId: "openclaw-weixin",
7126
+ channel: "weixin",
7127
+ packageName: "ylib-openclaw-weixin",
7128
+ dynamicLoader: async () => {
7129
+ try {
7130
+ return (await import("ylib-openclaw-weixin")) as Record<
7131
+ string,
7132
+ unknown
7133
+ >;
7134
+ } catch {
7135
+ return (await import("../../openclaw-weixin/index.ts")) as Record<
7136
+ string,
7137
+ unknown
7138
+ >;
7139
+ }
7140
+ },
7141
+ },
7142
+ ];
7143
+
7144
+ function asRawSchema(value: unknown): Record<string, unknown> | null {
7145
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
7146
+ return null;
7147
+ }
7148
+ return value as Record<string, unknown>;
7149
+ }
7150
+
7151
+ function readStaticPluginRawSchema(
7152
+ descriptor: PluginSchemaDescriptor,
7153
+ ): { rawSchema: Record<string, unknown>; source: string } | null {
7154
+ const candidates: string[] = [];
7155
+ try {
7156
+ const pluginJsonPath = requireAtBridge.resolve(
7157
+ `${descriptor.packageName}/openclaw.plugin.json`,
7158
+ );
7159
+ candidates.push(path.join(path.dirname(pluginJsonPath), "schema.json"));
7160
+ } catch {
7161
+ // package not found: static schema unavailable
7162
+ }
7163
+
7164
+ for (const candidate of candidates) {
7165
+ if (!candidate || !fs.existsSync(candidate)) continue;
7166
+ const raw = fs.readFileSync(candidate, "utf8");
7167
+ const parsed = JSON.parse(raw) as Record<string, unknown>;
7168
+ const parsedPluginId = String(parsed.pluginId || "").trim();
7169
+ if (parsedPluginId && parsedPluginId !== descriptor.pluginId) {
7170
+ throw new Error(
7171
+ `schema pluginId mismatch at ${candidate}: expected ${descriptor.pluginId}, got ${parsedPluginId}`,
7172
+ );
7173
+ }
7174
+ const rawSchema = asRawSchema(parsed.rawSchema);
7175
+ if (!rawSchema) {
7176
+ throw new Error(`schema.rawSchema missing or invalid at ${candidate}`);
7177
+ }
7178
+ return {
7179
+ rawSchema,
7180
+ source: `static:${candidate}`,
7181
+ };
7182
+ }
7183
+ return null;
7184
+ }
7185
+
7100
7186
  // getPluginSchemas: 运行时辅助函数。
7101
7187
  async function getPluginSchemas(): Promise<Array<Record<string, unknown>>> {
7102
7188
  // 聚合三个渠道插件 schema,并附带 effective whitelist 供前端渲染表单。
7103
7189
  const whitelist = readEffectiveWhitelist();
7104
7190
  const result: Array<Record<string, unknown>> = [];
7105
- try {
7106
- const dingtalkMod = (await import("ylib-dingtalk-connector")) as Record<
7191
+ for (const descriptor of pluginSchemaDescriptors) {
7192
+ const effectiveWhitelist = (whitelist[descriptor.pluginId] as Record<
7107
7193
  string,
7108
7194
  unknown
7109
- >;
7110
- const dRawSchema = resolveRawSchema(dingtalkMod, "dingtalk-connector");
7111
- result.push({
7112
- pluginId: "dingtalk-connector",
7113
- channel: "dingtalk",
7114
- rawSchema: dRawSchema,
7115
- schemaHash: calcSchemaHash(dRawSchema),
7116
- effectiveWhitelist: (whitelist["dingtalk-connector"] as Record<
7117
- string,
7118
- unknown
7119
- >) || { fields: [] },
7120
- });
7121
- } catch (err) {
7122
- result.push({
7123
- pluginId: "dingtalk-connector",
7124
- channel: "dingtalk",
7125
- rawSchema: {},
7126
- schemaHash: calcSchemaHash({}),
7127
- effectiveWhitelist: (whitelist["dingtalk-connector"] as Record<
7128
- string,
7129
- unknown
7130
- >) || { fields: [] },
7131
- error: (err as Error).message,
7132
- });
7133
- }
7134
- try {
7135
- const larkMod = (await import("ylib-openclaw-lark")) as Record<
7136
- string,
7137
- unknown
7138
- >;
7139
- const lRawSchema = resolveRawSchema(larkMod, "openclaw-lark");
7140
- result.push({
7141
- pluginId: "openclaw-lark",
7142
- channel: "feishu",
7143
- rawSchema: lRawSchema,
7144
- schemaHash: calcSchemaHash(lRawSchema),
7145
- effectiveWhitelist: (whitelist["openclaw-lark"] as Record<
7146
- string,
7147
- unknown
7148
- >) || { fields: [] },
7149
- });
7150
- } catch (err) {
7151
- result.push({
7152
- pluginId: "openclaw-lark",
7153
- channel: "feishu",
7154
- rawSchema: {},
7155
- schemaHash: calcSchemaHash({}),
7156
- effectiveWhitelist: (whitelist["openclaw-lark"] as Record<
7157
- string,
7158
- unknown
7159
- >) || { fields: [] },
7160
- error: (err as Error).message,
7161
- });
7162
- }
7163
- try {
7164
- let weixinMod: Record<string, unknown>;
7195
+ >) || { fields: [] };
7196
+ let staticError: string | null = null;
7197
+ let staticSchema: { rawSchema: Record<string, unknown>; source: string } | null =
7198
+ null;
7165
7199
  try {
7166
- const weixinPkg = "ylib-openclaw-weixin";
7167
- weixinMod = (await import(weixinPkg)) as Record<string, unknown>;
7168
- } catch {
7169
- weixinMod = (await import("../../openclaw-weixin/index.ts")) as Record<
7170
- string,
7171
- unknown
7172
- >;
7200
+ staticSchema = readStaticPluginRawSchema(descriptor);
7201
+ } catch (readErr) {
7202
+ staticError = (readErr as Error).message;
7203
+ }
7204
+ if (staticSchema) {
7205
+ result.push({
7206
+ pluginId: descriptor.pluginId,
7207
+ channel: descriptor.channel,
7208
+ rawSchema: staticSchema.rawSchema,
7209
+ schemaHash: calcSchemaHash(staticSchema.rawSchema),
7210
+ effectiveWhitelist,
7211
+ schemaSource: staticSchema.source,
7212
+ ...(staticError ? { staticError } : {}),
7213
+ });
7214
+ continue;
7215
+ }
7216
+ try {
7217
+ const pluginMod = await descriptor.dynamicLoader();
7218
+ const rawSchema = resolveRawSchema(pluginMod, descriptor.pluginId);
7219
+ result.push({
7220
+ pluginId: descriptor.pluginId,
7221
+ channel: descriptor.channel,
7222
+ rawSchema,
7223
+ schemaHash: calcSchemaHash(rawSchema),
7224
+ effectiveWhitelist,
7225
+ schemaSource: staticError ? "dynamic-fallback" : "dynamic",
7226
+ ...(staticError ? { staticError } : {}),
7227
+ });
7228
+ } catch (dynamicError) {
7229
+ try {
7230
+ const localStatic = readStaticPluginRawSchema(descriptor);
7231
+ if (!localStatic) throw dynamicError;
7232
+ result.push({
7233
+ pluginId: descriptor.pluginId,
7234
+ channel: descriptor.channel,
7235
+ rawSchema: localStatic.rawSchema,
7236
+ schemaHash: calcSchemaHash(localStatic.rawSchema),
7237
+ effectiveWhitelist,
7238
+ schemaSource: `${localStatic.source}:fallback`,
7239
+ error: (dynamicError as Error).message,
7240
+ ...(staticError ? { staticError } : {}),
7241
+ });
7242
+ } catch {
7243
+ result.push({
7244
+ pluginId: descriptor.pluginId,
7245
+ channel: descriptor.channel,
7246
+ rawSchema: {},
7247
+ schemaHash: calcSchemaHash({}),
7248
+ effectiveWhitelist,
7249
+ schemaSource: "error",
7250
+ error: (dynamicError as Error).message,
7251
+ ...(staticError ? { staticError } : {}),
7252
+ });
7253
+ }
7173
7254
  }
7174
- const wRawSchema = resolveRawSchema(weixinMod, "openclaw-weixin");
7175
- result.push({
7176
- pluginId: "openclaw-weixin",
7177
- channel: "weixin",
7178
- rawSchema: wRawSchema,
7179
- schemaHash: calcSchemaHash(wRawSchema),
7180
- effectiveWhitelist: (whitelist["openclaw-weixin"] as Record<
7181
- string,
7182
- unknown
7183
- >) || { fields: [] },
7184
- });
7185
- } catch (err) {
7186
- result.push({
7187
- pluginId: "openclaw-weixin",
7188
- channel: "weixin",
7189
- rawSchema: {},
7190
- schemaHash: calcSchemaHash({}),
7191
- effectiveWhitelist: (whitelist["openclaw-weixin"] as Record<
7192
- string,
7193
- unknown
7194
- >) || { fields: [] },
7195
- error: (err as Error).message,
7196
- });
7197
7255
  }
7198
7256
  return result;
7199
7257
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ylib-syim",
3
- "version": "0.0.29",
3
+ "version": "0.0.31",
4
4
  "description": "多 IM / 多 Agent 的会话路由与上下文管理(支持 /new)",
5
5
  "type": "module",
6
6
  "exports": {
@@ -46,9 +46,9 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@ffmpeg-installer/ffmpeg": "^1.1.0",
49
- "ylib-dingtalk-connector": "0.7.10-beta.16",
50
- "ylib-openclaw-lark": "2026.3.17-beta.21",
51
- "ylib-openclaw-weixin": "2.1.7-beta.9",
49
+ "ylib-dingtalk-connector": "0.7.10-beta.18",
50
+ "ylib-openclaw-lark": "2026.3.17-beta.23",
51
+ "ylib-openclaw-weixin": "2.1.7-beta.11",
52
52
  "axios": "^1.6.0",
53
53
  "dingtalk-stream": "^2.1.4",
54
54
  "fluent-ffmpeg": "^2.1.3",