@m1heng-clawd/feishu 0.1.7 → 0.1.9

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/src/reactions.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ClawdbotConfig } from "openclaw/plugin-sdk";
2
- import type { FeishuConfig } from "./types.js";
3
2
  import { createFeishuClient } from "./client.js";
3
+ import { resolveFeishuAccount } from "./accounts.js";
4
4
 
5
5
  export type FeishuReaction = {
6
6
  reactionId: string;
@@ -18,14 +18,15 @@ export async function addReactionFeishu(params: {
18
18
  cfg: ClawdbotConfig;
19
19
  messageId: string;
20
20
  emojiType: string;
21
+ accountId?: string;
21
22
  }): Promise<{ reactionId: string }> {
22
- const { cfg, messageId, emojiType } = params;
23
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
24
- if (!feishuCfg) {
25
- throw new Error("Feishu channel not configured");
23
+ const { cfg, messageId, emojiType, accountId } = params;
24
+ const account = resolveFeishuAccount({ cfg, accountId });
25
+ if (!account.configured) {
26
+ throw new Error(`Feishu account "${account.accountId}" not configured`);
26
27
  }
27
28
 
28
- const client = createFeishuClient(feishuCfg);
29
+ const client = createFeishuClient(account);
29
30
 
30
31
  const response = (await client.im.messageReaction.create({
31
32
  path: { message_id: messageId },
@@ -59,14 +60,15 @@ export async function removeReactionFeishu(params: {
59
60
  cfg: ClawdbotConfig;
60
61
  messageId: string;
61
62
  reactionId: string;
63
+ accountId?: string;
62
64
  }): Promise<void> {
63
- const { cfg, messageId, reactionId } = params;
64
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
65
- if (!feishuCfg) {
66
- throw new Error("Feishu channel not configured");
65
+ const { cfg, messageId, reactionId, accountId } = params;
66
+ const account = resolveFeishuAccount({ cfg, accountId });
67
+ if (!account.configured) {
68
+ throw new Error(`Feishu account "${account.accountId}" not configured`);
67
69
  }
68
70
 
69
- const client = createFeishuClient(feishuCfg);
71
+ const client = createFeishuClient(account);
70
72
 
71
73
  const response = (await client.im.messageReaction.delete({
72
74
  path: {
@@ -87,14 +89,15 @@ export async function listReactionsFeishu(params: {
87
89
  cfg: ClawdbotConfig;
88
90
  messageId: string;
89
91
  emojiType?: string;
92
+ accountId?: string;
90
93
  }): Promise<FeishuReaction[]> {
91
- const { cfg, messageId, emojiType } = params;
92
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
93
- if (!feishuCfg) {
94
- throw new Error("Feishu channel not configured");
94
+ const { cfg, messageId, emojiType, accountId } = params;
95
+ const account = resolveFeishuAccount({ cfg, accountId });
96
+ if (!account.configured) {
97
+ throw new Error(`Feishu account "${account.accountId}" not configured`);
95
98
  }
96
99
 
97
- const client = createFeishuClient(feishuCfg);
100
+ const client = createFeishuClient(account);
98
101
 
99
102
  const response = (await client.im.messageReaction.list({
100
103
  path: { message_id: messageId },
@@ -10,6 +10,7 @@ import { getFeishuRuntime } from "./runtime.js";
10
10
  import { sendMessageFeishu, sendMarkdownCardFeishu } from "./send.js";
11
11
  import type { FeishuConfig } from "./types.js";
12
12
  import type { MentionTarget } from "./mention.js";
13
+ import { resolveFeishuAccount } from "./accounts.js";
13
14
  import {
14
15
  addTypingIndicator,
15
16
  removeTypingIndicator,
@@ -36,11 +37,16 @@ export type CreateFeishuReplyDispatcherParams = {
36
37
  replyToMessageId?: string;
37
38
  /** Mention targets, will be auto-included in replies */
38
39
  mentionTargets?: MentionTarget[];
40
+ /** Account ID for multi-account support */
41
+ accountId?: string;
39
42
  };
40
43
 
41
44
  export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherParams) {
42
45
  const core = getFeishuRuntime();
43
- const { cfg, agentId, chatId, replyToMessageId, mentionTargets } = params;
46
+ const { cfg, agentId, chatId, replyToMessageId, mentionTargets, accountId } = params;
47
+
48
+ // Resolve account for config access
49
+ const account = resolveFeishuAccount({ cfg, accountId });
44
50
 
45
51
  const prefixContext = createReplyPrefixContext({
46
52
  cfg,
@@ -54,14 +60,14 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
54
60
  const typingCallbacks = createTypingCallbacks({
55
61
  start: async () => {
56
62
  if (!replyToMessageId) return;
57
- typingState = await addTypingIndicator({ cfg, messageId: replyToMessageId });
58
- params.runtime.log?.(`feishu: added typing indicator reaction`);
63
+ typingState = await addTypingIndicator({ cfg, messageId: replyToMessageId, accountId });
64
+ params.runtime.log?.(`feishu[${account.accountId}]: added typing indicator reaction`);
59
65
  },
60
66
  stop: async () => {
61
67
  if (!typingState) return;
62
- await removeTypingIndicator({ cfg, state: typingState });
68
+ await removeTypingIndicator({ cfg, state: typingState, accountId });
63
69
  typingState = null;
64
- params.runtime.log?.(`feishu: removed typing indicator reaction`);
70
+ params.runtime.log?.(`feishu[${account.accountId}]: removed typing indicator reaction`);
65
71
  },
66
72
  onStartError: (err) => {
67
73
  logTypingFailure({
@@ -99,15 +105,15 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
99
105
  humanDelay: core.channel.reply.resolveHumanDelayConfig(cfg, agentId),
100
106
  onReplyStart: typingCallbacks.onReplyStart,
101
107
  deliver: async (payload: ReplyPayload) => {
102
- params.runtime.log?.(`feishu deliver called: text=${payload.text?.slice(0, 100)}`);
108
+ params.runtime.log?.(`feishu[${account.accountId}] deliver called: text=${payload.text?.slice(0, 100)}`);
103
109
  const text = payload.text ?? "";
104
110
  if (!text.trim()) {
105
- params.runtime.log?.(`feishu deliver: empty text, skipping`);
111
+ params.runtime.log?.(`feishu[${account.accountId}] deliver: empty text, skipping`);
106
112
  return;
107
113
  }
108
114
 
109
115
  // Check render mode: auto (default), raw, or card
110
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
116
+ const feishuCfg = account.config;
111
117
  const renderMode = feishuCfg?.renderMode ?? "auto";
112
118
 
113
119
  // Determine if we should use card for this message
@@ -120,7 +126,7 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
120
126
  if (useCard) {
121
127
  // Card mode: send as interactive card with markdown rendering
122
128
  const chunks = core.channel.text.chunkTextWithMode(text, textChunkLimit, chunkMode);
123
- params.runtime.log?.(`feishu deliver: sending ${chunks.length} card chunks to ${chatId}`);
129
+ params.runtime.log?.(`feishu[${account.accountId}] deliver: sending ${chunks.length} card chunks to ${chatId}`);
124
130
  for (const chunk of chunks) {
125
131
  await sendMarkdownCardFeishu({
126
132
  cfg,
@@ -128,6 +134,7 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
128
134
  text: chunk,
129
135
  replyToMessageId,
130
136
  mentions: isFirstChunk ? mentionTargets : undefined,
137
+ accountId,
131
138
  });
132
139
  isFirstChunk = false;
133
140
  }
@@ -135,7 +142,7 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
135
142
  // Raw mode: send as plain text with table conversion
136
143
  const converted = core.channel.text.convertMarkdownTables(text, tableMode);
137
144
  const chunks = core.channel.text.chunkTextWithMode(converted, textChunkLimit, chunkMode);
138
- params.runtime.log?.(`feishu deliver: sending ${chunks.length} text chunks to ${chatId}`);
145
+ params.runtime.log?.(`feishu[${account.accountId}] deliver: sending ${chunks.length} text chunks to ${chatId}`);
139
146
  for (const chunk of chunks) {
140
147
  await sendMessageFeishu({
141
148
  cfg,
@@ -143,13 +150,14 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
143
150
  text: chunk,
144
151
  replyToMessageId,
145
152
  mentions: isFirstChunk ? mentionTargets : undefined,
153
+ accountId,
146
154
  });
147
155
  isFirstChunk = false;
148
156
  }
149
157
  }
150
158
  },
151
159
  onError: (err, info) => {
152
- params.runtime.error?.(`feishu ${info.kind} reply failed: ${String(err)}`);
160
+ params.runtime.error?.(`feishu[${account.accountId}] ${info.kind} reply failed: ${String(err)}`);
153
161
  typingCallbacks.onIdle?.();
154
162
  },
155
163
  onIdle: typingCallbacks.onIdle,
package/src/send.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import type { ClawdbotConfig } from "openclaw/plugin-sdk";
2
- import type { FeishuConfig, FeishuSendResult } from "./types.js";
2
+ import type { FeishuSendResult, ResolvedFeishuAccount } from "./types.js";
3
3
  import type { MentionTarget } from "./mention.js";
4
4
  import { buildMentionedMessage, buildMentionedCardContent } from "./mention.js";
5
5
  import { createFeishuClient } from "./client.js";
6
6
  import { resolveReceiveIdType, normalizeFeishuTarget } from "./targets.js";
7
7
  import { getFeishuRuntime } from "./runtime.js";
8
+ import { resolveFeishuAccount } from "./accounts.js";
8
9
 
9
10
  export type FeishuMessageInfo = {
10
11
  messageId: string;
@@ -23,14 +24,15 @@ export type FeishuMessageInfo = {
23
24
  export async function getMessageFeishu(params: {
24
25
  cfg: ClawdbotConfig;
25
26
  messageId: string;
27
+ accountId?: string;
26
28
  }): Promise<FeishuMessageInfo | null> {
27
- const { cfg, messageId } = params;
28
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
29
- if (!feishuCfg) {
30
- throw new Error("Feishu channel not configured");
29
+ const { cfg, messageId, accountId } = params;
30
+ const account = resolveFeishuAccount({ cfg, accountId });
31
+ if (!account.configured) {
32
+ throw new Error(`Feishu account "${account.accountId}" not configured`);
31
33
  }
32
34
 
33
- const client = createFeishuClient(feishuCfg);
35
+ const client = createFeishuClient(account);
34
36
 
35
37
  try {
36
38
  const response = (await client.im.message.get({
@@ -95,9 +97,11 @@ export type SendFeishuMessageParams = {
95
97
  replyToMessageId?: string;
96
98
  /** Mention target users */
97
99
  mentions?: MentionTarget[];
100
+ /** Account ID (optional, uses default if not specified) */
101
+ accountId?: string;
98
102
  };
99
103
 
100
- function buildFeishuPostMessagePayload(params: { feishuCfg: FeishuConfig; messageText: string }): {
104
+ function buildFeishuPostMessagePayload(params: { messageText: string }): {
101
105
  content: string;
102
106
  msgType: string;
103
107
  } {
@@ -120,13 +124,13 @@ function buildFeishuPostMessagePayload(params: { feishuCfg: FeishuConfig; messag
120
124
  }
121
125
 
122
126
  export async function sendMessageFeishu(params: SendFeishuMessageParams): Promise<FeishuSendResult> {
123
- const { cfg, to, text, replyToMessageId, mentions } = params;
124
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
125
- if (!feishuCfg) {
126
- throw new Error("Feishu channel not configured");
127
+ const { cfg, to, text, replyToMessageId, mentions, accountId } = params;
128
+ const account = resolveFeishuAccount({ cfg, accountId });
129
+ if (!account.configured) {
130
+ throw new Error(`Feishu account "${account.accountId}" not configured`);
127
131
  }
128
132
 
129
- const client = createFeishuClient(feishuCfg);
133
+ const client = createFeishuClient(account);
130
134
  const receiveId = normalizeFeishuTarget(to);
131
135
  if (!receiveId) {
132
136
  throw new Error(`Invalid Feishu target: ${to}`);
@@ -145,10 +149,7 @@ export async function sendMessageFeishu(params: SendFeishuMessageParams): Promis
145
149
  }
146
150
  const messageText = getFeishuRuntime().channel.text.convertMarkdownTables(rawText, tableMode);
147
151
 
148
- const { content, msgType } = buildFeishuPostMessagePayload({
149
- feishuCfg,
150
- messageText,
151
- });
152
+ const { content, msgType } = buildFeishuPostMessagePayload({ messageText });
152
153
 
153
154
  if (replyToMessageId) {
154
155
  const response = await client.im.message.reply({
@@ -193,16 +194,17 @@ export type SendFeishuCardParams = {
193
194
  to: string;
194
195
  card: Record<string, unknown>;
195
196
  replyToMessageId?: string;
197
+ accountId?: string;
196
198
  };
197
199
 
198
200
  export async function sendCardFeishu(params: SendFeishuCardParams): Promise<FeishuSendResult> {
199
- const { cfg, to, card, replyToMessageId } = params;
200
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
201
- if (!feishuCfg) {
202
- throw new Error("Feishu channel not configured");
201
+ const { cfg, to, card, replyToMessageId, accountId } = params;
202
+ const account = resolveFeishuAccount({ cfg, accountId });
203
+ if (!account.configured) {
204
+ throw new Error(`Feishu account "${account.accountId}" not configured`);
203
205
  }
204
206
 
205
- const client = createFeishuClient(feishuCfg);
207
+ const client = createFeishuClient(account);
206
208
  const receiveId = normalizeFeishuTarget(to);
207
209
  if (!receiveId) {
208
210
  throw new Error(`Invalid Feishu target: ${to}`);
@@ -253,14 +255,15 @@ export async function updateCardFeishu(params: {
253
255
  cfg: ClawdbotConfig;
254
256
  messageId: string;
255
257
  card: Record<string, unknown>;
258
+ accountId?: string;
256
259
  }): Promise<void> {
257
- const { cfg, messageId, card } = params;
258
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
259
- if (!feishuCfg) {
260
- throw new Error("Feishu channel not configured");
260
+ const { cfg, messageId, card, accountId } = params;
261
+ const account = resolveFeishuAccount({ cfg, accountId });
262
+ if (!account.configured) {
263
+ throw new Error(`Feishu account "${account.accountId}" not configured`);
261
264
  }
262
265
 
263
- const client = createFeishuClient(feishuCfg);
266
+ const client = createFeishuClient(account);
264
267
  const content = JSON.stringify(card);
265
268
 
266
269
  const response = await client.im.message.patch({
@@ -276,18 +279,22 @@ export async function updateCardFeishu(params: {
276
279
  /**
277
280
  * Build a Feishu interactive card with markdown content.
278
281
  * Cards render markdown properly (code blocks, tables, links, etc.)
282
+ * Uses schema 2.0 format for proper markdown rendering.
279
283
  */
280
284
  export function buildMarkdownCard(text: string): Record<string, unknown> {
281
285
  return {
286
+ schema: "2.0",
282
287
  config: {
283
288
  wide_screen_mode: true,
284
289
  },
285
- elements: [
286
- {
287
- tag: "markdown",
288
- content: text,
289
- },
290
- ],
290
+ body: {
291
+ elements: [
292
+ {
293
+ tag: "markdown",
294
+ content: text,
295
+ },
296
+ ],
297
+ },
291
298
  };
292
299
  }
293
300
 
@@ -302,15 +309,16 @@ export async function sendMarkdownCardFeishu(params: {
302
309
  replyToMessageId?: string;
303
310
  /** Mention target users */
304
311
  mentions?: MentionTarget[];
312
+ accountId?: string;
305
313
  }): Promise<FeishuSendResult> {
306
- const { cfg, to, text, replyToMessageId, mentions } = params;
314
+ const { cfg, to, text, replyToMessageId, mentions, accountId } = params;
307
315
  // Build message content (with @mention support)
308
316
  let cardText = text;
309
317
  if (mentions && mentions.length > 0) {
310
318
  cardText = buildMentionedCardContent(mentions, text);
311
319
  }
312
320
  const card = buildMarkdownCard(cardText);
313
- return sendCardFeishu({ cfg, to, card, replyToMessageId });
321
+ return sendCardFeishu({ cfg, to, card, replyToMessageId, accountId });
314
322
  }
315
323
 
316
324
  /**
@@ -321,24 +329,22 @@ export async function editMessageFeishu(params: {
321
329
  cfg: ClawdbotConfig;
322
330
  messageId: string;
323
331
  text: string;
332
+ accountId?: string;
324
333
  }): Promise<void> {
325
- const { cfg, messageId, text } = params;
326
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
327
- if (!feishuCfg) {
328
- throw new Error("Feishu channel not configured");
334
+ const { cfg, messageId, text, accountId } = params;
335
+ const account = resolveFeishuAccount({ cfg, accountId });
336
+ if (!account.configured) {
337
+ throw new Error(`Feishu account "${account.accountId}" not configured`);
329
338
  }
330
339
 
331
- const client = createFeishuClient(feishuCfg);
340
+ const client = createFeishuClient(account);
332
341
  const tableMode = getFeishuRuntime().channel.text.resolveMarkdownTableMode({
333
342
  cfg,
334
343
  channel: "feishu",
335
344
  });
336
345
  const messageText = getFeishuRuntime().channel.text.convertMarkdownTables(text ?? "", tableMode);
337
346
 
338
- const { content, msgType } = buildFeishuPostMessagePayload({
339
- feishuCfg,
340
- messageText,
341
- });
347
+ const { content, msgType } = buildFeishuPostMessagePayload({ messageText });
342
348
 
343
349
  const response = await client.im.message.update({
344
350
  path: { message_id: messageId },
package/src/types.ts CHANGED
@@ -1,18 +1,25 @@
1
- import type { FeishuConfigSchema, FeishuGroupSchema, z } from "./config-schema.js";
1
+ import type { FeishuConfigSchema, FeishuGroupSchema, FeishuAccountConfigSchema, z } from "./config-schema.js";
2
2
  import type { MentionTarget } from "./mention.js";
3
3
 
4
4
  export type FeishuConfig = z.infer<typeof FeishuConfigSchema>;
5
5
  export type FeishuGroupConfig = z.infer<typeof FeishuGroupSchema>;
6
+ export type FeishuAccountConfig = z.infer<typeof FeishuAccountConfigSchema>;
6
7
 
7
- export type FeishuDomain = "feishu" | "lark";
8
+ export type FeishuDomain = "feishu" | "lark" | (string & {});
8
9
  export type FeishuConnectionMode = "websocket" | "webhook";
9
10
 
10
11
  export type ResolvedFeishuAccount = {
11
12
  accountId: string;
12
13
  enabled: boolean;
13
14
  configured: boolean;
15
+ name?: string;
14
16
  appId?: string;
17
+ appSecret?: string;
18
+ encryptKey?: string;
19
+ verificationToken?: string;
15
20
  domain: FeishuDomain;
21
+ /** Merged config (top-level defaults + account-specific overrides) */
22
+ config: FeishuConfig;
16
23
  };
17
24
 
18
25
  export type FeishuIdType = "open_id" | "user_id" | "union_id" | "chat_id";
@@ -61,3 +68,10 @@ export type FeishuToolsConfig = {
61
68
  perm?: boolean;
62
69
  scopes?: boolean;
63
70
  };
71
+
72
+ export type DynamicAgentCreationConfig = {
73
+ enabled?: boolean;
74
+ workspaceTemplate?: string;
75
+ agentDirTemplate?: string;
76
+ maxAgents?: number;
77
+ };
package/src/typing.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ClawdbotConfig } from "openclaw/plugin-sdk";
2
- import type { FeishuConfig } from "./types.js";
3
2
  import { createFeishuClient } from "./client.js";
3
+ import { resolveFeishuAccount } from "./accounts.js";
4
4
 
5
5
  // Feishu emoji types for typing indicator
6
6
  // See: https://open.feishu.cn/document/server-docs/im-v1/message-reaction/emojis-introduce
@@ -18,14 +18,15 @@ export type TypingIndicatorState = {
18
18
  export async function addTypingIndicator(params: {
19
19
  cfg: ClawdbotConfig;
20
20
  messageId: string;
21
+ accountId?: string;
21
22
  }): Promise<TypingIndicatorState> {
22
- const { cfg, messageId } = params;
23
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
24
- if (!feishuCfg) {
23
+ const { cfg, messageId, accountId } = params;
24
+ const account = resolveFeishuAccount({ cfg, accountId });
25
+ if (!account.configured) {
25
26
  return { messageId, reactionId: null };
26
27
  }
27
28
 
28
- const client = createFeishuClient(feishuCfg);
29
+ const client = createFeishuClient(account);
29
30
 
30
31
  try {
31
32
  const response = await client.im.messageReaction.create({
@@ -50,14 +51,15 @@ export async function addTypingIndicator(params: {
50
51
  export async function removeTypingIndicator(params: {
51
52
  cfg: ClawdbotConfig;
52
53
  state: TypingIndicatorState;
54
+ accountId?: string;
53
55
  }): Promise<void> {
54
- const { cfg, state } = params;
56
+ const { cfg, state, accountId } = params;
55
57
  if (!state.reactionId) return;
56
58
 
57
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
58
- if (!feishuCfg) return;
59
+ const account = resolveFeishuAccount({ cfg, accountId });
60
+ if (!account.configured) return;
59
61
 
60
- const client = createFeishuClient(feishuCfg);
62
+ const client = createFeishuClient(account);
61
63
 
62
64
  try {
63
65
  await client.im.messageReaction.delete({
package/src/wiki.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
2
  import { createFeishuClient } from "./client.js";
3
- import type { FeishuConfig } from "./types.js";
3
+ import { listEnabledFeishuAccounts } from "./accounts.js";
4
4
  import type * as Lark from "@larksuiteoapi/node-sdk";
5
5
  import { FeishuWikiSchema, type FeishuWikiParams } from "./wiki-schema.js";
6
6
  import { resolveToolsConfig } from "./tools-config.js";
@@ -150,19 +150,25 @@ async function renameNode(
150
150
  // ============ Tool Registration ============
151
151
 
152
152
  export function registerFeishuWikiTools(api: OpenClawPluginApi) {
153
- const feishuCfg = api.config?.channels?.feishu as FeishuConfig | undefined;
154
- if (!feishuCfg?.appId || !feishuCfg?.appSecret) {
155
- api.logger.debug?.("feishu_wiki: Feishu credentials not configured, skipping wiki tools");
153
+ if (!api.config) {
154
+ api.logger.debug?.("feishu_wiki: No config available, skipping wiki tools");
156
155
  return;
157
156
  }
158
157
 
159
- const toolsCfg = resolveToolsConfig(feishuCfg.tools);
158
+ const accounts = listEnabledFeishuAccounts(api.config);
159
+ if (accounts.length === 0) {
160
+ api.logger.debug?.("feishu_wiki: No Feishu accounts configured, skipping wiki tools");
161
+ return;
162
+ }
163
+
164
+ const firstAccount = accounts[0];
165
+ const toolsCfg = resolveToolsConfig(firstAccount.config.tools);
160
166
  if (!toolsCfg.wiki) {
161
167
  api.logger.debug?.("feishu_wiki: wiki tool disabled in config");
162
168
  return;
163
169
  }
164
170
 
165
- const getClient = () => createFeishuClient(feishuCfg);
171
+ const getClient = () => createFeishuClient(firstAccount);
166
172
 
167
173
  api.registerTool(
168
174
  {