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.
- package/bridges/main.ts +146 -88
- 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
|
-
|
|
7106
|
-
const
|
|
7191
|
+
for (const descriptor of pluginSchemaDescriptors) {
|
|
7192
|
+
const effectiveWhitelist = (whitelist[descriptor.pluginId] as Record<
|
|
7107
7193
|
string,
|
|
7108
7194
|
unknown
|
|
7109
|
-
|
|
7110
|
-
|
|
7111
|
-
|
|
7112
|
-
|
|
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
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
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.
|
|
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.
|
|
50
|
-
"ylib-openclaw-lark": "2026.3.17-beta.
|
|
51
|
-
"ylib-openclaw-weixin": "2.1.7-beta.
|
|
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",
|