@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,794 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*
|
|
6
|
+
* Interactive card building for Lark/Feishu.
|
|
7
|
+
*
|
|
8
|
+
* Provides utilities to construct Feishu Interactive Message Cards for
|
|
9
|
+
* different agent response states (thinking, streaming, complete, confirm).
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.REASONING_ELEMENT_ID = exports.STREAMING_ELEMENT_ID = void 0;
|
|
13
|
+
exports.splitReasoningText = splitReasoningText;
|
|
14
|
+
exports.stripReasoningTags = stripReasoningTags;
|
|
15
|
+
exports.formatReasoningDuration = formatReasoningDuration;
|
|
16
|
+
exports.formatToolUseDuration = formatToolUseDuration;
|
|
17
|
+
exports.formatElapsed = formatElapsed;
|
|
18
|
+
exports.compactNumber = compactNumber;
|
|
19
|
+
exports.formatFooterRuntimeSegments = formatFooterRuntimeSegments;
|
|
20
|
+
exports.buildCardContent = buildCardContent;
|
|
21
|
+
exports.buildStreamingThinkingCard = buildStreamingThinkingCard;
|
|
22
|
+
exports.buildStreamingPreAnswerCard = buildStreamingPreAnswerCard;
|
|
23
|
+
exports.toCardKit2 = toCardKit2;
|
|
24
|
+
const markdown_style_1 = require("./markdown-style.js");
|
|
25
|
+
const tool_use_display_1 = require("./tool-use-display.js");
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Constants
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Element ID used for the streaming text area in cards. The CardKit
|
|
31
|
+
* `cardElement.content()` API targets this element for typewriter-effect
|
|
32
|
+
* streaming updates.
|
|
33
|
+
*/
|
|
34
|
+
exports.STREAMING_ELEMENT_ID = 'streaming_content';
|
|
35
|
+
exports.REASONING_ELEMENT_ID = 'reasoning_content';
|
|
36
|
+
const TOOL_USE_STEP_CONTENT_INDENT = '0px 0px 0px 22px';
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Helpers
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// ---- Reasoning text utilities ----
|
|
41
|
+
// Mirrors the logic in the framework's `splitTelegramReasoningText` and
|
|
42
|
+
// related helpers from `plugin-sdk/telegram/reasoning-lane-coordinator`.
|
|
43
|
+
// Those are not exported from the public plugin-sdk entry, so we replicate
|
|
44
|
+
// the same detection/splitting logic here.
|
|
45
|
+
const REASONING_PREFIX = 'Reasoning:\n';
|
|
46
|
+
/**
|
|
47
|
+
* Split a payload text into optional `reasoningText` and `answerText`.
|
|
48
|
+
*
|
|
49
|
+
* Handles two formats produced by the framework:
|
|
50
|
+
* 1. "Reasoning:\n_italic line_\n…" prefix (from `formatReasoningMessage`)
|
|
51
|
+
* 2. `<think>…</think>` / `<thinking>…</thinking>` XML tags
|
|
52
|
+
*
|
|
53
|
+
* Equivalent to the framework's `splitTelegramReasoningText()`.
|
|
54
|
+
*/
|
|
55
|
+
function splitReasoningText(text) {
|
|
56
|
+
if (typeof text !== 'string' || !text.trim())
|
|
57
|
+
return {};
|
|
58
|
+
const trimmed = text.trim();
|
|
59
|
+
// Case 1: "Reasoning:\n..." prefix — the entire payload is reasoning
|
|
60
|
+
if (trimmed.startsWith(REASONING_PREFIX) && trimmed.length > REASONING_PREFIX.length) {
|
|
61
|
+
return { reasoningText: cleanReasoningPrefix(trimmed) };
|
|
62
|
+
}
|
|
63
|
+
// Case 2: XML thinking tags — extract content and strip from answer
|
|
64
|
+
const taggedReasoning = extractThinkingContent(text);
|
|
65
|
+
const strippedAnswer = stripReasoningTags(text);
|
|
66
|
+
if (!taggedReasoning && strippedAnswer === text) {
|
|
67
|
+
return { answerText: text };
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
reasoningText: taggedReasoning || undefined,
|
|
71
|
+
answerText: strippedAnswer || undefined,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Extract content from `<think>`, `<thinking>`, `<thought>` blocks.
|
|
76
|
+
* Handles both closed and unclosed (streaming) tags.
|
|
77
|
+
*/
|
|
78
|
+
function extractThinkingContent(text) {
|
|
79
|
+
if (!text)
|
|
80
|
+
return '';
|
|
81
|
+
const scanRe = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
|
|
82
|
+
let result = '';
|
|
83
|
+
let lastIndex = 0;
|
|
84
|
+
let inThinking = false;
|
|
85
|
+
for (const match of text.matchAll(scanRe)) {
|
|
86
|
+
const idx = match.index ?? 0;
|
|
87
|
+
if (inThinking) {
|
|
88
|
+
result += text.slice(lastIndex, idx);
|
|
89
|
+
}
|
|
90
|
+
inThinking = match[1] !== '/';
|
|
91
|
+
lastIndex = idx + match[0].length;
|
|
92
|
+
}
|
|
93
|
+
// Handle unclosed tag (still streaming)
|
|
94
|
+
if (inThinking) {
|
|
95
|
+
result += text.slice(lastIndex);
|
|
96
|
+
}
|
|
97
|
+
return result.trim();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Strip reasoning blocks — both XML tags with their content and any
|
|
101
|
+
* "Reasoning:\n" prefixed content.
|
|
102
|
+
*/
|
|
103
|
+
function stripReasoningTags(text) {
|
|
104
|
+
// Strip complete XML blocks
|
|
105
|
+
let result = text.replace(/<\s*(?:think(?:ing)?|thought|antthinking)\s*>[\s\S]*?<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi, '');
|
|
106
|
+
// Strip unclosed tag at end (streaming)
|
|
107
|
+
result = result.replace(/<\s*(?:think(?:ing)?|thought|antthinking)\s*>[\s\S]*$/gi, '');
|
|
108
|
+
// Strip orphaned closing tags
|
|
109
|
+
result = result.replace(/<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi, '');
|
|
110
|
+
return result.trim();
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Clean a "Reasoning:\n_italic_" formatted message back to plain text.
|
|
114
|
+
* Strips the prefix and per-line italic markdown wrappers.
|
|
115
|
+
*/
|
|
116
|
+
function cleanReasoningPrefix(text) {
|
|
117
|
+
let cleaned = text.replace(/^Reasoning:\s*/i, '');
|
|
118
|
+
cleaned = cleaned
|
|
119
|
+
.split('\n')
|
|
120
|
+
.map((line) => line.replace(/^_(.+)_$/, '$1'))
|
|
121
|
+
.join('\n');
|
|
122
|
+
return cleaned.trim();
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Format reasoning duration into a human-readable i18n pair.
|
|
126
|
+
* e.g. { zh: "思考了 3.2s", en: "Thought for 3.2s" }
|
|
127
|
+
*/
|
|
128
|
+
function formatReasoningDuration(ms) {
|
|
129
|
+
const d = formatElapsed(ms);
|
|
130
|
+
return { zh: `思考了 ${d}`, en: `Thought for ${d}` };
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Format tool-use duration into a human-readable i18n pair.
|
|
134
|
+
*/
|
|
135
|
+
function formatToolUseDuration(ms) {
|
|
136
|
+
const d = formatElapsed(ms);
|
|
137
|
+
return { zh: `执行耗时 ${d}`, en: `Tool use for ${d}` };
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Format milliseconds into a human-readable duration string.
|
|
141
|
+
*/
|
|
142
|
+
function formatElapsed(ms) {
|
|
143
|
+
const seconds = ms / 1000;
|
|
144
|
+
return seconds < 60 ? `${seconds.toFixed(1)}s` : `${Math.floor(seconds / 60)}m ${Math.round(seconds % 60)}s`;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Build footer meta-info: notation-sized text with i18n support.
|
|
148
|
+
* Error text is rendered in red; normal text uses default grey (notation).
|
|
149
|
+
*/
|
|
150
|
+
function buildFooter(zhText, enText, isError) {
|
|
151
|
+
const zhContent = isError ? `<font color='red'>${zhText}</font>` : zhText;
|
|
152
|
+
const enContent = isError ? `<font color='red'>${enText}</font>` : enText;
|
|
153
|
+
return [
|
|
154
|
+
{
|
|
155
|
+
tag: 'markdown',
|
|
156
|
+
content: enContent,
|
|
157
|
+
i18n_content: { zh_cn: zhContent, en_us: enContent },
|
|
158
|
+
text_size: 'notation',
|
|
159
|
+
},
|
|
160
|
+
];
|
|
161
|
+
}
|
|
162
|
+
function compactNumber(value) {
|
|
163
|
+
const abs = Math.abs(value);
|
|
164
|
+
if (abs >= 1_000_000) {
|
|
165
|
+
const m = value / 1_000_000;
|
|
166
|
+
return Math.abs(m) >= 100 ? `${Math.round(m)}m` : `${m.toFixed(1)}m`;
|
|
167
|
+
}
|
|
168
|
+
if (abs >= 1_000) {
|
|
169
|
+
const k = value / 1_000;
|
|
170
|
+
return Math.abs(k) >= 100 ? `${Math.round(k)}k` : `${k.toFixed(1)}k`;
|
|
171
|
+
}
|
|
172
|
+
return `${Math.round(value)}`;
|
|
173
|
+
}
|
|
174
|
+
function formatFooterRuntimeSegments(params) {
|
|
175
|
+
const { footer, metrics, elapsedMs, isError, isAborted } = params;
|
|
176
|
+
const primaryZh = [];
|
|
177
|
+
const primaryEn = [];
|
|
178
|
+
const detailZh = [];
|
|
179
|
+
const detailEn = [];
|
|
180
|
+
// --- Primary line: status, elapsed, model ---
|
|
181
|
+
if (footer?.status) {
|
|
182
|
+
if (isError) {
|
|
183
|
+
primaryZh.push('出错');
|
|
184
|
+
primaryEn.push('Error');
|
|
185
|
+
}
|
|
186
|
+
else if (isAborted) {
|
|
187
|
+
primaryZh.push('已停止');
|
|
188
|
+
primaryEn.push('Stopped');
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
primaryZh.push('已完成');
|
|
192
|
+
primaryEn.push('Completed');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (footer?.elapsed && elapsedMs != null) {
|
|
196
|
+
const d = formatElapsed(elapsedMs);
|
|
197
|
+
primaryZh.push(`耗时 ${d}`);
|
|
198
|
+
primaryEn.push(`Elapsed ${d}`);
|
|
199
|
+
}
|
|
200
|
+
if (footer?.model && metrics?.model) {
|
|
201
|
+
const model = metrics.model.trim();
|
|
202
|
+
if (model) {
|
|
203
|
+
primaryZh.push(model);
|
|
204
|
+
primaryEn.push(model);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// --- Detail line: tokens, cache, context ---
|
|
208
|
+
if (footer?.tokens && metrics) {
|
|
209
|
+
const inTokens = typeof metrics.inputTokens === 'number' ? Math.max(0, metrics.inputTokens) : undefined;
|
|
210
|
+
const outTokens = typeof metrics.outputTokens === 'number' ? Math.max(0, metrics.outputTokens) : undefined;
|
|
211
|
+
if (inTokens != null && outTokens != null) {
|
|
212
|
+
const inLabel = compactNumber(inTokens);
|
|
213
|
+
const outLabel = compactNumber(outTokens);
|
|
214
|
+
detailZh.push(`↑ ${inLabel} ↓ ${outLabel}`);
|
|
215
|
+
detailEn.push(`↑ ${inLabel} ↓ ${outLabel}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (footer?.cache && metrics) {
|
|
219
|
+
const read = typeof metrics.cacheRead === 'number' ? Math.max(0, metrics.cacheRead) : undefined;
|
|
220
|
+
const write = typeof metrics.cacheWrite === 'number' ? Math.max(0, metrics.cacheWrite) : undefined;
|
|
221
|
+
const inputVal = typeof metrics.inputTokens === 'number' ? Math.max(0, metrics.inputTokens) : undefined;
|
|
222
|
+
if (read != null && write != null && inputVal != null) {
|
|
223
|
+
const total = read + write + inputVal;
|
|
224
|
+
const hit = total > 0 ? Math.round((read / total) * 100) : 0;
|
|
225
|
+
const left = compactNumber(read);
|
|
226
|
+
const right = compactNumber(write);
|
|
227
|
+
detailZh.push(`缓存 ${left}/${right} (${hit}%)`);
|
|
228
|
+
detailEn.push(`Cache ${left}/${right} (${hit}%)`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
if (footer?.context && metrics) {
|
|
232
|
+
const freshTotal = metrics.totalTokensFresh === false ? undefined : metrics.totalTokens;
|
|
233
|
+
const total = typeof freshTotal === 'number' ? Math.max(0, freshTotal) : undefined;
|
|
234
|
+
const ctx = typeof metrics.contextTokens === 'number' ? Math.max(0, metrics.contextTokens) : undefined;
|
|
235
|
+
if (total != null && ctx != null) {
|
|
236
|
+
const totalLabel = compactNumber(total);
|
|
237
|
+
const ctxLabel = compactNumber(ctx);
|
|
238
|
+
const pct = ctx > 0 ? Math.round((total / ctx) * 100) : 0;
|
|
239
|
+
const pctLabel = `${pct}%`;
|
|
240
|
+
detailZh.push(`上下文 ${totalLabel}/${ctxLabel} (${pctLabel})`);
|
|
241
|
+
detailEn.push(`Context ${totalLabel}/${ctxLabel} (${pctLabel})`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return { primaryZh, primaryEn, detailZh, detailEn };
|
|
245
|
+
}
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
// buildCardContent
|
|
248
|
+
// ---------------------------------------------------------------------------
|
|
249
|
+
/**
|
|
250
|
+
* Build a full Feishu Interactive Message Card JSON object for the
|
|
251
|
+
* given state.
|
|
252
|
+
*/
|
|
253
|
+
function buildCardContent(state, data = {}) {
|
|
254
|
+
switch (state) {
|
|
255
|
+
case 'thinking':
|
|
256
|
+
return buildThinkingCard();
|
|
257
|
+
case 'streaming':
|
|
258
|
+
return buildStreamingCard(data.text ?? '', {
|
|
259
|
+
reasoningText: data.reasoningText,
|
|
260
|
+
showToolUse: data.showToolUse,
|
|
261
|
+
toolUseSteps: data.toolUseSteps,
|
|
262
|
+
toolUseTitleSuffix: data.toolUseTitleSuffix,
|
|
263
|
+
});
|
|
264
|
+
case 'complete':
|
|
265
|
+
return buildCompleteCard({
|
|
266
|
+
text: data.text ?? '',
|
|
267
|
+
elapsedMs: data.elapsedMs,
|
|
268
|
+
isError: data.isError,
|
|
269
|
+
reasoningText: data.reasoningText,
|
|
270
|
+
reasoningElapsedMs: data.reasoningElapsedMs,
|
|
271
|
+
toolUseSteps: data.toolUseSteps,
|
|
272
|
+
toolUseTitleSuffix: data.toolUseTitleSuffix,
|
|
273
|
+
toolUseElapsedMs: data.toolUseElapsedMs,
|
|
274
|
+
showToolUse: data.showToolUse,
|
|
275
|
+
isAborted: data.isAborted,
|
|
276
|
+
footer: data.footer,
|
|
277
|
+
footerMetrics: data.footerMetrics,
|
|
278
|
+
});
|
|
279
|
+
case 'confirm':
|
|
280
|
+
return buildConfirmCard(data.confirmData);
|
|
281
|
+
default:
|
|
282
|
+
throw new Error(`Unknown card state: ${state}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// ---------------------------------------------------------------------------
|
|
286
|
+
// Private card builders
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
function buildThinkingCard() {
|
|
289
|
+
return {
|
|
290
|
+
config: { wide_screen_mode: true, update_multi: true, locales: ['zh_cn', 'en_us'] },
|
|
291
|
+
elements: [
|
|
292
|
+
{
|
|
293
|
+
tag: 'markdown',
|
|
294
|
+
content: 'Thinking...',
|
|
295
|
+
i18n_content: { zh_cn: '思考中...', en_us: 'Thinking...' },
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function buildStreamingCard(partialText, params = {}) {
|
|
301
|
+
const { showToolUse = true, toolUseSteps, toolUseTitleSuffix, reasoningText } = params;
|
|
302
|
+
const elements = [];
|
|
303
|
+
const hasToolUse = Boolean(toolUseSteps?.length);
|
|
304
|
+
if (showToolUse) {
|
|
305
|
+
elements.push(hasToolUse
|
|
306
|
+
? buildToolUsePanel({
|
|
307
|
+
toolUseSteps,
|
|
308
|
+
titleSuffix: toolUseTitleSuffix,
|
|
309
|
+
})
|
|
310
|
+
: buildStreamingToolUsePendingPanel());
|
|
311
|
+
}
|
|
312
|
+
if (!partialText && reasoningText) {
|
|
313
|
+
// Reasoning phase: show reasoning content in notation style
|
|
314
|
+
elements.push({
|
|
315
|
+
tag: 'markdown',
|
|
316
|
+
content: `💭 **Thinking...**\n\n${reasoningText}`,
|
|
317
|
+
i18n_content: {
|
|
318
|
+
zh_cn: `💭 **思考中...**\n\n${reasoningText}`,
|
|
319
|
+
en_us: `💭 **Thinking...**\n\n${reasoningText}`,
|
|
320
|
+
},
|
|
321
|
+
text_size: 'notation',
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
else if (partialText) {
|
|
325
|
+
// Answer phase: show answer content only
|
|
326
|
+
elements.push({
|
|
327
|
+
tag: 'markdown',
|
|
328
|
+
content: (0, markdown_style_1.optimizeMarkdownStyle)(partialText),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
config: { wide_screen_mode: true, update_multi: true, locales: ['zh_cn', 'en_us'] },
|
|
333
|
+
elements,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
function buildCompleteCard(params) {
|
|
337
|
+
const { text, elapsedMs, isError, reasoningText, reasoningElapsedMs, toolUseSteps, toolUseTitleSuffix, toolUseElapsedMs, showToolUse = true, isAborted, footer, footerMetrics, } = params;
|
|
338
|
+
const elements = [];
|
|
339
|
+
if (showToolUse) {
|
|
340
|
+
elements.push(buildToolUsePanel({
|
|
341
|
+
toolUseSteps,
|
|
342
|
+
toolUseElapsedMs,
|
|
343
|
+
titleSuffix: toolUseTitleSuffix,
|
|
344
|
+
}));
|
|
345
|
+
}
|
|
346
|
+
// Collapsible reasoning panel (before main content)
|
|
347
|
+
if (reasoningText) {
|
|
348
|
+
const dur = reasoningElapsedMs ? formatReasoningDuration(reasoningElapsedMs) : null;
|
|
349
|
+
const zhLabel = dur ? dur.zh : '思考';
|
|
350
|
+
const enLabel = dur ? dur.en : 'Thought';
|
|
351
|
+
elements.push({
|
|
352
|
+
tag: 'collapsible_panel',
|
|
353
|
+
expanded: false,
|
|
354
|
+
header: {
|
|
355
|
+
title: {
|
|
356
|
+
tag: 'markdown',
|
|
357
|
+
content: `💭 ${enLabel}`,
|
|
358
|
+
i18n_content: {
|
|
359
|
+
zh_cn: `💭 ${zhLabel}`,
|
|
360
|
+
en_us: `💭 ${enLabel}`,
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
vertical_align: 'center',
|
|
364
|
+
icon: {
|
|
365
|
+
tag: 'standard_icon',
|
|
366
|
+
token: 'down-small-ccm_outlined',
|
|
367
|
+
size: '16px 16px',
|
|
368
|
+
},
|
|
369
|
+
icon_position: 'follow_text',
|
|
370
|
+
icon_expanded_angle: -180,
|
|
371
|
+
},
|
|
372
|
+
border: { color: 'grey', corner_radius: '5px' },
|
|
373
|
+
vertical_spacing: '8px',
|
|
374
|
+
padding: '8px 8px 8px 8px',
|
|
375
|
+
elements: [
|
|
376
|
+
{
|
|
377
|
+
tag: 'markdown',
|
|
378
|
+
content: reasoningText,
|
|
379
|
+
text_size: 'notation',
|
|
380
|
+
},
|
|
381
|
+
],
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
// Full text content
|
|
385
|
+
elements.push({
|
|
386
|
+
tag: 'markdown',
|
|
387
|
+
content: (0, markdown_style_1.optimizeMarkdownStyle)(text),
|
|
388
|
+
});
|
|
389
|
+
// Footer meta-info: split into two lines for readability.
|
|
390
|
+
// Line 1 (primary): status · elapsed · model
|
|
391
|
+
// Line 2 (detail): tokens · cache · context
|
|
392
|
+
const fp = formatFooterRuntimeSegments({
|
|
393
|
+
footer,
|
|
394
|
+
metrics: footerMetrics,
|
|
395
|
+
elapsedMs,
|
|
396
|
+
isError,
|
|
397
|
+
isAborted,
|
|
398
|
+
});
|
|
399
|
+
const footerZhLines = [];
|
|
400
|
+
const footerEnLines = [];
|
|
401
|
+
if (fp.primaryZh.length > 0) {
|
|
402
|
+
footerZhLines.push(fp.primaryZh.join(' · '));
|
|
403
|
+
footerEnLines.push(fp.primaryEn.join(' · '));
|
|
404
|
+
}
|
|
405
|
+
if (fp.detailZh.length > 0) {
|
|
406
|
+
footerZhLines.push(fp.detailZh.join(' · '));
|
|
407
|
+
footerEnLines.push(fp.detailEn.join(' · '));
|
|
408
|
+
}
|
|
409
|
+
if (footerZhLines.length > 0) {
|
|
410
|
+
elements.push(...buildFooter(footerZhLines.join('\n'), footerEnLines.join('\n'), isError));
|
|
411
|
+
}
|
|
412
|
+
// Use the answer text as the feed preview summary.
|
|
413
|
+
// Strip markdown syntax so the preview reads as plain text.
|
|
414
|
+
const summaryText = text.replace(/[*_`#>[\]()~]/g, '').trim();
|
|
415
|
+
const summary = summaryText ? { content: summaryText.slice(0, 120) } : undefined;
|
|
416
|
+
return {
|
|
417
|
+
config: { wide_screen_mode: true, update_multi: true, locales: ['zh_cn', 'en_us'], summary },
|
|
418
|
+
elements,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function buildConfirmCard(confirmData) {
|
|
422
|
+
const elements = [];
|
|
423
|
+
// Operation description
|
|
424
|
+
elements.push({
|
|
425
|
+
tag: 'div',
|
|
426
|
+
text: {
|
|
427
|
+
tag: 'lark_md',
|
|
428
|
+
content: confirmData.operationDescription,
|
|
429
|
+
},
|
|
430
|
+
});
|
|
431
|
+
// Preview (if available)
|
|
432
|
+
if (confirmData.preview) {
|
|
433
|
+
elements.push({ tag: 'hr' });
|
|
434
|
+
elements.push({
|
|
435
|
+
tag: 'div',
|
|
436
|
+
text: {
|
|
437
|
+
tag: 'lark_md',
|
|
438
|
+
content: `**Preview:**\n${confirmData.preview}`,
|
|
439
|
+
},
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
// Confirm / Reject / Preview buttons
|
|
443
|
+
elements.push({ tag: 'hr' });
|
|
444
|
+
elements.push({
|
|
445
|
+
tag: 'action',
|
|
446
|
+
actions: [
|
|
447
|
+
{
|
|
448
|
+
tag: 'button',
|
|
449
|
+
text: { tag: 'plain_text', content: 'Confirm' },
|
|
450
|
+
type: 'primary',
|
|
451
|
+
value: {
|
|
452
|
+
action: 'confirm_write',
|
|
453
|
+
operation_id: confirmData.pendingOperationId,
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
tag: 'button',
|
|
458
|
+
text: { tag: 'plain_text', content: 'Reject' },
|
|
459
|
+
type: 'danger',
|
|
460
|
+
value: {
|
|
461
|
+
action: 'reject_write',
|
|
462
|
+
operation_id: confirmData.pendingOperationId,
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
...(confirmData.preview
|
|
466
|
+
? []
|
|
467
|
+
: [
|
|
468
|
+
{
|
|
469
|
+
tag: 'button',
|
|
470
|
+
text: {
|
|
471
|
+
tag: 'plain_text',
|
|
472
|
+
content: 'Preview',
|
|
473
|
+
},
|
|
474
|
+
type: 'default',
|
|
475
|
+
value: {
|
|
476
|
+
action: 'preview_write',
|
|
477
|
+
operation_id: confirmData.pendingOperationId,
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
]),
|
|
481
|
+
],
|
|
482
|
+
});
|
|
483
|
+
return {
|
|
484
|
+
config: { wide_screen_mode: true, update_multi: true },
|
|
485
|
+
header: {
|
|
486
|
+
title: {
|
|
487
|
+
tag: 'plain_text',
|
|
488
|
+
content: '\ud83d\udd12 Confirmation Required',
|
|
489
|
+
},
|
|
490
|
+
template: 'orange',
|
|
491
|
+
},
|
|
492
|
+
elements,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
// ---------------------------------------------------------------------------
|
|
496
|
+
// toCardKit2
|
|
497
|
+
// ---------------------------------------------------------------------------
|
|
498
|
+
/**
|
|
499
|
+
* Convert an old-format FeishuCard to CardKit JSON 2.0 format.
|
|
500
|
+
* JSON 2.0 uses `body.elements` instead of top-level `elements`.
|
|
501
|
+
*/
|
|
502
|
+
/**
|
|
503
|
+
* Build the initial CardKit 2.0 streaming card with a loading icon.
|
|
504
|
+
* Optionally includes a tool-use pending panel above the streaming area.
|
|
505
|
+
*/
|
|
506
|
+
function buildStreamingThinkingCard(showToolUse = true) {
|
|
507
|
+
return buildStreamingPreAnswerCard({ showToolUse });
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Build a CardKit 2.0 card for the pre-answer streaming phase.
|
|
511
|
+
* Used both for the initial card and for live updates during tool calls.
|
|
512
|
+
*/
|
|
513
|
+
function buildStreamingPreAnswerCard(params) {
|
|
514
|
+
const { steps, elapsedMs, showToolUse = true } = params;
|
|
515
|
+
const hasSteps = Boolean(steps?.length);
|
|
516
|
+
const elements = [];
|
|
517
|
+
if (showToolUse) {
|
|
518
|
+
elements.push(hasSteps ? buildStreamingToolUseActivePanel({ steps: steps, elapsedMs }) : buildStreamingToolUsePendingPanel());
|
|
519
|
+
}
|
|
520
|
+
elements.push({
|
|
521
|
+
tag: 'markdown',
|
|
522
|
+
content: '',
|
|
523
|
+
text_align: 'left',
|
|
524
|
+
text_size: 'normal_v2',
|
|
525
|
+
margin: '0px 0px 0px 0px',
|
|
526
|
+
element_id: exports.STREAMING_ELEMENT_ID,
|
|
527
|
+
});
|
|
528
|
+
elements.push({
|
|
529
|
+
tag: 'markdown',
|
|
530
|
+
content: ' ',
|
|
531
|
+
icon: {
|
|
532
|
+
tag: 'custom_icon',
|
|
533
|
+
img_key: 'img_v3_02vb_496bec09-4b43-4773-ad6b-0cdd103cd2bg',
|
|
534
|
+
size: '16px 16px',
|
|
535
|
+
},
|
|
536
|
+
element_id: 'loading_icon',
|
|
537
|
+
});
|
|
538
|
+
return {
|
|
539
|
+
schema: '2.0',
|
|
540
|
+
config: {
|
|
541
|
+
streaming_mode: true,
|
|
542
|
+
locales: ['zh_cn', 'en_us'],
|
|
543
|
+
summary: {
|
|
544
|
+
content: 'Processing...',
|
|
545
|
+
i18n_content: { zh_cn: '处理中...', en_us: 'Processing...' },
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
body: { elements },
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Build the collapsible panel for the active pre-answer phase.
|
|
553
|
+
* Used by buildStreamingPreAnswerCard when at least one step exists.
|
|
554
|
+
*/
|
|
555
|
+
function buildStreamingToolUseActivePanel(params) {
|
|
556
|
+
const { steps, elapsedMs } = params;
|
|
557
|
+
const enParts = ['Tool use'];
|
|
558
|
+
const zhParts = ['工具执行'];
|
|
559
|
+
if (steps.length > 0) {
|
|
560
|
+
enParts.push(`${steps.length} step${steps.length === 1 ? '' : 's'}`);
|
|
561
|
+
zhParts.push(`${steps.length} 步`);
|
|
562
|
+
}
|
|
563
|
+
if (elapsedMs != null && elapsedMs > 0) {
|
|
564
|
+
const d = formatElapsed(elapsedMs);
|
|
565
|
+
enParts.push(`(${d})`);
|
|
566
|
+
zhParts.push(`(${d})`);
|
|
567
|
+
}
|
|
568
|
+
return {
|
|
569
|
+
tag: 'collapsible_panel',
|
|
570
|
+
expanded: true,
|
|
571
|
+
header: {
|
|
572
|
+
title: {
|
|
573
|
+
tag: 'plain_text',
|
|
574
|
+
content: `🛠️ ${enParts.join(' · ')}`,
|
|
575
|
+
i18n_content: {
|
|
576
|
+
zh_cn: `🛠️ ${zhParts.join(' · ')}`,
|
|
577
|
+
en_us: `🛠️ ${enParts.join(' · ')}`,
|
|
578
|
+
},
|
|
579
|
+
text_color: 'grey',
|
|
580
|
+
text_size: 'notation',
|
|
581
|
+
},
|
|
582
|
+
vertical_align: 'center',
|
|
583
|
+
icon: {
|
|
584
|
+
tag: 'standard_icon',
|
|
585
|
+
token: 'down-small-ccm_outlined',
|
|
586
|
+
color: 'grey',
|
|
587
|
+
size: '16px 16px',
|
|
588
|
+
},
|
|
589
|
+
icon_position: 'right',
|
|
590
|
+
icon_expanded_angle: -180,
|
|
591
|
+
},
|
|
592
|
+
border: { color: 'grey', corner_radius: '5px' },
|
|
593
|
+
vertical_spacing: '4px',
|
|
594
|
+
padding: '8px 8px 8px 8px',
|
|
595
|
+
elements: steps.flatMap((step) => buildToolUseStepElements(step)),
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
function toCardKit2(card) {
|
|
599
|
+
const result = {
|
|
600
|
+
schema: '2.0',
|
|
601
|
+
config: card.config,
|
|
602
|
+
body: { elements: card.elements },
|
|
603
|
+
};
|
|
604
|
+
if (card.header)
|
|
605
|
+
result.header = card.header;
|
|
606
|
+
return result;
|
|
607
|
+
}
|
|
608
|
+
function buildStreamingToolUsePendingPanel() {
|
|
609
|
+
return {
|
|
610
|
+
tag: 'collapsible_panel',
|
|
611
|
+
expanded: false,
|
|
612
|
+
header: {
|
|
613
|
+
title: {
|
|
614
|
+
tag: 'plain_text',
|
|
615
|
+
content: '🛠️ Tool use pending',
|
|
616
|
+
i18n_content: {
|
|
617
|
+
zh_cn: '🛠️ 等待工具执行',
|
|
618
|
+
en_us: '🛠️ Tool use pending',
|
|
619
|
+
},
|
|
620
|
+
text_color: 'grey',
|
|
621
|
+
text_size: 'notation',
|
|
622
|
+
},
|
|
623
|
+
vertical_align: 'center',
|
|
624
|
+
icon: {
|
|
625
|
+
tag: 'standard_icon',
|
|
626
|
+
token: 'down-small-ccm_outlined',
|
|
627
|
+
color: 'grey',
|
|
628
|
+
size: '16px 16px',
|
|
629
|
+
},
|
|
630
|
+
icon_position: 'right',
|
|
631
|
+
icon_expanded_angle: -180,
|
|
632
|
+
},
|
|
633
|
+
border: { color: 'grey', corner_radius: '5px' },
|
|
634
|
+
vertical_spacing: '4px',
|
|
635
|
+
padding: '8px 8px 8px 8px',
|
|
636
|
+
elements: [],
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
function buildToolUsePanel(params) {
|
|
640
|
+
const { toolUseSteps = [], toolUseElapsedMs, titleSuffix } = params;
|
|
641
|
+
const duration = toolUseElapsedMs ? formatToolUseDuration(toolUseElapsedMs) : null;
|
|
642
|
+
const zhTitleParts = [duration?.zh ?? '工具执行'];
|
|
643
|
+
const enTitleParts = [duration?.en ?? 'Tool use'];
|
|
644
|
+
if (titleSuffix) {
|
|
645
|
+
zhTitleParts.push(titleSuffix.zh);
|
|
646
|
+
enTitleParts.push(titleSuffix.en);
|
|
647
|
+
}
|
|
648
|
+
const stepElements = toolUseSteps.length > 0
|
|
649
|
+
? toolUseSteps.flatMap((step) => buildToolUseStepElements(step))
|
|
650
|
+
: [buildToolUsePlaceholder()];
|
|
651
|
+
return {
|
|
652
|
+
tag: 'collapsible_panel',
|
|
653
|
+
expanded: false,
|
|
654
|
+
header: {
|
|
655
|
+
title: {
|
|
656
|
+
tag: 'plain_text',
|
|
657
|
+
content: `🛠️ ${enTitleParts.join(' · ')}`,
|
|
658
|
+
i18n_content: {
|
|
659
|
+
zh_cn: `🛠️ ${zhTitleParts.join(' · ')}`,
|
|
660
|
+
en_us: `🛠️ ${enTitleParts.join(' · ')}`,
|
|
661
|
+
},
|
|
662
|
+
text_color: 'grey',
|
|
663
|
+
text_size: 'notation',
|
|
664
|
+
},
|
|
665
|
+
vertical_align: 'center',
|
|
666
|
+
icon: {
|
|
667
|
+
tag: 'standard_icon',
|
|
668
|
+
token: 'down-small-ccm_outlined',
|
|
669
|
+
color: 'grey',
|
|
670
|
+
size: '16px 16px',
|
|
671
|
+
},
|
|
672
|
+
icon_position: 'right',
|
|
673
|
+
icon_expanded_angle: -180,
|
|
674
|
+
},
|
|
675
|
+
border: { color: 'grey', corner_radius: '5px' },
|
|
676
|
+
vertical_spacing: '4px',
|
|
677
|
+
padding: '8px 8px 8px 8px',
|
|
678
|
+
elements: stepElements,
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
function buildToolUseStepElements(step) {
|
|
682
|
+
const elements = [buildToolUseStepTitleElement(step)];
|
|
683
|
+
const detailElement = buildToolUseStepDetailElement(step);
|
|
684
|
+
if (detailElement) {
|
|
685
|
+
elements.push(detailElement);
|
|
686
|
+
}
|
|
687
|
+
const outputElement = buildToolUseStepOutputElement(step);
|
|
688
|
+
if (outputElement) {
|
|
689
|
+
elements.push(outputElement);
|
|
690
|
+
}
|
|
691
|
+
return elements;
|
|
692
|
+
}
|
|
693
|
+
function buildToolUsePlaceholder(labels) {
|
|
694
|
+
const zh = labels?.zh ?? '暂无工具步骤';
|
|
695
|
+
const en = labels?.en ?? tool_use_display_1.EMPTY_TOOL_USE_PLACEHOLDER;
|
|
696
|
+
return {
|
|
697
|
+
tag: 'div',
|
|
698
|
+
text: {
|
|
699
|
+
tag: 'plain_text',
|
|
700
|
+
content: en,
|
|
701
|
+
i18n_content: {
|
|
702
|
+
zh_cn: zh,
|
|
703
|
+
en_us: en,
|
|
704
|
+
},
|
|
705
|
+
text_color: 'grey',
|
|
706
|
+
text_size: 'notation',
|
|
707
|
+
},
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
function buildToolUseStepTitleElement(step) {
|
|
711
|
+
return {
|
|
712
|
+
tag: 'div',
|
|
713
|
+
icon: {
|
|
714
|
+
tag: 'standard_icon',
|
|
715
|
+
token: step.iconToken,
|
|
716
|
+
color: 'grey',
|
|
717
|
+
},
|
|
718
|
+
text: {
|
|
719
|
+
tag: 'lark_md',
|
|
720
|
+
content: buildToolUseStepTitleMarkdown(step),
|
|
721
|
+
text_size: 'notation',
|
|
722
|
+
},
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
function buildToolUseStepTitleMarkdown(step) {
|
|
726
|
+
const status = formatToolUseStepStatus(step.status);
|
|
727
|
+
return (0, markdown_style_1.optimizeMarkdownStyle)(`**${escapeToolUseMarkdownText(step.title)}** · <font color='${status.color}'>${status.label}</font>`, 1);
|
|
728
|
+
}
|
|
729
|
+
function buildToolUseStepDetailElement(step) {
|
|
730
|
+
const detail = step.detail?.trim();
|
|
731
|
+
if (!detail)
|
|
732
|
+
return undefined;
|
|
733
|
+
return {
|
|
734
|
+
tag: 'div',
|
|
735
|
+
margin: TOOL_USE_STEP_CONTENT_INDENT,
|
|
736
|
+
text: {
|
|
737
|
+
tag: 'plain_text',
|
|
738
|
+
content: detail,
|
|
739
|
+
text_color: 'grey',
|
|
740
|
+
text_size: 'notation',
|
|
741
|
+
},
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
function buildToolUseStepOutputElement(step) {
|
|
745
|
+
const content = buildToolUseStepOutputMarkdown(step);
|
|
746
|
+
if (!content)
|
|
747
|
+
return undefined;
|
|
748
|
+
return {
|
|
749
|
+
tag: 'div',
|
|
750
|
+
margin: TOOL_USE_STEP_CONTENT_INDENT,
|
|
751
|
+
text: {
|
|
752
|
+
tag: 'lark_md',
|
|
753
|
+
content,
|
|
754
|
+
text_size: 'notation',
|
|
755
|
+
},
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
function buildToolUseStepOutputMarkdown(step) {
|
|
759
|
+
const lines = [];
|
|
760
|
+
if (step.errorBlock) {
|
|
761
|
+
lines.push('**Error**');
|
|
762
|
+
lines.push(formatToolUseCodeBlock(step.errorBlock.content, step.errorBlock.language));
|
|
763
|
+
}
|
|
764
|
+
else if (step.resultBlock) {
|
|
765
|
+
lines.push('**Result**');
|
|
766
|
+
lines.push(formatToolUseCodeBlock(step.resultBlock.content, step.resultBlock.language));
|
|
767
|
+
}
|
|
768
|
+
if (lines.length === 0)
|
|
769
|
+
return undefined;
|
|
770
|
+
return (0, markdown_style_1.optimizeMarkdownStyle)(lines.join('\n'), 1);
|
|
771
|
+
}
|
|
772
|
+
function formatToolUseStepStatus(status) {
|
|
773
|
+
switch (status) {
|
|
774
|
+
case 'running':
|
|
775
|
+
return { label: 'Running', color: 'turquoise' };
|
|
776
|
+
case 'error':
|
|
777
|
+
return { label: 'Failed', color: 'red' };
|
|
778
|
+
case 'success':
|
|
779
|
+
default:
|
|
780
|
+
return { label: 'Succeeded', color: 'green' };
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
function formatToolUseCodeBlock(content, language) {
|
|
784
|
+
const normalized = content.replace(/\r\n/g, '\n').trim();
|
|
785
|
+
const fence = '`'.repeat(Math.max(3, longestBacktickRun(normalized) + 1));
|
|
786
|
+
return `${fence}${language}\n${normalized}\n${fence}`;
|
|
787
|
+
}
|
|
788
|
+
function longestBacktickRun(value) {
|
|
789
|
+
const matches = value.match(/`+/g) ?? [];
|
|
790
|
+
return matches.reduce((max, run) => Math.max(max, run.length), 0);
|
|
791
|
+
}
|
|
792
|
+
function escapeToolUseMarkdownText(value) {
|
|
793
|
+
return value.replace(/\\/g, '\\\\').replace(/([`*_{}[\]<>])/g, '\\$1');
|
|
794
|
+
}
|