@openclaw/feishu 2026.7.2-beta.7 → 2026.8.1-beta.3

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 (35) hide show
  1. package/dist/accounts-CCCdMen2.js +203 -0
  2. package/dist/api.js +61 -60
  3. package/dist/{channel-CScE82zY.js → channel-Ceq80_zP.js} +71 -42
  4. package/dist/channel-plugin-api.js +1 -1
  5. package/dist/{channel.runtime-B21e1E0r.js → channel.runtime-DnRyzGoU.js} +201 -152
  6. package/dist/{client-Dcbs6vml.js → client-Hp7uo_cl.js} +27 -16
  7. package/dist/contract-api.js +2 -2
  8. package/dist/{conversation-id-BeJL-wq7.js → conversation-id-VYgGQ-GX.js} +11 -15
  9. package/dist/doctor-contract-api.js +1 -1
  10. package/dist/doctor-contract-bEQXIXyP.js +158 -0
  11. package/dist/{drive-hSi_Utp0.js → drive-BVYM_Y4k.js} +325 -44
  12. package/dist/{media-CEUraFOR.js → media-BDouVaaM.js} +298 -182
  13. package/dist/{monitor-DngbaA6a.js → monitor-CZ8cDXrq.js} +3 -3
  14. package/dist/{monitor.account-BnTWCw55.js → monitor.account-Dq_voVMB.js} +263 -179
  15. package/dist/{monitor.startup-CqH2tiJq.js → monitor.startup-BGErejNH.js} +1 -1
  16. package/dist/{probe-p3POS2RN.js → probe-DVpy58s0.js} +2 -2
  17. package/dist/security-audit-D6Fz2h6p.js +23 -0
  18. package/dist/{send-result-B9_BpUPx.js → send-result-DEAycmOk.js} +18 -9
  19. package/dist/session-binding-contract-api.js +2 -2
  20. package/dist/{session-conversation-BksWrfzm.js → session-conversation-DFCIvQK-.js} +1 -1
  21. package/dist/session-key-api.js +1 -1
  22. package/dist/setup-api.js +1 -1
  23. package/dist/{subagent-hooks-Cx1cX7rW.js → subagent-hooks-KUi-7vUy.js} +4 -64
  24. package/dist/subagent-hooks-api.js +1 -1
  25. package/dist/{thread-bindings-N3wkgkIN.js → thread-bindings-CptM_YU6.js} +7 -9
  26. package/openclaw.plugin.json +143 -1
  27. package/package.json +4 -4
  28. package/skills/feishu-doc/SKILL.md +20 -195
  29. package/skills/feishu-doc/references/block-types.md +9 -14
  30. package/skills/feishu-drive/SKILL.md +16 -102
  31. package/skills/feishu-perm/SKILL.md +10 -110
  32. package/skills/feishu-wiki/SKILL.md +13 -109
  33. package/dist/accounts-u9X5Wsan.js +0 -469
  34. package/dist/doctor-contract-BiD9tyIv.js +0 -102
  35. package/dist/security-audit-D7WK_BHh.js +0 -11
