@openclaw/feishu 2026.7.2-beta.3 → 2026.7.2-beta.5
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 +1 -1
- package/dist/{accounts-BDoGHJDk.js → accounts-CKhCa76b.js} +2 -19
- package/dist/api.js +65 -43
- package/dist/{app-registration-BzkyrVZu.js → app-registration-cN1bVV6s.js} +5 -5
- package/dist/{channel-BdnXYU6g.js → channel-CBNICmK9.js} +37 -75
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-CVIzo2dV.js → channel.runtime-CSlJVqy4.js} +7 -7
- package/dist/{client-87BmeMpj.js → client-Dee7cKsS.js} +62 -1
- package/dist/contract-api.js +2 -2
- package/dist/doctor-contract-BiD9tyIv.js +102 -0
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{drive-BHv8WW9i.js → drive-DG6pKTPE.js} +23 -20
- package/dist/{send-DcrXbqqA.js → media-DOwcLJ1j.js} +1050 -1021
- package/dist/{monitor-BVQf7-Bl.js → monitor-DEHJlyWW.js} +6 -5
- package/dist/{monitor.account-Blbf2T6J.js → monitor.account-DEHl8Non.js} +1556 -592
- package/dist/monitor.startup-CSUPT_U1.js +143 -0
- package/dist/{probe-BgboTHIn.js → probe-Za1kgUvx.js} +70 -10
- package/dist/runtime-api.js +1 -2
- package/dist/{security-audit-BIeA3W3Q.js → security-audit-D7WK_BHh.js} +1 -1
- package/dist/{security-audit-shared-BIHeF-S_.js → security-audit-shared-BgpY7AiJ.js} +6 -11
- package/dist/security-contract-api.js +1 -1
- package/dist/{send-result-DfE5Fhz6.js → send-result-Bcofg0Vv.js} +1 -1
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/setup-api.js +1 -1
- package/dist/{subagent-hooks-BKTOxB-T.js → subagent-hooks-DL2SC5zX.js} +1 -1
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{thread-bindings-V0bwk0A1.js → thread-bindings-Dqs_A0du.js} +2 -1
- package/node_modules/@larksuiteoapi/node-sdk/README.md +13 -0
- package/node_modules/@larksuiteoapi/node-sdk/README.zh.md +12 -0
- package/node_modules/@larksuiteoapi/node-sdk/es/index.js +8950 -3084
- package/node_modules/@larksuiteoapi/node-sdk/lib/index.js +8951 -3083
- package/node_modules/@larksuiteoapi/node-sdk/package.json +1 -1
- package/node_modules/@larksuiteoapi/node-sdk/types/index.d.ts +12522 -698
- package/node_modules/@protobufjs/utf8/CHANGELOG.md +8 -0
- package/node_modules/@protobufjs/utf8/index.js +29 -18
- package/node_modules/@protobufjs/utf8/package.json +2 -2
- package/node_modules/@protobufjs/utf8/tests/index.js +5 -0
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/fs/promises.d.ts +16 -6
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/agent-base/README.md +145 -0
- package/node_modules/agent-base/dist/src/index.d.ts +78 -0
- package/node_modules/agent-base/dist/src/index.js +203 -0
- package/node_modules/agent-base/dist/src/index.js.map +1 -0
- package/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
- package/node_modules/agent-base/dist/src/promisify.js +18 -0
- package/node_modules/agent-base/dist/src/promisify.js.map +1 -0
- package/node_modules/agent-base/package.json +64 -0
- package/node_modules/agent-base/src/index.ts +345 -0
- package/node_modules/agent-base/src/promisify.ts +33 -0
- package/node_modules/axios/CHANGELOG.md +197 -1
- package/node_modules/axios/README.md +424 -256
- package/node_modules/axios/dist/axios.js +589 -204
- package/node_modules/axios/dist/axios.min.js +3 -3
- package/node_modules/axios/dist/axios.min.js.map +1 -1
- package/node_modules/axios/dist/browser/axios.cjs +630 -185
- package/node_modules/axios/dist/esm/axios.js +630 -185
- package/node_modules/axios/dist/esm/axios.min.js +2 -2
- package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
- package/node_modules/axios/dist/node/axios.cjs +949 -301
- package/node_modules/axios/index.d.cts +28 -5
- package/node_modules/axios/index.d.ts +24 -3
- package/node_modules/axios/lib/adapters/adapters.js +1 -1
- package/node_modules/axios/lib/adapters/fetch.js +223 -49
- package/node_modules/axios/lib/adapters/http.js +408 -193
- package/node_modules/axios/lib/adapters/xhr.js +3 -1
- package/node_modules/axios/lib/core/Axios.js +4 -2
- package/node_modules/axios/lib/core/AxiosError.js +13 -1
- package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
- package/node_modules/axios/lib/core/buildFullPath.js +29 -1
- package/node_modules/axios/lib/core/mergeConfig.js +35 -0
- package/node_modules/axios/lib/defaults/transitional.js +2 -0
- package/node_modules/axios/lib/env/data.js +1 -1
- package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -3
- package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
- package/node_modules/axios/lib/helpers/buildURL.js +7 -4
- package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
- package/node_modules/axios/lib/helpers/cookies.js +5 -1
- package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
- package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
- package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
- package/node_modules/axios/lib/helpers/fromDataURI.js +20 -5
- package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
- package/node_modules/axios/lib/helpers/resolveConfig.js +26 -13
- package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
- package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
- package/node_modules/axios/lib/helpers/toFormData.js +48 -12
- package/node_modules/axios/lib/helpers/validator.js +1 -1
- package/node_modules/axios/lib/utils.js +105 -19
- package/node_modules/axios/package.json +31 -13
- package/node_modules/https-proxy-agent/README.md +137 -0
- package/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
- package/node_modules/https-proxy-agent/dist/agent.js +177 -0
- package/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
- package/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
- package/node_modules/https-proxy-agent/dist/index.js +14 -0
- package/node_modules/https-proxy-agent/dist/index.js.map +1 -0
- package/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
- package/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
- package/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
- package/node_modules/https-proxy-agent/package.json +56 -0
- package/node_modules/protobufjs/dist/light/protobuf.js +145 -188
- package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.js +33 -76
- package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.js +168 -208
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/index.d.ts +0 -8
- package/node_modules/protobufjs/package.json +2 -3
- package/node_modules/protobufjs/src/parse.js +3 -0
- package/node_modules/protobufjs/src/util/minimal.js +0 -3
- package/node_modules/qs/CHANGELOG.md +11 -0
- package/node_modules/qs/dist/qs.js +17 -17
- package/node_modules/qs/lib/parse.js +19 -8
- package/node_modules/qs/lib/utils.js +47 -8
- package/node_modules/qs/package.json +6 -5
- package/node_modules/qs/test/parse.js +230 -0
- package/node_modules/qs/test/utils.js +194 -0
- package/node_modules/typebox/build/compile/validator.d.mts +1 -4
- package/node_modules/typebox/build/guard/guard.d.mts +1 -1
- package/node_modules/typebox/build/guard/guard.mjs +5 -2
- package/node_modules/typebox/build/guard/string.mjs +16 -4
- package/node_modules/typebox/build/schema/engine/_functions.mjs +34 -15
- package/node_modules/typebox/build/type/action/readonly_object.d.mts +5 -0
- package/node_modules/typebox/build/type/action/readonly_object.mjs +8 -0
- package/node_modules/typebox/build/typebox.d.mts +1 -1
- package/node_modules/typebox/build/typebox.mjs +1 -1
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +29 -32
- package/node_modules/ws/lib/receiver.js +15 -32
- package/node_modules/ws/lib/websocket-server.js +4 -4
- package/node_modules/ws/lib/websocket.js +4 -4
- package/node_modules/ws/package.json +5 -1
- package/openclaw.plugin.json +2 -16
- package/package.json +20 -8
- package/dist/doctor-contract-DXH5hux1.js +0 -97
- package/dist/monitor.startup-Cy8NPGAX.js +0 -43
- package/node_modules/@protobufjs/inquire/CHANGELOG.md +0 -8
- package/node_modules/@protobufjs/inquire/LICENSE +0 -26
- package/node_modules/@protobufjs/inquire/README.md +0 -13
- package/node_modules/@protobufjs/inquire/index.d.ts +0 -10
- package/node_modules/@protobufjs/inquire/index.js +0 -38
- package/node_modules/@protobufjs/inquire/package.json +0 -21
- package/node_modules/@protobufjs/inquire/tests/data/array.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/data/emptyArray.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/data/emptyObject.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/data/object.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/index.js +0 -20
- package/node_modules/axios/dist/axios.js.map +0 -1
- package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
- package/node_modules/axios/dist/esm/axios.js.map +0 -1
- package/node_modules/axios/dist/node/axios.cjs.map +0 -1
- package/npm-shrinkwrap.json +0 -1354
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
|
|
2
|
+
import { r as registerFeishuAiAgent, t as probeFeishu } from "./probe-Za1kgUvx.js";
|
|
3
|
+
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
4
|
+
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
|
+
import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
|
|
6
|
+
//#region extensions/feishu/src/bot-identity-cache.ts
|
|
7
|
+
const FEISHU_BOT_IDENTITY_CACHE_NAMESPACE = "feishu.bot-identity-cache";
|
|
8
|
+
const FEISHU_BOT_IDENTITY_CACHE_MAX_ENTRIES = 128;
|
|
9
|
+
function openFeishuBotIdentityCache() {
|
|
10
|
+
return getFeishuRuntime().state.openKeyedStore({
|
|
11
|
+
namespace: FEISHU_BOT_IDENTITY_CACHE_NAMESPACE,
|
|
12
|
+
maxEntries: FEISHU_BOT_IDENTITY_CACHE_MAX_ENTRIES
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function parseCachedFeishuBotIdentity(value) {
|
|
16
|
+
if (!value || typeof value !== "object") return null;
|
|
17
|
+
const state = value;
|
|
18
|
+
const appId = normalizeOptionalString(state.appId);
|
|
19
|
+
const botOpenId = normalizeOptionalString(state.botOpenId);
|
|
20
|
+
const botName = normalizeOptionalString(state.botName);
|
|
21
|
+
const fetchedAt = normalizeOptionalString(state.fetchedAt);
|
|
22
|
+
if (!appId || !botOpenId || !fetchedAt || Number.isNaN(Date.parse(fetchedAt))) return null;
|
|
23
|
+
return {
|
|
24
|
+
appId,
|
|
25
|
+
botOpenId,
|
|
26
|
+
botName,
|
|
27
|
+
fetchedAt
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async function readCachedFeishuBotIdentity(params) {
|
|
31
|
+
const appId = normalizeOptionalString(params.appId);
|
|
32
|
+
if (!appId) return null;
|
|
33
|
+
const cached = parseCachedFeishuBotIdentity(await openFeishuBotIdentityCache().lookup(normalizeAccountId(params.accountId)));
|
|
34
|
+
if (!cached || cached.appId !== appId) return null;
|
|
35
|
+
return {
|
|
36
|
+
botOpenId: cached.botOpenId,
|
|
37
|
+
botName: cached.botName,
|
|
38
|
+
fetchedAt: cached.fetchedAt
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async function writeCachedFeishuBotIdentity(params) {
|
|
42
|
+
const appId = normalizeOptionalString(params.appId);
|
|
43
|
+
const botOpenId = normalizeOptionalString(params.botOpenId);
|
|
44
|
+
if (!appId || !botOpenId) return;
|
|
45
|
+
const botName = normalizeOptionalString(params.botName);
|
|
46
|
+
await openFeishuBotIdentityCache().register(normalizeAccountId(params.accountId), {
|
|
47
|
+
appId,
|
|
48
|
+
botOpenId,
|
|
49
|
+
botName,
|
|
50
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region extensions/feishu/src/monitor-startup-timeout.ts
|
|
55
|
+
const FEISHU_STARTUP_BOT_INFO_TIMEOUT_DEFAULT_MS = 3e4;
|
|
56
|
+
const FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV = "OPENCLAW_FEISHU_STARTUP_PROBE_TIMEOUT_MS";
|
|
57
|
+
function resolveStartupProbeTimeoutMs(env = process.env) {
|
|
58
|
+
const raw = env[FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV];
|
|
59
|
+
if (raw) {
|
|
60
|
+
const parsed = parseStrictPositiveInteger(raw);
|
|
61
|
+
if (parsed !== void 0) return parsed;
|
|
62
|
+
console.warn(`[feishu] ${FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV}="${raw}" is invalid; using default ${FEISHU_STARTUP_BOT_INFO_TIMEOUT_DEFAULT_MS}ms`);
|
|
63
|
+
}
|
|
64
|
+
return FEISHU_STARTUP_BOT_INFO_TIMEOUT_DEFAULT_MS;
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region extensions/feishu/src/monitor.startup.ts
|
|
68
|
+
const FEISHU_STARTUP_BOT_INFO_TIMEOUT_MS = resolveStartupProbeTimeoutMs();
|
|
69
|
+
function isTimeoutErrorMessage(message) {
|
|
70
|
+
const lower = normalizeLowercaseStringOrEmpty(message);
|
|
71
|
+
return lower.includes("timeout") || lower.includes("timed out");
|
|
72
|
+
}
|
|
73
|
+
function isAbortErrorMessage(message) {
|
|
74
|
+
return normalizeLowercaseStringOrEmpty(message).includes("aborted");
|
|
75
|
+
}
|
|
76
|
+
async function writeProviderBotIdentityCache(params) {
|
|
77
|
+
try {
|
|
78
|
+
await writeCachedFeishuBotIdentity({
|
|
79
|
+
accountId: params.account.accountId,
|
|
80
|
+
appId: params.account.appId,
|
|
81
|
+
botOpenId: params.botOpenId,
|
|
82
|
+
botName: params.botName
|
|
83
|
+
});
|
|
84
|
+
} catch {
|
|
85
|
+
params.runtime?.log?.(`feishu[${params.account.accountId}]: bot identity cache write failed; continuing startup`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async function readProviderBotIdentityCache(params) {
|
|
89
|
+
try {
|
|
90
|
+
const cached = await readCachedFeishuBotIdentity({
|
|
91
|
+
accountId: params.account.accountId,
|
|
92
|
+
appId: params.account.appId
|
|
93
|
+
});
|
|
94
|
+
if (!cached) return {};
|
|
95
|
+
params.runtime?.log?.(`feishu[${params.account.accountId}]: using cached provider-verified bot identity while the fresh probe is unavailable`);
|
|
96
|
+
return {
|
|
97
|
+
botOpenId: cached.botOpenId,
|
|
98
|
+
botName: cached.botName,
|
|
99
|
+
source: "cache"
|
|
100
|
+
};
|
|
101
|
+
} catch {
|
|
102
|
+
params.runtime?.log?.(`feishu[${params.account.accountId}]: bot identity cache read failed; continuing without cached identity`);
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function fetchBotIdentityForMonitor(account, options = {}) {
|
|
107
|
+
if (options.abortSignal?.aborted) return {};
|
|
108
|
+
const timeoutMs = options.timeoutMs ?? FEISHU_STARTUP_BOT_INFO_TIMEOUT_MS;
|
|
109
|
+
const result = await probeFeishu(account, {
|
|
110
|
+
timeoutMs,
|
|
111
|
+
abortSignal: options.abortSignal
|
|
112
|
+
});
|
|
113
|
+
const resultAppId = normalizeOptionalString(result.appId);
|
|
114
|
+
if (result.ok && resultAppId === account.appId) {
|
|
115
|
+
registerFeishuAiAgent(account, { abortSignal: options.abortSignal }).then((registration) => {
|
|
116
|
+
if (!registration.ok && registration.reason !== "aborted") (options.runtime?.log ?? console.log)(`feishu[${account.accountId}]: AI-agent registration unavailable (${registration.reason}); continuing with standard bot identity`);
|
|
117
|
+
}).catch(() => {
|
|
118
|
+
(options.runtime?.log ?? console.log)(`feishu[${account.accountId}]: AI-agent registration failed unexpectedly; continuing with standard bot identity`);
|
|
119
|
+
});
|
|
120
|
+
await writeProviderBotIdentityCache({
|
|
121
|
+
account,
|
|
122
|
+
botOpenId: result.botOpenId,
|
|
123
|
+
botName: result.botName,
|
|
124
|
+
runtime: options.runtime
|
|
125
|
+
});
|
|
126
|
+
return {
|
|
127
|
+
botOpenId: normalizeOptionalString(result.botOpenId),
|
|
128
|
+
botName: normalizeOptionalString(result.botName),
|
|
129
|
+
source: "provider"
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
if (result.ok) (options.runtime?.log ?? console.log)(`feishu[${account.accountId}]: bot info probe returned identity for a different app; ignoring stale result`);
|
|
133
|
+
const probeError = result.error ?? void 0;
|
|
134
|
+
if (options.abortSignal?.aborted || isAbortErrorMessage(probeError)) return {};
|
|
135
|
+
if (isTimeoutErrorMessage(probeError)) (options.runtime?.error ?? console.error)(`feishu[${account.accountId}]: bot info probe timed out after ${timeoutMs}ms; continuing startup`);
|
|
136
|
+
if (options.allowCachedFallback === false) return {};
|
|
137
|
+
return readProviderBotIdentityCache({
|
|
138
|
+
account,
|
|
139
|
+
runtime: options.runtime
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
export { fetchBotIdentityForMonitor as t };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { r as createFeishuClient } from "./client-
|
|
2
|
+
import { r as createFeishuClient } from "./client-Dee7cKsS.js";
|
|
3
3
|
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
4
4
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
5
6
|
//#region extensions/feishu/src/async.ts
|
|
6
7
|
const RACE_TIMEOUT = Symbol("race-timeout");
|
|
7
8
|
const RACE_ABORT = Symbol("race-abort");
|
|
@@ -63,7 +64,10 @@ function waitForAbortableDelay(delayMs, abortSignal) {
|
|
|
63
64
|
}
|
|
64
65
|
//#endregion
|
|
65
66
|
//#region extensions/feishu/src/probe.ts
|
|
66
|
-
var probe_exports = /* @__PURE__ */ __exportAll({
|
|
67
|
+
var probe_exports = /* @__PURE__ */ __exportAll({
|
|
68
|
+
probeFeishu: () => probeFeishu,
|
|
69
|
+
registerFeishuAiAgent: () => registerFeishuAiAgent
|
|
70
|
+
});
|
|
67
71
|
/** Cache probe results to reduce repeated health-check calls.
|
|
68
72
|
* Gateway health checks call probeFeishu() every minute; without caching this
|
|
69
73
|
* burns ~43,200 calls/month, easily exceeding Feishu's free-tier quota.
|
|
@@ -74,6 +78,15 @@ const PROBE_SUCCESS_TTL_MS = 600 * 1e3;
|
|
|
74
78
|
const PROBE_ERROR_TTL_MS = 60 * 1e3;
|
|
75
79
|
const MAX_PROBE_CACHE_SIZE = 64;
|
|
76
80
|
const FEISHU_PROBE_REQUEST_TIMEOUT_MS = 1e4;
|
|
81
|
+
function buildProbeCacheKey(creds) {
|
|
82
|
+
const identity = [
|
|
83
|
+
creds.accountId ?? null,
|
|
84
|
+
creds.appId,
|
|
85
|
+
creds.appSecret,
|
|
86
|
+
creds.domain ?? null
|
|
87
|
+
];
|
|
88
|
+
return createHash("sha256").update(JSON.stringify(identity)).digest("hex");
|
|
89
|
+
}
|
|
77
90
|
function setCachedProbeResult(cacheKey, result, ttlMs) {
|
|
78
91
|
const expiresAt = resolveExpiresAtMsFromDurationMs(ttlMs);
|
|
79
92
|
if (expiresAt === void 0) {
|
|
@@ -101,7 +114,7 @@ async function probeFeishu(creds, options = {}) {
|
|
|
101
114
|
error: "probe aborted"
|
|
102
115
|
};
|
|
103
116
|
const timeoutMs = options.timeoutMs ?? FEISHU_PROBE_REQUEST_TIMEOUT_MS;
|
|
104
|
-
const cacheKey = creds
|
|
117
|
+
const cacheKey = buildProbeCacheKey(creds);
|
|
105
118
|
const cached = probeCache.get(cacheKey);
|
|
106
119
|
if (cached) {
|
|
107
120
|
const now = asDateTimestampMs(Date.now());
|
|
@@ -111,9 +124,8 @@ async function probeFeishu(creds, options = {}) {
|
|
|
111
124
|
}
|
|
112
125
|
try {
|
|
113
126
|
const responseResult = await raceWithTimeoutAndAbort(createFeishuClient(creds).request({
|
|
114
|
-
method: "
|
|
115
|
-
url: "/open-apis/bot/
|
|
116
|
-
data: { needBotInfo: true },
|
|
127
|
+
method: "GET",
|
|
128
|
+
url: "/open-apis/bot/v3/info",
|
|
117
129
|
timeout: timeoutMs
|
|
118
130
|
}), {
|
|
119
131
|
timeoutMs,
|
|
@@ -140,12 +152,17 @@ async function probeFeishu(creds, options = {}) {
|
|
|
140
152
|
appId: creds.appId,
|
|
141
153
|
error: `API error: ${response.msg || `code ${response.code}`}`
|
|
142
154
|
}, PROBE_ERROR_TTL_MS);
|
|
143
|
-
const botInfo = response.data?.
|
|
155
|
+
const botInfo = response.bot ?? response.data?.bot;
|
|
156
|
+
if (!botInfo?.open_id) return setCachedProbeResult(cacheKey, {
|
|
157
|
+
ok: false,
|
|
158
|
+
appId: creds.appId,
|
|
159
|
+
error: "API response missing bot open_id"
|
|
160
|
+
}, PROBE_ERROR_TTL_MS);
|
|
144
161
|
return setCachedProbeResult(cacheKey, {
|
|
145
162
|
ok: true,
|
|
146
163
|
appId: creds.appId,
|
|
147
|
-
botName: botInfo
|
|
148
|
-
botOpenId: botInfo
|
|
164
|
+
botName: botInfo.app_name,
|
|
165
|
+
botOpenId: botInfo.open_id
|
|
149
166
|
}, PROBE_SUCCESS_TTL_MS);
|
|
150
167
|
} catch (err) {
|
|
151
168
|
return setCachedProbeResult(cacheKey, {
|
|
@@ -155,5 +172,48 @@ async function probeFeishu(creds, options = {}) {
|
|
|
155
172
|
}, PROBE_ERROR_TTL_MS);
|
|
156
173
|
}
|
|
157
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Preserve Feishu's optional AI-agent registration without coupling it to health or
|
|
177
|
+
* identity. Monitor startup calls this once per account and never awaits it.
|
|
178
|
+
*/
|
|
179
|
+
async function registerFeishuAiAgent(creds, options = {}) {
|
|
180
|
+
if (!creds?.appId || !creds?.appSecret) return {
|
|
181
|
+
ok: false,
|
|
182
|
+
reason: "missing-credentials"
|
|
183
|
+
};
|
|
184
|
+
if (options.abortSignal?.aborted) return {
|
|
185
|
+
ok: false,
|
|
186
|
+
reason: "aborted"
|
|
187
|
+
};
|
|
188
|
+
const timeoutMs = options.timeoutMs ?? FEISHU_PROBE_REQUEST_TIMEOUT_MS;
|
|
189
|
+
try {
|
|
190
|
+
const responseResult = await raceWithTimeoutAndAbort(createFeishuClient(creds).request({
|
|
191
|
+
method: "POST",
|
|
192
|
+
url: "/open-apis/bot/v1/openclaw_bot/ping",
|
|
193
|
+
data: { needBotInfo: true },
|
|
194
|
+
timeout: timeoutMs
|
|
195
|
+
}), {
|
|
196
|
+
timeoutMs,
|
|
197
|
+
abortSignal: options.abortSignal
|
|
198
|
+
});
|
|
199
|
+
if (responseResult.status === "aborted" || options.abortSignal?.aborted) return {
|
|
200
|
+
ok: false,
|
|
201
|
+
reason: "aborted"
|
|
202
|
+
};
|
|
203
|
+
if (responseResult.status === "timeout") return {
|
|
204
|
+
ok: false,
|
|
205
|
+
reason: "timeout"
|
|
206
|
+
};
|
|
207
|
+
return responseResult.value.code === 0 ? { ok: true } : {
|
|
208
|
+
ok: false,
|
|
209
|
+
reason: "api-error"
|
|
210
|
+
};
|
|
211
|
+
} catch {
|
|
212
|
+
return {
|
|
213
|
+
ok: false,
|
|
214
|
+
reason: "request-error"
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
158
218
|
//#endregion
|
|
159
|
-
export { waitForAbortableDelay as i, probe_exports as n,
|
|
219
|
+
export { waitForAbortableDelay as a, raceWithTimeoutAndAbort as i, probe_exports as n, registerFeishuAiAgent as r, probeFeishu as t };
|
package/dist/runtime-api.js
CHANGED
|
@@ -6,8 +6,7 @@ import { PAIRING_APPROVED_MESSAGE, buildProbeChannelStatusSummary, createDefault
|
|
|
6
6
|
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
|
|
7
7
|
import { getSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
|
8
8
|
import { DEFAULT_ACCOUNT_ID, buildChannelConfigSchema, createActionGate, createDedupeCache } from "openclaw/plugin-sdk/core";
|
|
9
|
-
import { buildAgentMediaPayload } from "openclaw/plugin-sdk/agent-media-payload";
|
|
10
9
|
import { evaluateSupplementalContextVisibility, filterSupplementalContextItems, resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
|
|
11
10
|
import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
|
|
12
11
|
import { isRequestBodyLimitError, readRequestBodyWithLimit, requestBodyErrorToText } from "openclaw/plugin-sdk/webhook-ingress";
|
|
13
|
-
export { DEFAULT_ACCOUNT_ID, PAIRING_APPROVED_MESSAGE,
|
|
12
|
+
export { DEFAULT_ACCOUNT_ID, PAIRING_APPROVED_MESSAGE, buildChannelConfigSchema, buildProbeChannelStatusSummary, chunkTextForOutbound, createActionGate, createChannelPairingController, createDedupeCache, createDefaultChannelRuntimeState, createReplyPrefixContext, evaluateSupplementalContextVisibility, filterSupplementalContextItems, getSessionEntry, isRequestBodyLimitError, normalizeAgentId, readJsonFileWithFallback, readRequestBodyWithLimit, requestBodyErrorToText, resolveChannelContextVisibilityMode, setFeishuRuntime };
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
+
import { asOptionalRecord, hasNonEmptyString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
1
2
|
import { hasConfiguredSecretInput } from "openclaw/plugin-sdk/secret-input";
|
|
2
3
|
//#region extensions/feishu/src/security-audit-shared.ts
|
|
3
|
-
function asRecord(value) {
|
|
4
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
5
|
-
}
|
|
6
|
-
function hasNonEmptyString(value) {
|
|
7
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
8
|
-
}
|
|
9
4
|
function isFeishuDocToolEnabled(cfg) {
|
|
10
|
-
const feishu =
|
|
5
|
+
const feishu = asOptionalRecord(asOptionalRecord(cfg.channels)?.feishu);
|
|
11
6
|
if (!feishu || feishu.enabled === false) return false;
|
|
12
|
-
const baseTools =
|
|
7
|
+
const baseTools = asOptionalRecord(feishu.tools);
|
|
13
8
|
const baseDocEnabled = baseTools?.doc !== false;
|
|
14
9
|
const baseAppId = hasNonEmptyString(feishu.appId);
|
|
15
10
|
const baseAppSecret = hasConfiguredSecretInput(feishu.appSecret, cfg.secrets?.defaults);
|
|
16
11
|
const baseConfigured = baseAppId && baseAppSecret;
|
|
17
|
-
const accounts =
|
|
12
|
+
const accounts = asOptionalRecord(feishu.accounts);
|
|
18
13
|
if (!accounts || Object.keys(accounts).length === 0) return baseDocEnabled && baseConfigured;
|
|
19
14
|
for (const accountValue of Object.values(accounts)) {
|
|
20
|
-
const account =
|
|
15
|
+
const account = asOptionalRecord(accountValue) ?? {};
|
|
21
16
|
if (account.enabled === false) continue;
|
|
22
|
-
if (!((
|
|
17
|
+
if (!((asOptionalRecord(account.tools) ?? baseTools)?.doc !== false)) continue;
|
|
23
18
|
if ((hasNonEmptyString(account.appId) || baseAppId) && (hasConfiguredSecretInput(account.appSecret, cfg.secrets?.defaults) || baseAppSecret)) return true;
|
|
24
19
|
}
|
|
25
20
|
return false;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-
|
|
1
|
+
import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BgpY7AiJ.js";
|
|
2
2
|
export { collectFeishuSecurityAuditFindings };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as isRecord$1 } from "./accounts-
|
|
1
|
+
import { d as isRecord$1 } from "./accounts-CKhCa76b.js";
|
|
2
2
|
import { r as normalizeFeishuTarget, t as detectIdType } from "./targets-BUjQ1TcA.js";
|
|
3
3
|
import { compileAllowlist, resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
|
|
4
4
|
import { ToolAuthorizationError } from "openclaw/plugin-sdk/channel-actions";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-
|
|
1
|
+
import { r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-Dqs_A0du.js";
|
|
2
2
|
export { createFeishuThreadBindingManager, testing as feishuThreadBindingTesting };
|
package/dist/setup-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-
|
|
1
|
+
import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-CBNICmK9.js";
|
|
2
2
|
export { feishuPlugin, feishuSetupAdapter, feishuSetupWizard };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
2
|
import { r as normalizeFeishuTarget } from "./targets-BUjQ1TcA.js";
|
|
3
3
|
import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-BeJL-wq7.js";
|
|
4
|
-
import { n as getFeishuThreadBindingManager } from "./thread-bindings-
|
|
4
|
+
import { n as getFeishuThreadBindingManager } from "./thread-bindings-Dqs_A0du.js";
|
|
5
5
|
import { normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
//#region extensions/feishu/src/subagent-hooks.ts
|
|
7
7
|
var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
2
2
|
//#region extensions/feishu/subagent-hooks-api.ts
|
|
3
|
-
const loadFeishuSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-
|
|
3
|
+
const loadFeishuSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-DL2SC5zX.js").then((n) => n.i));
|
|
4
4
|
function registerFeishuSubagentHooks(api) {
|
|
5
5
|
api.on("subagent_delivery_target", async (event) => {
|
|
6
6
|
const { handleFeishuSubagentDeliveryTarget } = await loadFeishuSubagentHooksModule();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { registerSessionBindingAdapter, resolveThreadBindingConversationIdFromBindingId, resolveThreadBindingIdleTimeoutMsForChannel, resolveThreadBindingMaxAgeMsForChannel, unregisterSessionBindingAdapter } from "openclaw/plugin-sdk/conversation-runtime";
|
|
2
2
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
3
|
import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
|
|
4
|
+
import { resolveDefaultAgentId } from "openclaw/plugin-sdk/agent-runtime";
|
|
4
5
|
//#region extensions/feishu/src/thread-bindings.ts
|
|
5
6
|
const FEISHU_THREAD_BINDINGS_STATE_KEY = Symbol.for("openclaw.feishuThreadBindingsState");
|
|
6
7
|
let state;
|
|
@@ -94,7 +95,7 @@ function createFeishuThreadBindingManager(params) {
|
|
|
94
95
|
deliveryThreadId: typeof metadata?.deliveryThreadId === "string" && metadata.deliveryThreadId.trim() ? metadata.deliveryThreadId.trim() : existingLocal?.deliveryThreadId,
|
|
95
96
|
targetKind: toFeishuTargetKind(targetKind),
|
|
96
97
|
targetSessionKey: normalizedTargetSessionKey,
|
|
97
|
-
agentId: typeof metadata?.agentId === "string" && metadata.agentId.trim() ? metadata.agentId.trim() : existingLocal?.agentId ?? resolveAgentIdFromSessionKey(normalizedTargetSessionKey),
|
|
98
|
+
agentId: typeof metadata?.agentId === "string" && metadata.agentId.trim() ? metadata.agentId.trim() : existingLocal?.agentId ?? resolveAgentIdFromSessionKey(normalizedTargetSessionKey, resolveDefaultAgentId(params.cfg)),
|
|
98
99
|
label: typeof metadata?.label === "string" && metadata.label.trim() ? metadata.label.trim() : existingLocal?.label,
|
|
99
100
|
boundBy: typeof metadata?.boundBy === "string" && metadata.boundBy.trim() ? metadata.boundBy.trim() : existingLocal?.boundBy,
|
|
100
101
|
boundAt: now,
|
|
@@ -705,10 +705,22 @@ await lark.registerApp({
|
|
|
705
705
|
addons: { scopes: { tenant: ['drive:drive.metadata:readonly'] } },
|
|
706
706
|
onQRCodeReady(info) { /* ... */ },
|
|
707
707
|
});
|
|
708
|
+
|
|
709
|
+
// Minimal base: drop the default template (bot capability only, no business
|
|
710
|
+
// scopes) and show only the explicitly declared items. With `preset: false`
|
|
711
|
+
// an otherwise-empty addons is valid.
|
|
712
|
+
await lark.registerApp({
|
|
713
|
+
addons: {
|
|
714
|
+
preset: false,
|
|
715
|
+
scopes: { tenant: ['im:message:send_as_bot'] },
|
|
716
|
+
},
|
|
717
|
+
onQRCodeReady(info) { /* ... */ },
|
|
718
|
+
});
|
|
708
719
|
```
|
|
709
720
|
|
|
710
721
|
Notes:
|
|
711
722
|
|
|
723
|
+
- `addons.preset` selects the template base: `true` / omitted keeps the platform default template and layers the declared items on top (additive — the default behavior); `false` drops the default template and starts from the minimal base (bot capability only, no business scopes), showing only the explicitly declared items. Only with `preset: false` may `addons` be otherwise empty (minimal base, zero increments); otherwise at least one scope, event or callback is required.
|
|
712
724
|
- `addons` is **additive only**: items are merged on top of the base template; base permissions can never be removed.
|
|
713
725
|
- Only the 5 public config types (tenant/user scopes, tenant/user events, callbacks) are supported. Sensitive config (event subscription type and request URLs, `security.*`, encrypt keys, etc.) cannot travel via `addons` — use the [update application config OpenAPI](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v7/application-v7/application-config/patch) instead.
|
|
714
726
|
- The SDK only validates the shape, not the item names; names unknown to the platform catalog are silently ignored by the confirm page.
|
|
@@ -728,6 +740,7 @@ Notes:
|
|
|
728
740
|
| appPreset.name | App name. Supports the `{user}` placeholder (replaced with the scanning user's name) | string | No | - |
|
|
729
741
|
| appPreset.desc | App description. Supports the `{user}` placeholder | string | No | - |
|
|
730
742
|
| addons | Incremental scopes/events/callbacks pre-filled into the confirm page, effective after user confirmation. See "Custom scopes/events/callbacks" above | AppAddons | No | - |
|
|
743
|
+
| addons.preset | Template base selector. `true`/omitted: keep the platform default template and layer the declared items on top; `false`: drop the default template and use the minimal base (bot capability only, no business scopes). With `false`, an otherwise-empty `addons` is valid | boolean | No | `true` |
|
|
731
744
|
| addons.scopes.tenant | App-identity (tenant) scopes, e.g. `im:message:send_as_bot` | string[] | No | - |
|
|
732
745
|
| addons.scopes.user | User-identity scopes, e.g. `calendar:calendar:read` | string[] | No | - |
|
|
733
746
|
| addons.events.items.tenant | App-identity events, e.g. `im.message.receive_v1` | string[] | No | - |
|
|
@@ -765,10 +765,21 @@ await lark.registerApp({
|
|
|
765
765
|
addons: { scopes: { tenant: ['drive:drive.metadata:readonly'] } },
|
|
766
766
|
onQRCodeReady(info) { /* ... */ },
|
|
767
767
|
});
|
|
768
|
+
|
|
769
|
+
// 最小基座:丢弃默认模板(仅保留机器人能力,无业务权限),仅展示显式声明的配置项。
|
|
770
|
+
// 传入 `preset: false` 时,即使 addons 没有其他配置项也是合法的。
|
|
771
|
+
await lark.registerApp({
|
|
772
|
+
addons: {
|
|
773
|
+
preset: false,
|
|
774
|
+
scopes: { tenant: ['im:message:send_as_bot'] },
|
|
775
|
+
},
|
|
776
|
+
onQRCodeReady(info) { /* ... */ },
|
|
777
|
+
});
|
|
768
778
|
```
|
|
769
779
|
|
|
770
780
|
注意:
|
|
771
781
|
|
|
782
|
+
- `addons.preset` 用于选择模板基座:`true` / 不传表示保留平台默认模板,并在其上叠加声明的配置项(增量,默认行为);`false` 表示丢弃默认模板,从最小基座(仅机器人能力,无业务权限)开始,仅展示显式声明的配置项。仅当 `preset: false` 时 `addons` 可以不含其他配置项(最小基座、零增量),否则至少需包含一个权限、事件或回调。
|
|
772
783
|
- `addons` 仅支持在基础模板上**增量叠加**,不支持删减基础权限。
|
|
773
784
|
- 仅支持 5 类公开配置(应用/用户身份权限、应用/用户身份事件、回调)。敏感配置(事件订阅方式与回调地址、`security.*`、加密 key 等)不能通过 `addons` 传入,需调用[更新应用开发配置 OpenAPI](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v7/application-v7/application-config/patch)。
|
|
774
785
|
- SDK 只校验数据形状,不校验权限点/事件/回调名称是否存在;平台目录中不存在的名称会被确认页忽略。
|
|
@@ -788,6 +799,7 @@ await lark.registerApp({
|
|
|
788
799
|
| appPreset.name | 应用名称,支持 `{user}` 占位符(替换为扫码用户名称) | string | 否 | - |
|
|
789
800
|
| appPreset.desc | 应用描述,支持 `{user}` 占位符 | string | 否 | - |
|
|
790
801
|
| addons | 增量权限/事件/回调配置,预填到扫码后的确认页,用户确认后生效。详见上方「自定义权限/事件/回调」 | AppAddons | 否 | - |
|
|
802
|
+
| addons.preset | 模板基座选择。`true`/不传:保留平台默认模板,在其上叠加声明的配置项;`false`:丢弃默认模板,使用最小基座(仅机器人能力,无业务权限)。传 `false` 时 `addons` 可不含其他配置项 | boolean | 否 | `true` |
|
|
791
803
|
| addons.scopes.tenant | 应用身份权限列表,如 `im:message:send_as_bot` | string[] | 否 | - |
|
|
792
804
|
| addons.scopes.user | 用户身份权限列表,如 `calendar:calendar:read` | string[] | 否 | - |
|
|
793
805
|
| addons.events.items.tenant | 应用身份事件列表,如 `im.message.receive_v1` | string[] | 否 | - |
|