@larksuite/openclaw-lark 2025.7.15-beta.0
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/LICENSE +21 -0
- package/README.md +76 -0
- package/bin/openclaw-lark.js +39 -0
- package/index.d.ts +36 -0
- package/index.js +188 -0
- package/openclaw.plugin.json +64 -0
- package/package.json +63 -0
- package/secret-contract-api.d.ts +15 -0
- package/secret-contract-api.js +78 -0
- package/skills/feishu-bitable/SKILL.md +248 -0
- package/skills/feishu-bitable/references/examples.md +813 -0
- package/skills/feishu-bitable/references/field-properties.md +763 -0
- package/skills/feishu-bitable/references/record-values.md +911 -0
- package/skills/feishu-calendar/SKILL.md +242 -0
- package/skills/feishu-channel-rules/SKILL.md +18 -0
- package/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
- package/skills/feishu-create-doc/SKILL.md +719 -0
- package/skills/feishu-fetch-doc/SKILL.md +93 -0
- package/skills/feishu-im-read/SKILL.md +163 -0
- package/skills/feishu-task/SKILL.md +340 -0
- package/skills/feishu-troubleshoot/SKILL.md +70 -0
- package/skills/feishu-update-doc/SKILL.md +285 -0
- package/src/card/builder.d.ts +152 -0
- package/src/card/builder.js +794 -0
- package/src/card/card-error.d.ts +91 -0
- package/src/card/card-error.js +206 -0
- package/src/card/cardkit.d.ts +90 -0
- package/src/card/cardkit.js +203 -0
- package/src/card/flush-controller.d.ts +45 -0
- package/src/card/flush-controller.js +138 -0
- package/src/card/image-resolver.d.ts +45 -0
- package/src/card/image-resolver.js +116 -0
- package/src/card/markdown-style.d.ts +16 -0
- package/src/card/markdown-style.js +106 -0
- package/src/card/reasoning-utils.d.ts +14 -0
- package/src/card/reasoning-utils.js +64 -0
- package/src/card/reply-dispatcher-types.d.ts +132 -0
- package/src/card/reply-dispatcher-types.js +61 -0
- package/src/card/reply-dispatcher.d.ts +15 -0
- package/src/card/reply-dispatcher.js +447 -0
- package/src/card/reply-mode.d.ts +41 -0
- package/src/card/reply-mode.js +70 -0
- package/src/card/streaming-card-controller.d.ts +118 -0
- package/src/card/streaming-card-controller.js +1045 -0
- package/src/card/tool-use-config.d.ts +26 -0
- package/src/card/tool-use-config.js +76 -0
- package/src/card/tool-use-display.d.ts +37 -0
- package/src/card/tool-use-display.js +476 -0
- package/src/card/tool-use-trace-store.d.ts +51 -0
- package/src/card/tool-use-trace-store.js +271 -0
- package/src/card/unavailable-guard.d.ts +35 -0
- package/src/card/unavailable-guard.js +87 -0
- package/src/channel/abort-detect.d.ts +47 -0
- package/src/channel/abort-detect.js +219 -0
- package/src/channel/chat-queue.d.ts +41 -0
- package/src/channel/chat-queue.js +68 -0
- package/src/channel/config-adapter.d.ts +23 -0
- package/src/channel/config-adapter.js +107 -0
- package/src/channel/directory.d.ts +57 -0
- package/src/channel/directory.js +197 -0
- package/src/channel/event-handlers.d.ts +17 -0
- package/src/channel/event-handlers.js +380 -0
- package/src/channel/interactive-dispatch.d.ts +59 -0
- package/src/channel/interactive-dispatch.js +195 -0
- package/src/channel/monitor.d.ts +17 -0
- package/src/channel/monitor.js +140 -0
- package/src/channel/onboarding-config.d.ts +18 -0
- package/src/channel/onboarding-config.js +96 -0
- package/src/channel/onboarding-migrate.d.ts +25 -0
- package/src/channel/onboarding-migrate.js +70 -0
- package/src/channel/onboarding.d.ts +12 -0
- package/src/channel/onboarding.js +300 -0
- package/src/channel/plugin.d.ts +13 -0
- package/src/channel/plugin.js +310 -0
- package/src/channel/probe.d.ts +14 -0
- package/src/channel/probe.js +24 -0
- package/src/channel/types.d.ts +37 -0
- package/src/channel/types.js +8 -0
- package/src/commands/auth.d.ts +21 -0
- package/src/commands/auth.js +165 -0
- package/src/commands/diagnose.d.ts +69 -0
- package/src/commands/diagnose.js +848 -0
- package/src/commands/doctor.d.ts +27 -0
- package/src/commands/doctor.js +588 -0
- package/src/commands/index.d.ts +25 -0
- package/src/commands/index.js +219 -0
- package/src/commands/locale.d.ts +7 -0
- package/src/commands/locale.js +8 -0
- package/src/core/accounts.d.ts +51 -0
- package/src/core/accounts.js +219 -0
- package/src/core/agent-config.d.ts +100 -0
- package/src/core/agent-config.js +148 -0
- package/src/core/api-error.d.ts +48 -0
- package/src/core/api-error.js +117 -0
- package/src/core/app-owner-fallback.d.ts +22 -0
- package/src/core/app-owner-fallback.js +39 -0
- package/src/core/app-scope-checker.d.ts +87 -0
- package/src/core/app-scope-checker.js +198 -0
- package/src/core/auth-errors.d.ts +144 -0
- package/src/core/auth-errors.js +160 -0
- package/src/core/card-action-operator.d.ts +33 -0
- package/src/core/card-action-operator.js +30 -0
- package/src/core/chat-info-cache.d.ts +67 -0
- package/src/core/chat-info-cache.js +165 -0
- package/src/core/comment-target.d.ts +65 -0
- package/src/core/comment-target.js +100 -0
- package/src/core/config-schema.d.ts +490 -0
- package/src/core/config-schema.js +223 -0
- package/src/core/device-flow.d.ts +77 -0
- package/src/core/device-flow.js +217 -0
- package/src/core/domains.d.ts +18 -0
- package/src/core/domains.js +34 -0
- package/src/core/feishu-fetch.d.ts +18 -0
- package/src/core/feishu-fetch.js +28 -0
- package/src/core/footer-config.d.ts +24 -0
- package/src/core/footer-config.js +51 -0
- package/src/core/lark-client.d.ts +125 -0
- package/src/core/lark-client.js +468 -0
- package/src/core/lark-logger.d.ts +23 -0
- package/src/core/lark-logger.js +160 -0
- package/src/core/lark-ticket.d.ts +29 -0
- package/src/core/lark-ticket.js +40 -0
- package/src/core/message-unavailable.d.ts +53 -0
- package/src/core/message-unavailable.js +142 -0
- package/src/core/owner-policy.d.ts +32 -0
- package/src/core/owner-policy.js +55 -0
- package/src/core/permission-url.d.ts +22 -0
- package/src/core/permission-url.js +76 -0
- package/src/core/raw-request.d.ts +27 -0
- package/src/core/raw-request.js +90 -0
- package/src/core/runtime-store.d.ts +13 -0
- package/src/core/runtime-store.js +29 -0
- package/src/core/scope-manager.d.ts +168 -0
- package/src/core/scope-manager.js +224 -0
- package/src/core/sdk-compat.d.ts +20 -0
- package/src/core/sdk-compat.js +28 -0
- package/src/core/security-check.d.ts +72 -0
- package/src/core/security-check.js +184 -0
- package/src/core/shutdown-hooks.d.ts +22 -0
- package/src/core/shutdown-hooks.js +61 -0
- package/src/core/synthetic-target.d.ts +33 -0
- package/src/core/synthetic-target.js +40 -0
- package/src/core/targets.d.ts +60 -0
- package/src/core/targets.js +173 -0
- package/src/core/token-store.d.ts +54 -0
- package/src/core/token-store.js +326 -0
- package/src/core/tool-client.d.ts +176 -0
- package/src/core/tool-client.js +426 -0
- package/src/core/tool-scopes.d.ts +156 -0
- package/src/core/tool-scopes.js +344 -0
- package/src/core/tools-config.d.ts +55 -0
- package/src/core/tools-config.js +143 -0
- package/src/core/types.d.ts +91 -0
- package/src/core/types.js +12 -0
- package/src/core/uat-client.d.ts +46 -0
- package/src/core/uat-client.js +192 -0
- package/src/core/version.d.ts +31 -0
- package/src/core/version.js +69 -0
- package/src/messaging/converters/audio.d.ts +8 -0
- package/src/messaging/converters/audio.js +24 -0
- package/src/messaging/converters/calendar.d.ts +13 -0
- package/src/messaging/converters/calendar.js +56 -0
- package/src/messaging/converters/content-converter-helpers.d.ts +30 -0
- package/src/messaging/converters/content-converter-helpers.js +82 -0
- package/src/messaging/converters/content-converter.d.ts +24 -0
- package/src/messaging/converters/content-converter.js +40 -0
- package/src/messaging/converters/file.d.ts +8 -0
- package/src/messaging/converters/file.js +24 -0
- package/src/messaging/converters/folder.d.ts +8 -0
- package/src/messaging/converters/folder.js +24 -0
- package/src/messaging/converters/hongbao.d.ts +8 -0
- package/src/messaging/converters/hongbao.js +20 -0
- package/src/messaging/converters/image.d.ts +8 -0
- package/src/messaging/converters/image.js +22 -0
- package/src/messaging/converters/index.d.ts +8 -0
- package/src/messaging/converters/index.js +53 -0
- package/src/messaging/converters/interactive/card-converter.d.ts +76 -0
- package/src/messaging/converters/interactive/card-converter.js +1177 -0
- package/src/messaging/converters/interactive/card-utils.d.ts +9 -0
- package/src/messaging/converters/interactive/card-utils.js +47 -0
- package/src/messaging/converters/interactive/index.d.ts +8 -0
- package/src/messaging/converters/interactive/index.js +25 -0
- package/src/messaging/converters/interactive/legacy.d.ts +11 -0
- package/src/messaging/converters/interactive/legacy.js +60 -0
- package/src/messaging/converters/interactive/types.d.ts +23 -0
- package/src/messaging/converters/interactive/types.js +27 -0
- package/src/messaging/converters/location.d.ts +8 -0
- package/src/messaging/converters/location.js +23 -0
- package/src/messaging/converters/merge-forward.d.ts +32 -0
- package/src/messaging/converters/merge-forward.js +235 -0
- package/src/messaging/converters/post.d.ts +11 -0
- package/src/messaging/converters/post.js +235 -0
- package/src/messaging/converters/share.d.ts +9 -0
- package/src/messaging/converters/share.js +28 -0
- package/src/messaging/converters/sticker.d.ts +8 -0
- package/src/messaging/converters/sticker.js +22 -0
- package/src/messaging/converters/system.d.ts +12 -0
- package/src/messaging/converters/system.js +36 -0
- package/src/messaging/converters/text.d.ts +8 -0
- package/src/messaging/converters/text.js +18 -0
- package/src/messaging/converters/todo.d.ts +8 -0
- package/src/messaging/converters/todo.js +45 -0
- package/src/messaging/converters/types.d.ts +114 -0
- package/src/messaging/converters/types.js +8 -0
- package/src/messaging/converters/unknown.d.ts +8 -0
- package/src/messaging/converters/unknown.js +20 -0
- package/src/messaging/converters/utils.d.ts +22 -0
- package/src/messaging/converters/utils.js +57 -0
- package/src/messaging/converters/video-chat.d.ts +8 -0
- package/src/messaging/converters/video-chat.js +31 -0
- package/src/messaging/converters/video.d.ts +8 -0
- package/src/messaging/converters/video.js +35 -0
- package/src/messaging/converters/vote.d.ts +8 -0
- package/src/messaging/converters/vote.js +28 -0
- package/src/messaging/inbound/bot-content.d.ts +84 -0
- package/src/messaging/inbound/bot-content.js +117 -0
- package/src/messaging/inbound/bot-loop-guard.d.ts +48 -0
- package/src/messaging/inbound/bot-loop-guard.js +89 -0
- package/src/messaging/inbound/comment-context.d.ts +82 -0
- package/src/messaging/inbound/comment-context.js +353 -0
- package/src/messaging/inbound/comment-handler.d.ts +30 -0
- package/src/messaging/inbound/comment-handler.js +269 -0
- package/src/messaging/inbound/dedup.d.ts +59 -0
- package/src/messaging/inbound/dedup.js +121 -0
- package/src/messaging/inbound/dispatch-builders.d.ts +104 -0
- package/src/messaging/inbound/dispatch-builders.js +241 -0
- package/src/messaging/inbound/dispatch-commands.d.ts +22 -0
- package/src/messaging/inbound/dispatch-commands.js +131 -0
- package/src/messaging/inbound/dispatch-context.d.ts +67 -0
- package/src/messaging/inbound/dispatch-context.js +153 -0
- package/src/messaging/inbound/dispatch.d.ts +50 -0
- package/src/messaging/inbound/dispatch.js +477 -0
- package/src/messaging/inbound/enrich.d.ts +102 -0
- package/src/messaging/inbound/enrich.js +236 -0
- package/src/messaging/inbound/gate-effects.d.ts +23 -0
- package/src/messaging/inbound/gate-effects.js +46 -0
- package/src/messaging/inbound/gate.d.ts +91 -0
- package/src/messaging/inbound/gate.js +342 -0
- package/src/messaging/inbound/handler-registry.d.ts +25 -0
- package/src/messaging/inbound/handler-registry.js +23 -0
- package/src/messaging/inbound/handler.d.ts +37 -0
- package/src/messaging/inbound/handler.js +286 -0
- package/src/messaging/inbound/media-resolver.d.ts +32 -0
- package/src/messaging/inbound/media-resolver.js +91 -0
- package/src/messaging/inbound/mention-registry.d.ts +59 -0
- package/src/messaging/inbound/mention-registry.js +115 -0
- package/src/messaging/inbound/mention.d.ts +48 -0
- package/src/messaging/inbound/mention.js +102 -0
- package/src/messaging/inbound/parse-io.d.ts +50 -0
- package/src/messaging/inbound/parse-io.js +86 -0
- package/src/messaging/inbound/parse.d.ts +28 -0
- package/src/messaging/inbound/parse.js +128 -0
- package/src/messaging/inbound/permission.d.ts +17 -0
- package/src/messaging/inbound/permission.js +44 -0
- package/src/messaging/inbound/policy.d.ts +95 -0
- package/src/messaging/inbound/policy.js +168 -0
- package/src/messaging/inbound/reaction-handler.d.ts +62 -0
- package/src/messaging/inbound/reaction-handler.js +259 -0
- package/src/messaging/inbound/sentinel-store.d.ts +37 -0
- package/src/messaging/inbound/sentinel-store.js +98 -0
- package/src/messaging/inbound/synthetic-message.d.ts +26 -0
- package/src/messaging/inbound/synthetic-message.js +59 -0
- package/src/messaging/inbound/user-name-cache-store.d.ts +62 -0
- package/src/messaging/inbound/user-name-cache-store.js +236 -0
- package/src/messaging/inbound/user-name-cache.d.ts +78 -0
- package/src/messaging/inbound/user-name-cache.js +306 -0
- package/src/messaging/inbound/vc-meeting-invited-handler.d.ts +20 -0
- package/src/messaging/inbound/vc-meeting-invited-handler.js +236 -0
- package/src/messaging/inbound/vc-sender.d.ts +41 -0
- package/src/messaging/inbound/vc-sender.js +53 -0
- package/src/messaging/outbound/actions.d.ts +16 -0
- package/src/messaging/outbound/actions.js +329 -0
- package/src/messaging/outbound/bot-peer-context.d.ts +42 -0
- package/src/messaging/outbound/bot-peer-context.js +40 -0
- package/src/messaging/outbound/chat-manage.d.ts +64 -0
- package/src/messaging/outbound/chat-manage.js +117 -0
- package/src/messaging/outbound/deliver.d.ts +186 -0
- package/src/messaging/outbound/deliver.js +410 -0
- package/src/messaging/outbound/fetch.d.ts +12 -0
- package/src/messaging/outbound/fetch.js +17 -0
- package/src/messaging/outbound/forward.d.ts +26 -0
- package/src/messaging/outbound/forward.js +51 -0
- package/src/messaging/outbound/media-url-utils.d.ts +29 -0
- package/src/messaging/outbound/media-url-utils.js +172 -0
- package/src/messaging/outbound/media.d.ts +260 -0
- package/src/messaging/outbound/media.js +865 -0
- package/src/messaging/outbound/normalize-mentions.d.ts +50 -0
- package/src/messaging/outbound/normalize-mentions.js +166 -0
- package/src/messaging/outbound/outbound-mention.d.ts +41 -0
- package/src/messaging/outbound/outbound-mention.js +112 -0
- package/src/messaging/outbound/outbound.d.ts +79 -0
- package/src/messaging/outbound/outbound.js +195 -0
- package/src/messaging/outbound/reactions.d.ts +124 -0
- package/src/messaging/outbound/reactions.js +384 -0
- package/src/messaging/outbound/send.d.ts +153 -0
- package/src/messaging/outbound/send.js +417 -0
- package/src/messaging/outbound/typing.d.ts +60 -0
- package/src/messaging/outbound/typing.js +139 -0
- package/src/messaging/shared/message-lookup.d.ts +54 -0
- package/src/messaging/shared/message-lookup.js +120 -0
- package/src/messaging/types.d.ts +316 -0
- package/src/messaging/types.js +11 -0
- package/src/tools/ask-user-question.d.ts +32 -0
- package/src/tools/ask-user-question.js +922 -0
- package/src/tools/auto-auth.d.ts +57 -0
- package/src/tools/auto-auth.js +904 -0
- package/src/tools/helpers.d.ts +264 -0
- package/src/tools/helpers.js +389 -0
- package/src/tools/mcp/doc/create.d.ts +12 -0
- package/src/tools/mcp/doc/create.js +47 -0
- package/src/tools/mcp/doc/fetch.d.ts +12 -0
- package/src/tools/mcp/doc/fetch.js +39 -0
- package/src/tools/mcp/doc/index.d.ts +12 -0
- package/src/tools/mcp/doc/index.js +50 -0
- package/src/tools/mcp/doc/update.d.ts +12 -0
- package/src/tools/mcp/doc/update.js +64 -0
- package/src/tools/mcp/shared.d.ts +59 -0
- package/src/tools/mcp/shared.js +239 -0
- package/src/tools/oapi/bitable/app-table-field.d.ts +16 -0
- package/src/tools/oapi/bitable/app-table-field.js +225 -0
- package/src/tools/oapi/bitable/app-table-record.d.ts +20 -0
- package/src/tools/oapi/bitable/app-table-record.js +439 -0
- package/src/tools/oapi/bitable/app-table-view.d.ts +16 -0
- package/src/tools/oapi/bitable/app-table-view.js +172 -0
- package/src/tools/oapi/bitable/app-table.d.ts +17 -0
- package/src/tools/oapi/bitable/app-table.js +195 -0
- package/src/tools/oapi/bitable/app.d.ts +18 -0
- package/src/tools/oapi/bitable/app.js +189 -0
- package/src/tools/oapi/bitable/index.d.ts +9 -0
- package/src/tools/oapi/bitable/index.js +17 -0
- package/src/tools/oapi/calendar/calendar.d.ts +15 -0
- package/src/tools/oapi/calendar/calendar.js +125 -0
- package/src/tools/oapi/calendar/event-attendee.d.ts +14 -0
- package/src/tools/oapi/calendar/event-attendee.js +161 -0
- package/src/tools/oapi/calendar/event.d.ts +16 -0
- package/src/tools/oapi/calendar/event.js +712 -0
- package/src/tools/oapi/calendar/freebusy.d.ts +13 -0
- package/src/tools/oapi/calendar/freebusy.js +114 -0
- package/src/tools/oapi/calendar/index.d.ts +8 -0
- package/src/tools/oapi/calendar/index.js +15 -0
- package/src/tools/oapi/chat/chat.d.ts +16 -0
- package/src/tools/oapi/chat/chat.js +127 -0
- package/src/tools/oapi/chat/index.d.ts +10 -0
- package/src/tools/oapi/chat/index.js +23 -0
- package/src/tools/oapi/chat/members.d.ts +11 -0
- package/src/tools/oapi/chat/members.js +84 -0
- package/src/tools/oapi/common/get-user.d.ts +12 -0
- package/src/tools/oapi/common/get-user.js +109 -0
- package/src/tools/oapi/common/index.d.ts +6 -0
- package/src/tools/oapi/common/index.js +11 -0
- package/src/tools/oapi/common/search-user.d.ts +11 -0
- package/src/tools/oapi/common/search-user.js +76 -0
- package/src/tools/oapi/drive/doc-comments.d.ts +15 -0
- package/src/tools/oapi/drive/doc-comments.js +351 -0
- package/src/tools/oapi/drive/doc-media.d.ts +19 -0
- package/src/tools/oapi/drive/doc-media.js +371 -0
- package/src/tools/oapi/drive/file.d.ts +19 -0
- package/src/tools/oapi/drive/file.js +519 -0
- package/src/tools/oapi/drive/index.d.ts +12 -0
- package/src/tools/oapi/drive/index.js +45 -0
- package/src/tools/oapi/helpers.d.ts +183 -0
- package/src/tools/oapi/helpers.js +385 -0
- package/src/tools/oapi/im/format-messages.d.ts +50 -0
- package/src/tools/oapi/im/format-messages.js +169 -0
- package/src/tools/oapi/im/index.d.ts +10 -0
- package/src/tools/oapi/im/index.js +25 -0
- package/src/tools/oapi/im/message-read.d.ts +13 -0
- package/src/tools/oapi/im/message-read.js +419 -0
- package/src/tools/oapi/im/message.d.ts +16 -0
- package/src/tools/oapi/im/message.js +152 -0
- package/src/tools/oapi/im/resource.d.ts +13 -0
- package/src/tools/oapi/im/resource.js +186 -0
- package/src/tools/oapi/im/time-utils.d.ts +46 -0
- package/src/tools/oapi/im/time-utils.js +212 -0
- package/src/tools/oapi/im/user-name-uat.d.ts +26 -0
- package/src/tools/oapi/im/user-name-uat.js +143 -0
- package/src/tools/oapi/index.d.ts +11 -0
- package/src/tools/oapi/index.js +64 -0
- package/src/tools/oapi/sdk-types.d.ts +96 -0
- package/src/tools/oapi/sdk-types.js +13 -0
- package/src/tools/oapi/search/doc-search.d.ts +13 -0
- package/src/tools/oapi/search/doc-search.js +194 -0
- package/src/tools/oapi/search/index.d.ts +12 -0
- package/src/tools/oapi/search/index.js +37 -0
- package/src/tools/oapi/sheets/index.d.ts +12 -0
- package/src/tools/oapi/sheets/index.js +35 -0
- package/src/tools/oapi/sheets/sheet.d.ts +16 -0
- package/src/tools/oapi/sheets/sheet.js +688 -0
- package/src/tools/oapi/task/attachment.d.ts +18 -0
- package/src/tools/oapi/task/attachment.js +107 -0
- package/src/tools/oapi/task/comment.d.ts +15 -0
- package/src/tools/oapi/task/comment.js +149 -0
- package/src/tools/oapi/task/index.d.ts +11 -0
- package/src/tools/oapi/task/index.js +21 -0
- package/src/tools/oapi/task/section.d.ts +17 -0
- package/src/tools/oapi/task/section.js +293 -0
- package/src/tools/oapi/task/subtask.d.ts +14 -0
- package/src/tools/oapi/task/subtask.js +171 -0
- package/src/tools/oapi/task/task.d.ts +19 -0
- package/src/tools/oapi/task/task.js +512 -0
- package/src/tools/oapi/task/task_agent.d.ts +14 -0
- package/src/tools/oapi/task/task_agent.js +108 -0
- package/src/tools/oapi/task/tasklist.d.ts +19 -0
- package/src/tools/oapi/task/tasklist.js +276 -0
- package/src/tools/oapi/wiki/index.d.ts +12 -0
- package/src/tools/oapi/wiki/index.js +42 -0
- package/src/tools/oapi/wiki/space-node.d.ts +17 -0
- package/src/tools/oapi/wiki/space-node.js +233 -0
- package/src/tools/oapi/wiki/space.d.ts +15 -0
- package/src/tools/oapi/wiki/space.js +133 -0
- package/src/tools/oauth-batch-auth.d.ts +11 -0
- package/src/tools/oauth-batch-auth.js +150 -0
- package/src/tools/oauth-cards.d.ts +39 -0
- package/src/tools/oauth-cards.js +324 -0
- package/src/tools/oauth.d.ts +47 -0
- package/src/tools/oauth.js +592 -0
- package/src/tools/onboarding-auth.d.ts +27 -0
- package/src/tools/onboarding-auth.js +133 -0
- package/src/tools/tat/im/index.d.ts +15 -0
- package/src/tools/tat/im/index.js +22 -0
- package/src/tools/tat/im/resource.d.ts +15 -0
- package/src/tools/tat/im/resource.js +192 -0
- package/tsdown.config.d.ts +2 -0
- package/tsdown.config.js +25 -0
- package/vitest.config.d.ts +2 -0
- package/vitest.config.js +12 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* 飞书工具开发的通用辅助函数
|
|
6
|
+
*
|
|
7
|
+
* 提供所有工具通用的模式,减少重复代码。
|
|
8
|
+
*/
|
|
9
|
+
import type { ClawdbotConfig, OpenClawPluginApi } from 'openclaw/plugin-sdk';
|
|
10
|
+
import type { Client as LarkSdkClient } from '@larksuiteoapi/node-sdk';
|
|
11
|
+
import type { LarkAccount } from '../core/types';
|
|
12
|
+
import type { ToolClient } from '../core/tool-client';
|
|
13
|
+
/**
|
|
14
|
+
* 工具返回值的标准格式
|
|
15
|
+
*/
|
|
16
|
+
export interface ToolResult {
|
|
17
|
+
content: Array<{
|
|
18
|
+
type: 'text';
|
|
19
|
+
text: string;
|
|
20
|
+
}>;
|
|
21
|
+
details: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 客户端获取器函数类型
|
|
25
|
+
*/
|
|
26
|
+
export type ClientGetter = () => LarkSdkClient;
|
|
27
|
+
/**
|
|
28
|
+
* 工具日志记录器接口
|
|
29
|
+
*/
|
|
30
|
+
export interface ToolLogger {
|
|
31
|
+
info: (msg: string) => void;
|
|
32
|
+
warn: (msg: string) => void;
|
|
33
|
+
error: (msg: string) => void;
|
|
34
|
+
debug: (msg: string) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 工具上下文对象,包含所有常用的辅助工具
|
|
38
|
+
*/
|
|
39
|
+
export interface ToolContext {
|
|
40
|
+
/** @deprecated 使用 `toolClient().sdk` 代替 */
|
|
41
|
+
getClient: ClientGetter;
|
|
42
|
+
/** 获取当前请求对应的 {@link ToolClient} 实例 */
|
|
43
|
+
toolClient: () => ToolClient;
|
|
44
|
+
/** 工具日志记录器 */
|
|
45
|
+
log: ToolLogger;
|
|
46
|
+
}
|
|
47
|
+
export { getResolvedConfig } from '../core/lark-client';
|
|
48
|
+
/**
|
|
49
|
+
* 获取飞书客户端的标准模式
|
|
50
|
+
*
|
|
51
|
+
* 这是所有工具通用的逻辑:
|
|
52
|
+
* 1. 优先使用 LarkTicket 中的 accountId 动态解析账号
|
|
53
|
+
* 2. 如果没有 LarkTicket,回退到 accountIndex 指定的账号
|
|
54
|
+
* 3. 返回创建好的客户端实例
|
|
55
|
+
*
|
|
56
|
+
* @param config - OpenClaw 配置对象
|
|
57
|
+
* @param accountIndex - 使用第几个账号(默认 0,即第一个),仅在无 LarkTicket 时使用
|
|
58
|
+
* @returns 飞书 SDK 客户端实例
|
|
59
|
+
* @throws 如果没有启用的账号
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* export function registerMyTool(api: OpenClawPluginApi) {
|
|
64
|
+
* const getClient = createClientGetter(api.config);
|
|
65
|
+
*
|
|
66
|
+
* api.registerTool({
|
|
67
|
+
* name: "my_tool",
|
|
68
|
+
* async execute(_toolCallId, params) {
|
|
69
|
+
* const client = getClient();
|
|
70
|
+
* const res = await client.im.message.create({ ... });
|
|
71
|
+
* return formatToolResult(res.data);
|
|
72
|
+
* }
|
|
73
|
+
* });
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare function createClientGetter(config: ClawdbotConfig, accountIndex?: number): ClientGetter;
|
|
78
|
+
/**
|
|
79
|
+
* 获取当前请求对应的飞书账号信息
|
|
80
|
+
*
|
|
81
|
+
* 优先使用 LarkTicket 中的 accountId,回退到第一个启用的账号。
|
|
82
|
+
*
|
|
83
|
+
* @param config - OpenClaw 配置对象
|
|
84
|
+
* @returns 解析后的账号信息
|
|
85
|
+
* @throws 如果没有启用的账号
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const account = getFirstAccount(api.config);
|
|
90
|
+
* const client = LarkClient.fromAccount(account);
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare function getFirstAccount(config: ClawdbotConfig): LarkAccount;
|
|
94
|
+
/**
|
|
95
|
+
* 创建工具上下文,一次性返回所有常用的辅助工具
|
|
96
|
+
*
|
|
97
|
+
* 这是推荐的模式,避免在每个工具中重复调用 createClientGetter 和 createToolLogger。
|
|
98
|
+
*
|
|
99
|
+
* @param api - OpenClaw 插件 API
|
|
100
|
+
* @param toolName - 工具名称
|
|
101
|
+
* @param options - 可选配置
|
|
102
|
+
* @returns 工具上下文对象
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* export function registerMyTool(api: OpenClawPluginApi) {
|
|
107
|
+
* if (!api.config) return;
|
|
108
|
+
*
|
|
109
|
+
* const { toolClient, log } = createToolContext(api, "my_tool");
|
|
110
|
+
*
|
|
111
|
+
* api.registerTool({
|
|
112
|
+
* name: "my_tool",
|
|
113
|
+
* async execute(_toolCallId, params) {
|
|
114
|
+
* const client = getClient();
|
|
115
|
+
* log.info(`Processing action: ${params.action}`);
|
|
116
|
+
* const res = await client.im.message.create({ ... });
|
|
117
|
+
* return formatToolResult(res.data);
|
|
118
|
+
* }
|
|
119
|
+
* });
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare function createToolContext(api: OpenClawPluginApi, toolName: string, options?: {
|
|
124
|
+
/** 使用第几个账号(默认 0,即第一个) */
|
|
125
|
+
accountIndex?: number;
|
|
126
|
+
}): ToolContext;
|
|
127
|
+
/**
|
|
128
|
+
* 检查工具是否应该被注册(根据 channels.feishu.tools.deny 配置)。
|
|
129
|
+
*
|
|
130
|
+
* 在工具注册函数开头调用此函数,如果返回 `false` 则应该直接 return。
|
|
131
|
+
*
|
|
132
|
+
* @param api - OpenClaw Plugin API
|
|
133
|
+
* @param toolName - 工具名称
|
|
134
|
+
* @returns `true` 如果应该继续注册,`false` 如果应该跳过
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* export function registerMyTool(api: OpenClawPluginApi) {
|
|
139
|
+
* if (!checkToolRegistration(api, 'feishu_my_tool')) {
|
|
140
|
+
* return;
|
|
141
|
+
* }
|
|
142
|
+
*
|
|
143
|
+
* const { toolClient, log } = createToolContext(api, 'feishu_my_tool');
|
|
144
|
+
* api.registerTool({ ... });
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export declare function checkToolRegistration(api: OpenClawPluginApi, toolName: string): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* 包装的工具注册函数,自动检查 channels.feishu.tools.deny 配置。
|
|
151
|
+
*
|
|
152
|
+
* 用法:将 `api.registerTool(...)` 替换为 `registerTool(api, ...)`。
|
|
153
|
+
*
|
|
154
|
+
* @param api - OpenClaw Plugin API
|
|
155
|
+
* @param tool - 工具配置对象或工具工厂函数
|
|
156
|
+
* @param opts - 可选的工具注册选项
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* // 旧代码:
|
|
161
|
+
* api.registerTool({ name: 'feishu_my_tool', ... });
|
|
162
|
+
*
|
|
163
|
+
* // 新代码:
|
|
164
|
+
* registerTool(api, { name: 'feishu_my_tool', ... });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
export declare function registerTool(api: OpenClawPluginApi, tool: Parameters<OpenClawPluginApi['registerTool']>[0], opts?: Parameters<OpenClawPluginApi['registerTool']>[1]): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* 格式化工具返回值为 OpenClaw 期望的格式
|
|
170
|
+
*
|
|
171
|
+
* @param data - 要返回的数据(会被序列化为 JSON)
|
|
172
|
+
* @param options - 可选配置
|
|
173
|
+
* @returns OpenClaw 工具返回值格式
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* // 简单使用
|
|
178
|
+
* return formatToolResult({ success: true, user_id: "ou_xxx" });
|
|
179
|
+
*
|
|
180
|
+
* // 自定义 JSON 格式化
|
|
181
|
+
* return formatToolResult(data, { indent: 4 });
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
export declare function formatToolResult(data: unknown, options?: {
|
|
185
|
+
/** JSON 缩进空格数,默认 2 */
|
|
186
|
+
indent?: number;
|
|
187
|
+
}): ToolResult;
|
|
188
|
+
/**
|
|
189
|
+
* 格式化错误为工具返回值
|
|
190
|
+
*
|
|
191
|
+
* @param error - 错误对象或字符串
|
|
192
|
+
* @param context - 错误上下文信息(可选)
|
|
193
|
+
* @returns 包含错误信息的工具返回值
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```typescript
|
|
197
|
+
* try {
|
|
198
|
+
* const res = await client.im.message.create({ ... });
|
|
199
|
+
* return formatToolResult(res.data);
|
|
200
|
+
* } catch (err) {
|
|
201
|
+
* return formatToolError(err, { action: "send_message", user_id: "ou_xxx" });
|
|
202
|
+
* }
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
export declare function formatToolError(error: unknown, context?: Record<string, unknown>): ToolResult;
|
|
206
|
+
/**
|
|
207
|
+
* 创建带工具名前缀的日志函数
|
|
208
|
+
*
|
|
209
|
+
* @param api - OpenClaw 插件 API
|
|
210
|
+
* @param toolName - 工具名称
|
|
211
|
+
* @returns 日志函数对象
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* export function registerMyTool(api: OpenClawPluginApi) {
|
|
216
|
+
* const log = createToolLogger(api, "my_tool");
|
|
217
|
+
*
|
|
218
|
+
* log.info("Tool started");
|
|
219
|
+
* log.warn("Missing optional param: user_id");
|
|
220
|
+
* log.error("API call failed");
|
|
221
|
+
* log.debug("Intermediate state", { count: 5 });
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export declare function createToolLogger(api: OpenClawPluginApi, toolName: string): ToolLogger;
|
|
226
|
+
/**
|
|
227
|
+
* 校验必填参数
|
|
228
|
+
*
|
|
229
|
+
* @param params - 参数对象
|
|
230
|
+
* @param requiredFields - 必填字段列表
|
|
231
|
+
* @returns 校验结果,如果有缺失字段则返回错误信息
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* async execute(_toolCallId, params) {
|
|
236
|
+
* const error = validateRequiredParams(params, ["action", "user_id"]);
|
|
237
|
+
* if (error) return formatToolResult(error);
|
|
238
|
+
*
|
|
239
|
+
* // 继续处理...
|
|
240
|
+
* }
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
export declare function validateRequiredParams(params: Record<string, unknown>, requiredFields: string[]): {
|
|
244
|
+
error: string;
|
|
245
|
+
missing: string[];
|
|
246
|
+
} | null;
|
|
247
|
+
/**
|
|
248
|
+
* 校验枚举值
|
|
249
|
+
*
|
|
250
|
+
* @param value - 要校验的值
|
|
251
|
+
* @param allowedValues - 允许的值列表
|
|
252
|
+
* @param fieldName - 字段名(用于错误提示)
|
|
253
|
+
* @returns 校验结果,如果值不在允许列表中则返回错误信息
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* const error = validateEnum(params.action, ["create", "list", "delete"], "action");
|
|
258
|
+
* if (error) return formatToolResult(error);
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
export declare function validateEnum(value: unknown, allowedValues: unknown[], fieldName: string): {
|
|
262
|
+
error: string;
|
|
263
|
+
allowed: unknown[];
|
|
264
|
+
} | null;
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*
|
|
6
|
+
* 飞书工具开发的通用辅助函数
|
|
7
|
+
*
|
|
8
|
+
* 提供所有工具通用的模式,减少重复代码。
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.getResolvedConfig = void 0;
|
|
12
|
+
exports.createClientGetter = createClientGetter;
|
|
13
|
+
exports.getFirstAccount = getFirstAccount;
|
|
14
|
+
exports.createToolContext = createToolContext;
|
|
15
|
+
exports.checkToolRegistration = checkToolRegistration;
|
|
16
|
+
exports.registerTool = registerTool;
|
|
17
|
+
exports.formatToolResult = formatToolResult;
|
|
18
|
+
exports.formatToolError = formatToolError;
|
|
19
|
+
exports.createToolLogger = createToolLogger;
|
|
20
|
+
exports.validateRequiredParams = validateRequiredParams;
|
|
21
|
+
exports.validateEnum = validateEnum;
|
|
22
|
+
const accounts_1 = require("../core/accounts.js");
|
|
23
|
+
const lark_client_1 = require("../core/lark-client.js");
|
|
24
|
+
const lark_ticket_1 = require("../core/lark-ticket.js");
|
|
25
|
+
const tool_client_1 = require("../core/tool-client.js");
|
|
26
|
+
const tools_config_1 = require("../core/tools-config.js");
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// 配置解析
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// getResolvedConfig is defined in lark-client.ts (core layer) so that both
|
|
31
|
+
// tool-client.ts and this file can use it without a circular dependency.
|
|
32
|
+
var lark_client_2 = require("../core/lark-client.js");
|
|
33
|
+
Object.defineProperty(exports, "getResolvedConfig", { enumerable: true, get: function () { return lark_client_2.getResolvedConfig; } });
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// 客户端管理
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
/**
|
|
38
|
+
* 获取飞书客户端的标准模式
|
|
39
|
+
*
|
|
40
|
+
* 这是所有工具通用的逻辑:
|
|
41
|
+
* 1. 优先使用 LarkTicket 中的 accountId 动态解析账号
|
|
42
|
+
* 2. 如果没有 LarkTicket,回退到 accountIndex 指定的账号
|
|
43
|
+
* 3. 返回创建好的客户端实例
|
|
44
|
+
*
|
|
45
|
+
* @param config - OpenClaw 配置对象
|
|
46
|
+
* @param accountIndex - 使用第几个账号(默认 0,即第一个),仅在无 LarkTicket 时使用
|
|
47
|
+
* @returns 飞书 SDK 客户端实例
|
|
48
|
+
* @throws 如果没有启用的账号
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* export function registerMyTool(api: OpenClawPluginApi) {
|
|
53
|
+
* const getClient = createClientGetter(api.config);
|
|
54
|
+
*
|
|
55
|
+
* api.registerTool({
|
|
56
|
+
* name: "my_tool",
|
|
57
|
+
* async execute(_toolCallId, params) {
|
|
58
|
+
* const client = getClient();
|
|
59
|
+
* const res = await client.im.message.create({ ... });
|
|
60
|
+
* return formatToolResult(res.data);
|
|
61
|
+
* }
|
|
62
|
+
* });
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
function createClientGetter(config, accountIndex = 0) {
|
|
67
|
+
return () => {
|
|
68
|
+
// `config` may be stale after a hot-reload; use live config for account resolution.
|
|
69
|
+
const resolveConfig = (0, lark_client_1.getResolvedConfig)(config);
|
|
70
|
+
// 优先使用 LarkTicket 中的 accountId 进行动态账号解析
|
|
71
|
+
const ticket = (0, lark_ticket_1.getTicket)();
|
|
72
|
+
if (ticket?.accountId) {
|
|
73
|
+
const account = (0, accounts_1.getLarkAccount)(resolveConfig, ticket.accountId);
|
|
74
|
+
if (account.enabled && account.configured) {
|
|
75
|
+
return lark_client_1.LarkClient.fromAccount(account).sdk;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// 回退:使用 accountIndex 指定的账号
|
|
79
|
+
const accounts = (0, accounts_1.getEnabledLarkAccounts)(resolveConfig);
|
|
80
|
+
if (accounts.length === 0) {
|
|
81
|
+
throw new Error('No enabled Feishu accounts configured. ' + 'Please add appId and appSecret in config under channels.feishu');
|
|
82
|
+
}
|
|
83
|
+
if (accountIndex >= accounts.length) {
|
|
84
|
+
throw new Error(`Requested account index ${accountIndex} but only ${accounts.length} accounts available`);
|
|
85
|
+
}
|
|
86
|
+
const account = accounts[accountIndex];
|
|
87
|
+
const larkClient = lark_client_1.LarkClient.fromAccount(account);
|
|
88
|
+
return larkClient.sdk;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 获取当前请求对应的飞书账号信息
|
|
93
|
+
*
|
|
94
|
+
* 优先使用 LarkTicket 中的 accountId,回退到第一个启用的账号。
|
|
95
|
+
*
|
|
96
|
+
* @param config - OpenClaw 配置对象
|
|
97
|
+
* @returns 解析后的账号信息
|
|
98
|
+
* @throws 如果没有启用的账号
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const account = getFirstAccount(api.config);
|
|
103
|
+
* const client = LarkClient.fromAccount(account);
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
function getFirstAccount(config) {
|
|
107
|
+
// `config` may be stale after a hot-reload; use live config for account resolution.
|
|
108
|
+
const resolveConfig = (0, lark_client_1.getResolvedConfig)(config);
|
|
109
|
+
// 优先使用 LarkTicket 中的 accountId
|
|
110
|
+
const ticket = (0, lark_ticket_1.getTicket)();
|
|
111
|
+
if (ticket?.accountId) {
|
|
112
|
+
const account = (0, accounts_1.getLarkAccount)(resolveConfig, ticket.accountId);
|
|
113
|
+
if (account.enabled && account.configured) {
|
|
114
|
+
return account;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// 回退到第一个启用的账号
|
|
118
|
+
const accounts = (0, accounts_1.getEnabledLarkAccounts)(resolveConfig);
|
|
119
|
+
if (accounts.length === 0) {
|
|
120
|
+
throw new Error('No enabled Feishu accounts configured. ' + 'Please add appId and appSecret in config under channels.feishu');
|
|
121
|
+
}
|
|
122
|
+
return accounts[0];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 创建工具上下文,一次性返回所有常用的辅助工具
|
|
126
|
+
*
|
|
127
|
+
* 这是推荐的模式,避免在每个工具中重复调用 createClientGetter 和 createToolLogger。
|
|
128
|
+
*
|
|
129
|
+
* @param api - OpenClaw 插件 API
|
|
130
|
+
* @param toolName - 工具名称
|
|
131
|
+
* @param options - 可选配置
|
|
132
|
+
* @returns 工具上下文对象
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* export function registerMyTool(api: OpenClawPluginApi) {
|
|
137
|
+
* if (!api.config) return;
|
|
138
|
+
*
|
|
139
|
+
* const { toolClient, log } = createToolContext(api, "my_tool");
|
|
140
|
+
*
|
|
141
|
+
* api.registerTool({
|
|
142
|
+
* name: "my_tool",
|
|
143
|
+
* async execute(_toolCallId, params) {
|
|
144
|
+
* const client = getClient();
|
|
145
|
+
* log.info(`Processing action: ${params.action}`);
|
|
146
|
+
* const res = await client.im.message.create({ ... });
|
|
147
|
+
* return formatToolResult(res.data);
|
|
148
|
+
* }
|
|
149
|
+
* });
|
|
150
|
+
* }
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
function createToolContext(api, toolName, options) {
|
|
154
|
+
if (!api.config) {
|
|
155
|
+
throw new Error('No config available');
|
|
156
|
+
}
|
|
157
|
+
const config = api.config;
|
|
158
|
+
const accountIndex = options?.accountIndex ?? 0;
|
|
159
|
+
return {
|
|
160
|
+
getClient: createClientGetter(config, accountIndex),
|
|
161
|
+
toolClient: () => (0, tool_client_1.createToolClient)(config, accountIndex),
|
|
162
|
+
log: createToolLogger(api, toolName),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// 工具注册检查
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
/**
|
|
169
|
+
* 检查工具是否应该被注册(根据 channels.feishu.tools.deny 配置)。
|
|
170
|
+
*
|
|
171
|
+
* 在工具注册函数开头调用此函数,如果返回 `false` 则应该直接 return。
|
|
172
|
+
*
|
|
173
|
+
* @param api - OpenClaw Plugin API
|
|
174
|
+
* @param toolName - 工具名称
|
|
175
|
+
* @returns `true` 如果应该继续注册,`false` 如果应该跳过
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* export function registerMyTool(api: OpenClawPluginApi) {
|
|
180
|
+
* if (!checkToolRegistration(api, 'feishu_my_tool')) {
|
|
181
|
+
* return;
|
|
182
|
+
* }
|
|
183
|
+
*
|
|
184
|
+
* const { toolClient, log } = createToolContext(api, 'feishu_my_tool');
|
|
185
|
+
* api.registerTool({ ... });
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
function checkToolRegistration(api, toolName) {
|
|
190
|
+
if (!api.config)
|
|
191
|
+
return false;
|
|
192
|
+
if (!(0, tools_config_1.shouldRegisterTool)(api.config, toolName)) {
|
|
193
|
+
api.logger.debug?.(`${toolName}: Skipped registration (in deny list)`);
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* 包装的工具注册函数,自动检查 channels.feishu.tools.deny 配置。
|
|
200
|
+
*
|
|
201
|
+
* 用法:将 `api.registerTool(...)` 替换为 `registerTool(api, ...)`。
|
|
202
|
+
*
|
|
203
|
+
* @param api - OpenClaw Plugin API
|
|
204
|
+
* @param tool - 工具配置对象或工具工厂函数
|
|
205
|
+
* @param opts - 可选的工具注册选项
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```typescript
|
|
209
|
+
* // 旧代码:
|
|
210
|
+
* api.registerTool({ name: 'feishu_my_tool', ... });
|
|
211
|
+
*
|
|
212
|
+
* // 新代码:
|
|
213
|
+
* registerTool(api, { name: 'feishu_my_tool', ... });
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
function registerTool(api, tool, opts) {
|
|
217
|
+
// 提取工具名称
|
|
218
|
+
const toolName = typeof tool === 'function' ? tool.name : tool.name;
|
|
219
|
+
if (!toolName) {
|
|
220
|
+
// 如果无法提取工具名,直接注册(不拦截)
|
|
221
|
+
api.registerTool(tool, opts);
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
// 检查是否应该注册
|
|
225
|
+
if (!checkToolRegistration(api, toolName)) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
// 通过检查,调用原始的 registerTool
|
|
229
|
+
api.registerTool(tool, opts);
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
// 返回值格式化
|
|
234
|
+
// ---------------------------------------------------------------------------
|
|
235
|
+
/**
|
|
236
|
+
* 格式化工具返回值为 OpenClaw 期望的格式
|
|
237
|
+
*
|
|
238
|
+
* @param data - 要返回的数据(会被序列化为 JSON)
|
|
239
|
+
* @param options - 可选配置
|
|
240
|
+
* @returns OpenClaw 工具返回值格式
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* // 简单使用
|
|
245
|
+
* return formatToolResult({ success: true, user_id: "ou_xxx" });
|
|
246
|
+
*
|
|
247
|
+
* // 自定义 JSON 格式化
|
|
248
|
+
* return formatToolResult(data, { indent: 4 });
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
function formatToolResult(data, options = {}) {
|
|
252
|
+
const { indent = 2 } = options;
|
|
253
|
+
return {
|
|
254
|
+
content: [
|
|
255
|
+
{
|
|
256
|
+
type: 'text',
|
|
257
|
+
text: JSON.stringify(data, null, indent),
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
details: data, // 始终包含 details
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* 格式化错误为工具返回值
|
|
265
|
+
*
|
|
266
|
+
* @param error - 错误对象或字符串
|
|
267
|
+
* @param context - 错误上下文信息(可选)
|
|
268
|
+
* @returns 包含错误信息的工具返回值
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* try {
|
|
273
|
+
* const res = await client.im.message.create({ ... });
|
|
274
|
+
* return formatToolResult(res.data);
|
|
275
|
+
* } catch (err) {
|
|
276
|
+
* return formatToolError(err, { action: "send_message", user_id: "ou_xxx" });
|
|
277
|
+
* }
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
function formatToolError(error, context) {
|
|
281
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
282
|
+
return formatToolResult({
|
|
283
|
+
error: errorMsg,
|
|
284
|
+
...context,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
// 日志辅助
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
/**
|
|
291
|
+
* 创建带工具名前缀的日志函数
|
|
292
|
+
*
|
|
293
|
+
* @param api - OpenClaw 插件 API
|
|
294
|
+
* @param toolName - 工具名称
|
|
295
|
+
* @returns 日志函数对象
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```typescript
|
|
299
|
+
* export function registerMyTool(api: OpenClawPluginApi) {
|
|
300
|
+
* const log = createToolLogger(api, "my_tool");
|
|
301
|
+
*
|
|
302
|
+
* log.info("Tool started");
|
|
303
|
+
* log.warn("Missing optional param: user_id");
|
|
304
|
+
* log.error("API call failed");
|
|
305
|
+
* log.debug("Intermediate state", { count: 5 });
|
|
306
|
+
* }
|
|
307
|
+
* ```
|
|
308
|
+
*/
|
|
309
|
+
function createToolLogger(api, toolName) {
|
|
310
|
+
const prefix = `${toolName}:`;
|
|
311
|
+
return {
|
|
312
|
+
info: (msg) => {
|
|
313
|
+
if (api.logger.info) {
|
|
314
|
+
api.logger.info(`${prefix} ${msg}`);
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
warn: (msg) => {
|
|
318
|
+
if (api.logger.warn) {
|
|
319
|
+
api.logger.warn(`${prefix} ${msg}`);
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
error: (msg) => {
|
|
323
|
+
if (api.logger.error) {
|
|
324
|
+
api.logger.error(`${prefix} ${msg}`);
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
debug: (msg) => {
|
|
328
|
+
if (api.logger.debug) {
|
|
329
|
+
api.logger.debug(`${prefix} ${msg}`);
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
// ---------------------------------------------------------------------------
|
|
335
|
+
// 参数校验
|
|
336
|
+
// ---------------------------------------------------------------------------
|
|
337
|
+
/**
|
|
338
|
+
* 校验必填参数
|
|
339
|
+
*
|
|
340
|
+
* @param params - 参数对象
|
|
341
|
+
* @param requiredFields - 必填字段列表
|
|
342
|
+
* @returns 校验结果,如果有缺失字段则返回错误信息
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```typescript
|
|
346
|
+
* async execute(_toolCallId, params) {
|
|
347
|
+
* const error = validateRequiredParams(params, ["action", "user_id"]);
|
|
348
|
+
* if (error) return formatToolResult(error);
|
|
349
|
+
*
|
|
350
|
+
* // 继续处理...
|
|
351
|
+
* }
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
function validateRequiredParams(params, requiredFields) {
|
|
355
|
+
const missing = requiredFields.filter((field) => {
|
|
356
|
+
const value = params[field];
|
|
357
|
+
return value === undefined || value == null || value === '';
|
|
358
|
+
});
|
|
359
|
+
if (missing.length > 0) {
|
|
360
|
+
return {
|
|
361
|
+
error: `Missing required parameter(s): ${missing.join(', ')}`,
|
|
362
|
+
missing,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* 校验枚举值
|
|
369
|
+
*
|
|
370
|
+
* @param value - 要校验的值
|
|
371
|
+
* @param allowedValues - 允许的值列表
|
|
372
|
+
* @param fieldName - 字段名(用于错误提示)
|
|
373
|
+
* @returns 校验结果,如果值不在允许列表中则返回错误信息
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```typescript
|
|
377
|
+
* const error = validateEnum(params.action, ["create", "list", "delete"], "action");
|
|
378
|
+
* if (error) return formatToolResult(error);
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
function validateEnum(value, allowedValues, fieldName) {
|
|
382
|
+
if (!allowedValues.includes(value)) {
|
|
383
|
+
return {
|
|
384
|
+
error: `Invalid value for ${fieldName}: ${value}`,
|
|
385
|
+
allowed: allowedValues,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* MCP create-doc 工具
|
|
6
|
+
* 从 Markdown 创建云文档(支持异步 task_id 查询)
|
|
7
|
+
*/
|
|
8
|
+
import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
|
|
9
|
+
/**
|
|
10
|
+
* 注册 create-doc 工具
|
|
11
|
+
*/
|
|
12
|
+
export declare function registerCreateDocTool(api: OpenClawPluginApi): boolean;
|