@@ -1,13 +1,15 @@
1
- import { a as resolveDefaultFeishuAccountId, c as encodeQuery, d as isRecord$1, i as listFeishuAccountIds, l as extractReplyText, m as readString, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount, u as formatFeishuApiError, v as parseFeishuCommentTarget } from "./accounts-u9X5Wsan.js";
2
- import { A as resolveFeishuChatType, b as resolveFeishuChatReadPreliminaryAuthorization, h as authorizeFeishuChatMemberRead, m as assertFeishuChatReadAllowed } from "./send-result-B9_BpUPx.js";
3
- import { r as createFeishuClient } from "./client-Dcbs6vml.js";
1
+ import { a as resolveDefaultFeishuAccountId, i as listFeishuAccountIds, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-CCCdMen2.js";
2
+ import { A as resolveFeishuChatType, b as resolveFeishuChatReadPreliminaryAuthorization, h as authorizeFeishuChatMemberRead, m as assertFeishuChatReadAllowed } from "./send-result-DEAycmOk.js";
3
+ import { r as createFeishuClient } from "./client-Hp7uo_cl.js";
4
4
  import { optionalPositiveIntegerSchema } from "openclaw/plugin-sdk/channel-actions";
5
- import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
- import { normalizeOptionalAccountId } from "openclaw/plugin-sdk/account-resolution";
7
5
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
8
- import { jsonResult } from "openclaw/plugin-sdk/tool-results";
6
+ import { isRecord, normalizeOptionalString, normalizeStringEntries, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
7
+ import { normalizeOptionalAccountId } from "openclaw/plugin-sdk/account-resolution";
9
8
  import { Type } from "typebox";
9
+ import { wrapExternalContent } from "openclaw/plugin-sdk/security-runtime";
10
+ import { jsonResult } from "openclaw/plugin-sdk/tool-results";
10
11
  import { readPositiveIntegerParam } from "openclaw/plugin-sdk/param-readers";
12
+ import { retryAsync } from "openclaw/plugin-sdk/retry-runtime";
11
13
  //#region extensions/feishu/src/tools-config.ts
12
14
  /**
13
15
  * Default tool configuration.
@@ -56,14 +58,18 @@ function resolveImplicitToolAccountId(params) {
56
58
  }).enabled) return contextualAccountId;
57
59
  }
58
60
  const configuredDefaultAccountId = normalizeOptionalString((params.api.config?.channels?.feishu)?.defaultAccount);
59
- if (configuredDefaultAccountId) return configuredDefaultAccountId;
60
- if (params.requiredTool && params.api.config) for (const accountId of listFeishuAccountIds(params.api.config)) {
61
+ if (configuredDefaultAccountId && resolveFeishuAccount({
62
+ cfg: params.api.config,
63
+ accountId: configuredDefaultAccountId
64
+ }).enabled) return configuredDefaultAccountId;
65
+ if (params.api.config) for (const accountId of listFeishuAccountIds(params.api.config)) {
61
66
  const account = resolveFeishuAccount({
62
67
  cfg: params.api.config,
63
68
  accountId
64
69
  });
65
70
  if (account.enabled && account.configured && resolveToolsConfig(account.config.tools)[params.requiredTool.family]) return accountId;
66
71
  }
72
+ throw new Error(`No usable Feishu account has ${params.requiredTool.label} tools enabled`);
67
73
  }
68
74
  function resolveFeishuToolAccount(params) {
69
75
  if (!params.api.config) throw new Error("Feishu config unavailable");
@@ -71,7 +77,7 @@ function resolveFeishuToolAccount(params) {
71
77
  cfg: params.api.config,
72
78
  accountId: resolveImplicitToolAccountId(params)
73
79
  });
74
- if (params.requiredTool && !resolveToolsConfig(account.config.tools)[params.requiredTool.family]) throw new Error(`Feishu ${params.requiredTool.label} tools are disabled for account "${account.accountId}"`);
80
+ if (!resolveToolsConfig(account.config.tools)[params.requiredTool.family]) throw new Error(`Feishu ${params.requiredTool.label} tools are disabled for account "${account.accountId}"`);
75
81
  return account;
76
82
  }
77
83
  function createFeishuToolClient(params) {
@@ -99,6 +105,26 @@ function resolveAnyEnabledFeishuToolsConfig(accounts) {
99
105
  }
100
106
  return merged;
101
107
  }
108
+ //#endregion
109
+ //#region extensions/feishu/src/tool-result.ts
110
+ function feishuExternalToolResult(details) {
111
+ return {
112
+ content: [{
113
+ type: "text",
114
+ text: wrapExternalContent(JSON.stringify(details, null, 2), {
115
+ source: "api",
116
+ includeWarning: false
117
+ })
118
+ }],
119
+ details
120
+ };
121
+ }
122
+ function unknownToolActionResult(action) {
123
+ return jsonResult({ error: `Unknown action: ${String(action)}` });
124
+ }
125
+ function toolExecutionErrorResult(error) {
126
+ return feishuExternalToolResult({ error: formatErrorMessage(error) });
127
+ }
102
128
  const FeishuChatSchema = Type.Object({
103
129
  action: Type.Enum([
104
130
  "members",
@@ -125,6 +151,267 @@ const FeishuChatSchema = Type.Object({
125
151
  }))
126
152
  });
127
153
  //#endregion
154
+ //#region extensions/feishu/src/comment-target.ts
155
+ const FEISHU_COMMENT_FILE_TYPES = [
156
+ "doc",
157
+ "docx",
158
+ "file",
159
+ "sheet",
160
+ "slides"
161
+ ];
162
+ function normalizeCommentFileType(value) {
163
+ return typeof value === "string" && FEISHU_COMMENT_FILE_TYPES.includes(value) ? value : void 0;
164
+ }
165
+ function buildFeishuCommentTarget(params) {
166
+ return `comment:${params.fileType}:${params.fileToken}:${params.commentId}`;
167
+ }
168
+ function parseFeishuCommentTarget(raw) {
169
+ const trimmed = raw?.trim();
170
+ if (!trimmed?.startsWith("comment:")) return null;
171
+ const parts = trimmed.split(":");
172
+ if (parts.length !== 4) return null;
173
+ const fileType = normalizeCommentFileType(parts[1]);
174
+ const fileToken = parts[2]?.trim();
175
+ const commentId = parts[3]?.trim();
176
+ if (!fileType || !fileToken || !commentId) return null;
177
+ return {
178
+ fileType,
179
+ fileToken,
180
+ commentId
181
+ };
182
+ }
183
+ //#endregion
184
+ //#region extensions/feishu/src/send-rate-limit.ts
185
+ const FEISHU_SEND_RATE_LIMIT_CODES = /* @__PURE__ */ new Set([230020, 11232]);
186
+ function getFeishuSendRateLimitCode(error) {
187
+ if (!isRecord(error)) return;
188
+ const response = isRecord(error.response) ? error.response : void 0;
189
+ if (response?.status === 429) return 429;
190
+ const code = (isRecord(response?.data) ? response.data : void 0)?.code;
191
+ return typeof code === "number" && FEISHU_SEND_RATE_LIMIT_CODES.has(code) ? code : void 0;
192
+ }
193
+ function getFeishuSendRateLimitCodeFromResponse(response) {
194
+ if (!isRecord(response)) return;
195
+ const code = response.code;
196
+ return typeof code === "number" && FEISHU_SEND_RATE_LIMIT_CODES.has(code) ? code : void 0;
197
+ }
198
+ //#endregion
199
+ //#region extensions/feishu/src/comment-shared.ts
200
+ function encodeQuery(params) {
201
+ const query = new URLSearchParams();
202
+ for (const [key, value] of Object.entries(params)) {
203
+ const trimmed = value?.trim();
204
+ if (trimmed) query.set(key, trimmed);
205
+ }
206
+ const queryString = query.toString();
207
+ return queryString ? `?${queryString}` : "";
208
+ }
209
+ function formatFeishuApiError(error, options = {}) {
210
+ if (!isRecord(error)) return typeof error === "string" ? error : JSON.stringify(error);
211
+ const config = isRecord(error.config) ? error.config : void 0;
212
+ const response = isRecord(error.response) ? error.response : void 0;
213
+ const responseData = isRecord(response?.data) ? response?.data : void 0;
214
+ const feishuLogId = readStringValue(responseData?.log_id) || (options.includeNestedErrorLogId ? readStringValue(isRecord(responseData?.error) ? responseData.error.log_id : void 0) : void 0);
215
+ const nestedError = isRecord(responseData?.error) ? responseData.error : void 0;
216
+ return JSON.stringify({
217
+ message: typeof error.message === "string" ? error.message : typeof error === "string" ? error : JSON.stringify(error),
218
+ code: readStringValue(error.code),
219
+ method: readStringValue(config?.method),
220
+ url: readStringValue(config?.url),
221
+ ...options.includeConfigParams ? { params: config?.params } : {},
222
+ http_status: typeof response?.status === "number" ? response.status : void 0,
223
+ feishu_code: typeof responseData?.code === "number" ? responseData.code : readStringValue(responseData?.code),
224
+ feishu_msg: readStringValue(responseData?.msg),
225
+ feishu_log_id: feishuLogId,
226
+ feishu_troubleshooter: readStringValue(responseData?.troubleshooter) || readStringValue(nestedError?.troubleshooter)
227
+ });
228
+ }
229
+ function formatFeishuApiFailure(error, errorPrefix, options = {}) {
230
+ return `${errorPrefix}: ${formatFeishuApiError(error, options) || "unknown error"}`;
231
+ }
232
+ function createFeishuApiError(error, errorPrefix, options = {}) {
233
+ return new Error(formatFeishuApiFailure(error, errorPrefix, options), { cause: error });
234
+ }
235
+ const FEISHU_SEND_RETRY_BASE_MS = 500;
236
+ async function requestFeishuApi(request, errorPrefix, options = {}) {
237
+ try {
238
+ return await retryAsync(async () => {
239
+ const result = await request();
240
+ const fulfilledRateLimit = getFeishuSendRateLimitCodeFromResponse(result);
241
+ if (fulfilledRateLimit !== void 0) throw Object.assign(/* @__PURE__ */ new Error(`Request fulfilled with rate-limit code ${fulfilledRateLimit}`), { response: {
242
+ status: 200,
243
+ data: result
244
+ } });
245
+ return result;
246
+ }, {
247
+ attempts: 3,
248
+ minDelayMs: options.retryDelayMs ?? FEISHU_SEND_RETRY_BASE_MS,
249
+ shouldRetry: (error) => getFeishuSendRateLimitCode(error) !== void 0
250
+ });
251
+ } catch (error) {
252
+ throw createFeishuApiError(error, errorPrefix, options);
253
+ }
254
+ }
255
+ function readDocsLinkUrl(element) {
256
+ const docsLink = isRecord(element.docs_link) ? element.docs_link : void 0;
257
+ return normalizeOptionalString(docsLink?.url) || normalizeOptionalString(docsLink?.link) || normalizeOptionalString(element.url) || normalizeOptionalString(element.link) || void 0;
258
+ }
259
+ function readMentionUserId(element) {
260
+ const mention = isRecord(element.mention) ? element.mention : void 0;
261
+ return normalizeOptionalString((isRecord(element.person) ? element.person : void 0)?.user_id) || normalizeOptionalString(mention?.user_id) || normalizeOptionalString(mention?.open_id) || normalizeOptionalString(element.mention_user) || normalizeOptionalString(element.user_id) || void 0;
262
+ }
263
+ function readMentionDisplayText(element, userId) {
264
+ const mention = isRecord(element.mention) ? element.mention : void 0;
265
+ const mentionName = normalizeOptionalString(mention?.name) || normalizeOptionalString(mention?.display_name) || normalizeOptionalString(element.name);
266
+ return mentionName ? `@${mentionName}` : `@${userId}`;
267
+ }
268
+ function normalizeCommentText(parts) {
269
+ return parts.join("").trim() || void 0;
270
+ }
271
+ function normalizeCommentSemanticText(parts) {
272
+ return parts.join("").replace(/\s+/g, " ").trim() || void 0;
273
+ }
274
+ function readElementTextPreservingWhitespace(element) {
275
+ return (isRecord(element.text_run) ? readStringValue(element.text_run.content) || readStringValue(element.text_run.text) : void 0) || readStringValue(element.text) || readStringValue(element.content) || readStringValue(element.name) || void 0;
276
+ }
277
+ const FEISHU_LINK_TOKEN_MIN_LENGTH = 22;
278
+ const FEISHU_LINK_TOKEN_MAX_LENGTH = 28;
279
+ const COMMENT_LINK_KIND_ALIASES = /* @__PURE__ */ new Map([
280
+ ["doc", "doc"],
281
+ ["docs", "doc"],
282
+ ["docx", "docx"],
283
+ ["sheet", "sheet"],
284
+ ["sheets", "sheet"],
285
+ ["slide", "slides"],
286
+ ["slides", "slides"],
287
+ ["file", "file"],
288
+ ["files", "file"],
289
+ ["wiki", "wiki"],
290
+ ["mindnote", "mindnote"],
291
+ ["mindnotes", "mindnote"],
292
+ ["bitable", "bitable"],
293
+ ["base", "base"]
294
+ ]);
295
+ function isCommentFileType(value) {
296
+ return typeof value === "string" && FEISHU_COMMENT_FILE_TYPES.includes(value);
297
+ }
298
+ function isReasonableFeishuLinkToken(token) {
299
+ return typeof token === "string" && token.length >= FEISHU_LINK_TOKEN_MIN_LENGTH && token.length <= FEISHU_LINK_TOKEN_MAX_LENGTH;
300
+ }
301
+ function parseCommentLinkedDocumentPath(pathname) {
302
+ const segments = normalizeStringEntries(pathname.split("/"));
303
+ const offset = segments[0]?.toLowerCase() === "space" ? 1 : 0;
304
+ const kind = COMMENT_LINK_KIND_ALIASES.get(segments[offset]?.toLowerCase() ?? "");
305
+ const token = normalizeOptionalString(segments[offset + 1]);
306
+ if (!kind || !isReasonableFeishuLinkToken(token)) return null;
307
+ return {
308
+ urlKind: kind,
309
+ token
310
+ };
311
+ }
312
+ function hasResolvedLinkedDocumentReference(link) {
313
+ return link.urlKind !== "unknown" && (Boolean(link.resolvedObjToken) || Boolean(link.wikiNodeToken));
314
+ }
315
+ function resolveCommentLinkedDocumentFromUrl(params) {
316
+ const link = {
317
+ rawUrl: params.rawUrl,
318
+ urlKind: "unknown"
319
+ };
320
+ try {
321
+ const parsedPath = parseCommentLinkedDocumentPath(new URL(params.rawUrl).pathname);
322
+ if (!parsedPath) return link;
323
+ const { urlKind, token } = parsedPath;
324
+ link.urlKind = urlKind;
325
+ if (urlKind === "wiki") {
326
+ link.urlKind = "wiki";
327
+ link.wikiNodeToken = token;
328
+ } else {
329
+ link.resolvedObjType = urlKind;
330
+ link.resolvedObjToken = token;
331
+ }
332
+ if (link.resolvedObjType && link.resolvedObjToken && isCommentFileType(link.resolvedObjType) && params.currentDocument?.fileType === link.resolvedObjType && params.currentDocument.fileToken === link.resolvedObjToken) link.isCurrentDocument = true;
333
+ else if (link.resolvedObjType && link.resolvedObjToken && isCommentFileType(link.resolvedObjType)) link.isCurrentDocument = false;
334
+ } catch {
335
+ return link;
336
+ }
337
+ return link;
338
+ }
339
+ function parseCommentContentElements(params) {
340
+ const elements = Array.isArray(params.elements) ? params.elements : [];
341
+ const plainTextParts = [];
342
+ const semanticTextParts = [];
343
+ const mentions = [];
344
+ const linkedDocuments = [];
345
+ const botIds = new Set(Array.from(params.botOpenIds ?? []).map((value) => normalizeOptionalString(value)).filter((value) => Boolean(value)));
346
+ const linkedDocumentKeys = /* @__PURE__ */ new Set();
347
+ let botMentioned = false;
348
+ for (const rawElement of elements) {
349
+ if (!isRecord(rawElement)) continue;
350
+ const element = rawElement;
351
+ const type = normalizeOptionalString(element.type);
352
+ const text = (type === "text_run" ? readElementTextPreservingWhitespace(element) : void 0) || (type === "text" ? readElementTextPreservingWhitespace(element) : void 0) || (type === "docs_link" || type === "link" ? readDocsLinkUrl(element) : void 0) || (type === "mention" || type === "mention_user" || type === "person" ? (() => {
353
+ const userId = readMentionUserId(element);
354
+ return userId ? readMentionDisplayText(element, userId) : void 0;
355
+ })() : void 0) || readElementTextPreservingWhitespace(element) || void 0;
356
+ if (type === "mention" || type === "mention_user" || type === "person") {
357
+ const userId = readMentionUserId(element);
358
+ if (userId) {
359
+ const displayText = readMentionDisplayText(element, userId);
360
+ const isBotMention = botIds.has(userId);
361
+ mentions.push({
362
+ userId,
363
+ displayText,
364
+ isBotMention
365
+ });
366
+ plainTextParts.push(displayText);
367
+ if (!isBotMention) semanticTextParts.push(displayText);
368
+ else botMentioned = true;
369
+ continue;
370
+ }
371
+ }
372
+ if (type === "docs_link" || type === "link") {
373
+ const rawUrl = readDocsLinkUrl(element);
374
+ if (rawUrl) {
375
+ plainTextParts.push(rawUrl);
376
+ semanticTextParts.push(rawUrl);
377
+ const linkedDocument = resolveCommentLinkedDocumentFromUrl({
378
+ rawUrl,
379
+ currentDocument: params.currentDocument
380
+ });
381
+ if (hasResolvedLinkedDocumentReference(linkedDocument)) {
382
+ const key = [
383
+ linkedDocument.rawUrl,
384
+ linkedDocument.urlKind,
385
+ linkedDocument.resolvedObjType,
386
+ linkedDocument.resolvedObjToken,
387
+ linkedDocument.wikiNodeToken
388
+ ].join(":");
389
+ if (!linkedDocumentKeys.has(key)) {
390
+ linkedDocumentKeys.add(key);
391
+ linkedDocuments.push(linkedDocument);
392
+ }
393
+ }
394
+ continue;
395
+ }
396
+ }
397
+ if (text) {
398
+ plainTextParts.push(text);
399
+ semanticTextParts.push(text);
400
+ }
401
+ }
402
+ return {
403
+ plainText: normalizeCommentText(plainTextParts),
404
+ semanticText: normalizeCommentSemanticText(semanticTextParts),
405
+ mentions,
406
+ linkedDocuments,
407
+ botMentioned
408
+ };
409
+ }
410
+ function extractReplyText(reply) {
411
+ if (!reply || !isRecord(reply.content)) return;
412
+ return parseCommentContentElements({ elements: Array.isArray(reply.content.elements) ? reply.content.elements : [] }).plainText;
413
+ }
414
+ //#endregion
128
415
  //#region extensions/feishu/src/chat.ts
129
416
  function readChatPageSize(params) {
130
417
  return readPositiveIntegerParam(params, "page_size", {
@@ -292,6 +579,7 @@ function registerFeishuChatTools(api) {
292
579
  if (!resolveAnyEnabledFeishuToolsConfig(accounts).chat) return;
293
580
  api.registerTool((toolContext) => ({
294
581
  name: "feishu_chat",
582
+ resultContentSource: "network",
295
583
  label: "Feishu Chat",
296
584
  description: "Feishu chat operations. Actions: members, info, member_info",
297
585
  parameters: FeishuChatSchema,
@@ -310,7 +598,7 @@ function registerFeishuChatTools(api) {
310
598
  const client = createFeishuClient(account);
311
599
  switch (p.action) {
312
600
  case "members":
313
- if (!p.chat_id) return jsonResult({ error: "chat_id is required for action members" });
601
+ if (!p.chat_id) return feishuExternalToolResult({ error: "chat_id is required for action members" });
314
602
  {
315
603
  const chat = await getAuthorizedFeishuChatInfo({
316
604
  client,
@@ -327,12 +615,12 @@ function registerFeishuChatTools(api) {
327
615
  ctx: toolContext,
328
616
  memberIdType: p.member_id_type
329
617
  });
330
- if (authorization.kind === "direct") return jsonResult(buildFeishuDirectChatMembers(authorization));
618
+ if (authorization.kind === "direct") return feishuExternalToolResult(buildFeishuDirectChatMembers(authorization));
331
619
  }
332
- return jsonResult(await getChatMembers(client, p.chat_id, readChatPageSize(rawParams), p.page_token, p.member_id_type));
620
+ return feishuExternalToolResult(await getChatMembers(client, p.chat_id, readChatPageSize(rawParams), p.page_token, p.member_id_type));
333
621
  case "info":
334
- if (!p.chat_id) return jsonResult({ error: "chat_id is required for action info" });
335
- return jsonResult(await getAuthorizedFeishuChatInfo({
622
+ if (!p.chat_id) return feishuExternalToolResult({ error: "chat_id is required for action info" });
623
+ return feishuExternalToolResult(await getAuthorizedFeishuChatInfo({
336
624
  client,
337
625
  cfg,
338
626
  account,
@@ -340,8 +628,8 @@ function registerFeishuChatTools(api) {
340
628
  ctx: toolContext
341
629
  }));
342
630
  case "member_info":
343
- if (!p.member_id) return jsonResult({ error: "member_id is required for action member_info" });
344
- if (!p.chat_id) return jsonResult({ error: "chat_id is required for action member_info" });
631
+ if (!p.member_id) return feishuExternalToolResult({ error: "member_id is required for action member_info" });
632
+ if (!p.chat_id) return feishuExternalToolResult({ error: "chat_id is required for action member_info" });
345
633
  {
346
634
  const chat = await getAuthorizedFeishuChatInfo({
347
635
  client,
@@ -362,27 +650,19 @@ function registerFeishuChatTools(api) {
362
650
  if (authorization.kind === "group") {
363
651
  const memberIdType = p.member_id_type ?? "open_id";
364
652
  await assertFeishuChatMember(client, p.chat_id, p.member_id, memberIdType);
365
- return jsonResult(await getFeishuMemberInfo(client, p.member_id, memberIdType));
653
+ return feishuExternalToolResult(await getFeishuMemberInfo(client, p.member_id, memberIdType));
366
654
  }
367
- return jsonResult(await getFeishuMemberInfo(client, authorization.memberId, authorization.memberIdType));
655
+ return feishuExternalToolResult(await getFeishuMemberInfo(client, authorization.memberId, authorization.memberIdType));
368
656
  }
369
- default: return jsonResult({ error: `Unknown action: ${String(p.action)}` });
657
+ default: return feishuExternalToolResult({ error: `Unknown action: ${String(p.action)}` });
370
658
  }
371
659
  } catch (err) {
372
- return jsonResult({ error: formatFeishuApiError(err, { includeNestedErrorLogId: true }) });
660
+ return feishuExternalToolResult({ error: formatFeishuApiError(err, { includeNestedErrorLogId: true }) });
373
661
  }
374
662
  }
375
663
  }), { name: "feishu_chat" });
376
664
  }
377
665
  //#endregion
378
- //#region extensions/feishu/src/tool-result.ts
379
- function unknownToolActionResult(action) {
380
- return jsonResult({ error: `Unknown action: ${String(action)}` });
381
- }
382
- function toolExecutionErrorResult(error) {
383
- return jsonResult({ error: formatErrorMessage(error) });
384
- }
385
- //#endregion
386
666
  //#region extensions/feishu/src/comment-reaction.ts
387
667
  const COMMENT_TYPING_REACTION_TYPE = "Typing";
388
668
  const COMMENT_REACTION_TIMEOUT_MS = 3e4;
@@ -726,15 +1006,15 @@ function formatDriveApiError(error) {
726
1006
  return formatFeishuApiError(error, { includeConfigParams: true });
727
1007
  }
728
1008
  function extractDriveApiErrorMeta(error) {
729
- if (!isRecord$1(error)) return { message: typeof error === "string" ? error : JSON.stringify(error) };
730
- const response = isRecord$1(error.response) ? error.response : void 0;
731
- const responseData = isRecord$1(response?.data) ? response?.data : void 0;
1009
+ if (!isRecord(error)) return { message: typeof error === "string" ? error : JSON.stringify(error) };
1010
+ const response = isRecord(error.response) ? error.response : void 0;
1011
+ const responseData = isRecord(response?.data) ? response?.data : void 0;
732
1012
  return {
733
1013
  message: typeof error.message === "string" ? error.message : typeof error === "string" ? error : JSON.stringify(error),
734
1014
  httpStatus: typeof response?.status === "number" ? response.status : void 0,
735
- feishuCode: typeof responseData?.code === "number" ? responseData.code : readString(responseData?.code),
736
- feishuMsg: readString(responseData?.msg),
737
- feishuLogId: readString(responseData?.log_id)
1015
+ feishuCode: typeof responseData?.code === "number" ? responseData.code : readStringValue(responseData?.code),
1016
+ feishuMsg: readStringValue(responseData?.msg),
1017
+ feishuLogId: readStringValue(responseData?.log_id)
738
1018
  };
739
1019
  }
740
1020
  function isReplyNotAllowedError(error) {
@@ -1013,6 +1293,7 @@ function registerFeishuDriveTools(api) {
1013
1293
  const defaultAccountId = ctx.agentAccountId;
1014
1294
  return {
1015
1295
  name: "feishu_drive",
1296
+ resultContentSource: "network",
1016
1297
  label: "Feishu Drive",
1017
1298
  description: "Feishu cloud storage operations. Actions: list, info, create_folder, move, delete, list_comments, list_comment_replies, add_comment, reply_comment",
1018
1299
  parameters: FeishuDriveSchema,
@@ -1029,21 +1310,21 @@ function registerFeishuDriveTools(api) {
1029
1310
  }
1030
1311
  });
1031
1312
  switch (p.action) {
1032
- case "list": return jsonResult(await listFolder(client, {
1313
+ case "list": return feishuExternalToolResult(await listFolder(client, {
1033
1314
  folder_token: p.folder_token,
1034
1315
  page_size: p.page_size,
1035
1316
  page_token: p.page_token
1036
1317
  }));
1037
- case "info": return jsonResult(await getFileInfo(client, p.file_token, p.type));
1038
- case "create_folder": return jsonResult(await createFolder(client, p.name, p.folder_token));
1039
- case "move": return jsonResult(await moveFile(client, p.file_token, p.type, p.folder_token));
1040
- case "delete": return jsonResult(await deleteFile(client, p.file_token, p.type));
1041
- case "list_comments": return jsonResult(await listComments(client, applyCommentFileTypeDefault(applyAmbientCommentDefaults(p, ctx), "list_comments")));
1042
- case "list_comment_replies": return jsonResult(await listCommentReplies(client, applyCommentFileTypeDefault(applyAmbientCommentDefaults(p, ctx), "list_comment_replies")));
1318
+ case "info": return feishuExternalToolResult(await getFileInfo(client, p.file_token, p.type));
1319
+ case "create_folder": return feishuExternalToolResult(await createFolder(client, p.name, p.folder_token));
1320
+ case "move": return feishuExternalToolResult(await moveFile(client, p.file_token, p.type, p.folder_token));
1321
+ case "delete": return feishuExternalToolResult(await deleteFile(client, p.file_token, p.type));
1322
+ case "list_comments": return feishuExternalToolResult(await listComments(client, applyCommentFileTypeDefault(applyAmbientCommentDefaults(p, ctx), "list_comments")));
1323
+ case "list_comment_replies": return feishuExternalToolResult(await listCommentReplies(client, applyCommentFileTypeDefault(applyAmbientCommentDefaults(p, ctx), "list_comment_replies")));
1043
1324
  case "add_comment": {
1044
1325
  const resolved = applyAddCommentDefaults(applyAddCommentAmbientDefaults(p, ctx));
1045
1326
  try {
1046
- return jsonResult(await addComment(client, resolved));
1327
+ return feishuExternalToolResult(await addComment(client, resolved));
1047
1328
  } finally {
1048
1329
  cleanupAmbientCommentTypingReaction({
1049
1330
  client: getDriveInternalClient(client),
@@ -1054,7 +1335,7 @@ function registerFeishuDriveTools(api) {
1054
1335
  case "reply_comment": {
1055
1336
  const resolved = applyCommentFileTypeDefault(applyAmbientCommentDefaults(p, ctx), "reply_comment");
1056
1337
  try {
1057
- return jsonResult(await deliverCommentThreadText(client, resolved));
1338
+ return feishuExternalToolResult(await deliverCommentThreadText(client, resolved));
1058
1339
  } finally {
1059
1340
  cleanupAmbientCommentTypingReaction({
1060
1341
  client: getDriveInternalClient(client),
@@ -1072,4 +1353,4 @@ function registerFeishuDriveTools(api) {
1072
1353
  }, { name: "feishu_drive" });
1073
1354
  }
1074
1355
  //#endregion
1075
- export { toolExecutionErrorResult as a, buildFeishuDirectChatMembers as c, getFeishuMemberInfo as d, registerFeishuChatTools as f, resolveToolsConfig as g, resolveFeishuToolAccount as h, createCommentTypingReactionLifecycle as i, getChatInfo as l, resolveAnyEnabledFeishuToolsConfig as m, registerFeishuDriveTools as n, unknownToolActionResult as o, createFeishuToolClient as p, cleanupAmbientCommentTypingReaction as r, assertFeishuChatMember as s, deliverCommentThreadText as t, getChatMembers as u };
1356
+ export { resolveFeishuToolAccount as C, resolveAnyEnabledFeishuToolsConfig as S, parseFeishuCommentTarget as _, assertFeishuChatMember as a, unknownToolActionResult as b, getChatMembers as c, encodeQuery as d, extractReplyText as f, normalizeCommentFileType as g, buildFeishuCommentTarget as h, createCommentTypingReactionLifecycle as i, getFeishuMemberInfo as l, requestFeishuApi as m, registerFeishuDriveTools as n, buildFeishuDirectChatMembers as o, parseCommentContentElements as p, cleanupAmbientCommentTypingReaction as r, getChatInfo as s, deliverCommentThreadText as t, registerFeishuChatTools as u, feishuExternalToolResult as v, createFeishuToolClient as x, toolExecutionErrorResult as y };