fix: route feishu doc tools by agent account context (#27338) (thanks @AaronL725)

This commit is contained in:
Peter Steinberger
2026-02-26 13:00:15 +01:00
parent 58c100f66f
commit 39b5ffdaa6
5 changed files with 136 additions and 73 deletions

View File

@@ -460,53 +460,83 @@ export function registerFeishuDocTools(api: OpenClawPluginApi) {
const toolsCfg = resolveToolsConfig(firstAccount.config.tools);
const registered: string[] = [];
type FeishuDocExecuteParams = FeishuDocParams & { accountId?: string };
const resolveAccount = (params: FeishuDocParams) =>
resolveFeishuAccount({ cfg: api.config!, accountId: (params as any).accountId });
const resolveAccount = (
params: { accountId?: string } | undefined,
defaultAccountId: string | undefined,
) => {
const accountId =
typeof params?.accountId === "string" && params.accountId.trim().length > 0
? params.accountId.trim()
: defaultAccountId;
return resolveFeishuAccount({ cfg: api.config!, accountId });
};
const getClient = (params: FeishuDocParams) => createFeishuClient(resolveAccount(params));
const getClient = (params: { accountId?: string } | undefined, defaultAccountId?: string) =>
createFeishuClient(resolveAccount(params, defaultAccountId));
const getMediaMaxBytes = (params: FeishuDocParams) =>
(resolveAccount(params).config?.mediaMaxMb ?? 30) * 1024 * 1024;
const getMediaMaxBytes = (
params: { accountId?: string } | undefined,
defaultAccountId?: string,
) => (resolveAccount(params, defaultAccountId).config?.mediaMaxMb ?? 30) * 1024 * 1024;
// Main document tool with action-based dispatch
if (toolsCfg.doc) {
api.registerTool(
{
name: "feishu_doc",
label: "Feishu Doc",
description:
"Feishu document operations. Actions: read, write, append, create, list_blocks, get_block, update_block, delete_block",
parameters: FeishuDocSchema,
async execute(_toolCallId, params) {
const p = params as FeishuDocParams;
try {
const client = getClient(p);
switch (p.action) {
case "read":
return json(await readDoc(client, p.doc_token));
case "write":
return json(await writeDoc(client, p.doc_token, p.content, getMediaMaxBytes(p)));
case "append":
return json(await appendDoc(client, p.doc_token, p.content, getMediaMaxBytes(p)));
case "create":
return json(await createDoc(client, p.title, p.folder_token));
case "list_blocks":
return json(await listBlocks(client, p.doc_token));
case "get_block":
return json(await getBlock(client, p.doc_token, p.block_id));
case "update_block":
return json(await updateBlock(client, p.doc_token, p.block_id, p.content));
case "delete_block":
return json(await deleteBlock(client, p.doc_token, p.block_id));
default:
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- exhaustive check fallback
return json({ error: `Unknown action: ${(p as any).action}` });
(ctx) => {
const defaultAccountId = ctx.agentAccountId;
return {
name: "feishu_doc",
label: "Feishu Doc",
description:
"Feishu document operations. Actions: read, write, append, create, list_blocks, get_block, update_block, delete_block",
parameters: FeishuDocSchema,
async execute(_toolCallId, params) {
const p = params as FeishuDocExecuteParams;
try {
const client = getClient(p, defaultAccountId);
switch (p.action) {
case "read":
return json(await readDoc(client, p.doc_token));
case "write":
return json(
await writeDoc(
client,
p.doc_token,
p.content,
getMediaMaxBytes(p, defaultAccountId),
),
);
case "append":
return json(
await appendDoc(
client,
p.doc_token,
p.content,
getMediaMaxBytes(p, defaultAccountId),
),
);
case "create":
return json(await createDoc(client, p.title, p.folder_token));
case "list_blocks":
return json(await listBlocks(client, p.doc_token));
case "get_block":
return json(await getBlock(client, p.doc_token, p.block_id));
case "update_block":
return json(await updateBlock(client, p.doc_token, p.block_id, p.content));
case "delete_block":
return json(await deleteBlock(client, p.doc_token, p.block_id));
default: {
const exhaustiveCheck: never = p;
return json({ error: `Unknown action: ${String(exhaustiveCheck)}` });
}
}
} catch (err) {
return json({ error: err instanceof Error ? err.message : String(err) });
}
} catch (err) {
return json({ error: err instanceof Error ? err.message : String(err) });
}
},
},
};
},
{ name: "feishu_doc" },
);
@@ -516,7 +546,7 @@ export function registerFeishuDocTools(api: OpenClawPluginApi) {
// Keep feishu_app_scopes as independent tool
if (toolsCfg.scopes) {
api.registerTool(
{
(ctx) => ({
name: "feishu_app_scopes",
label: "Feishu App Scopes",
description:
@@ -524,13 +554,13 @@ export function registerFeishuDocTools(api: OpenClawPluginApi) {
parameters: Type.Object({}),
async execute() {
try {
const result = await listAppScopes(getClient({ action: "create", title: "" } as any));
const result = await listAppScopes(getClient(undefined, ctx.agentAccountId));
return json(result);
} catch (err) {
return json({ error: err instanceof Error ? err.message : String(err) });
}
},
},
}),
{ name: "feishu_app_scopes" },
);
registered.push("feishu_app_scopes");