@lark-project/openclaw-lark-project 2026.3.131
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 +80 -0
- package/README.zh.md +80 -0
- package/dist/index.js +172 -0
- package/dist/index.js.map +7 -0
- package/dist/skills/feishu-bitable/SKILL.md +248 -0
- package/dist/skills/feishu-bitable/references/examples.md +813 -0
- package/dist/skills/feishu-bitable/references/field-properties.md +763 -0
- package/dist/skills/feishu-bitable/references/record-values.md +911 -0
- package/dist/skills/feishu-calendar/SKILL.md +244 -0
- package/dist/skills/feishu-channel-rules/SKILL.md +18 -0
- package/dist/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
- package/dist/skills/feishu-create-doc/SKILL.md +719 -0
- package/dist/skills/feishu-fetch-doc/SKILL.md +93 -0
- package/dist/skills/feishu-im-read/SKILL.md +163 -0
- package/dist/skills/feishu-project/SKILL.md +122 -0
- package/dist/skills/feishu-task/SKILL.md +293 -0
- package/dist/skills/feishu-troubleshoot/SKILL.md +70 -0
- package/dist/skills/feishu-update-doc/SKILL.md +285 -0
- package/dist/src/card/builder.js +293 -0
- package/dist/src/card/builder.js.map +7 -0
- package/dist/src/card/cardkit.js +126 -0
- package/dist/src/card/cardkit.js.map +7 -0
- package/dist/src/card/flush-controller.js +107 -0
- package/dist/src/card/flush-controller.js.map +7 -0
- package/dist/src/card/markdown-style.js +57 -0
- package/dist/src/card/markdown-style.js.map +7 -0
- package/dist/src/card/reply-dispatcher-types.js +39 -0
- package/dist/src/card/reply-dispatcher-types.js.map +7 -0
- package/dist/src/card/reply-dispatcher.js +245 -0
- package/dist/src/card/reply-dispatcher.js.map +7 -0
- package/dist/src/card/reply-mode.js +29 -0
- package/dist/src/card/reply-mode.js.map +7 -0
- package/dist/src/card/streaming-card-controller.js +653 -0
- package/dist/src/card/streaming-card-controller.js.map +7 -0
- package/dist/src/card/unavailable-guard.js +76 -0
- package/dist/src/card/unavailable-guard.js.map +7 -0
- package/dist/src/channel/abort-detect.js +79 -0
- package/dist/src/channel/abort-detect.js.map +7 -0
- package/dist/src/channel/chat-queue.js +50 -0
- package/dist/src/channel/chat-queue.js.map +7 -0
- package/dist/src/channel/config-adapter.js +89 -0
- package/dist/src/channel/config-adapter.js.map +7 -0
- package/dist/src/channel/directory.js +133 -0
- package/dist/src/channel/directory.js.map +7 -0
- package/dist/src/channel/event-handlers.js +175 -0
- package/dist/src/channel/event-handlers.js.map +7 -0
- package/dist/src/channel/monitor.js +108 -0
- package/dist/src/channel/monitor.js.map +7 -0
- package/dist/src/channel/onboarding-config.js +76 -0
- package/dist/src/channel/onboarding-config.js.map +7 -0
- package/dist/src/channel/onboarding-migrate.js +55 -0
- package/dist/src/channel/onboarding-migrate.js.map +7 -0
- package/dist/src/channel/onboarding.js +285 -0
- package/dist/src/channel/onboarding.js.map +7 -0
- package/dist/src/channel/plugin.js +260 -0
- package/dist/src/channel/plugin.js.map +7 -0
- package/dist/src/channel/probe.js +14 -0
- package/dist/src/channel/probe.js.map +7 -0
- package/dist/src/channel/types.js +1 -0
- package/dist/src/channel/types.js.map +7 -0
- package/dist/src/commands/auth.js +73 -0
- package/dist/src/commands/auth.js.map +7 -0
- package/dist/src/commands/diagnose.js +658 -0
- package/dist/src/commands/diagnose.js.map +7 -0
- package/dist/src/commands/doctor.js +327 -0
- package/dist/src/commands/doctor.js.map +7 -0
- package/dist/src/commands/index.js +124 -0
- package/dist/src/commands/index.js.map +7 -0
- package/dist/src/core/accounts.js +129 -0
- package/dist/src/core/accounts.js.map +7 -0
- package/dist/src/core/agent-config.js +60 -0
- package/dist/src/core/agent-config.js.map +7 -0
- package/dist/src/core/api-error.js +55 -0
- package/dist/src/core/api-error.js.map +7 -0
- package/dist/src/core/app-owner-fallback.js +17 -0
- package/dist/src/core/app-owner-fallback.js.map +7 -0
- package/dist/src/core/app-scope-checker.js +95 -0
- package/dist/src/core/app-scope-checker.js.map +7 -0
- package/dist/src/core/auth-errors.js +120 -0
- package/dist/src/core/auth-errors.js.map +7 -0
- package/dist/src/core/chat-info-cache.js +102 -0
- package/dist/src/core/chat-info-cache.js.map +7 -0
- package/dist/src/core/config-schema.js +150 -0
- package/dist/src/core/config-schema.js.map +7 -0
- package/dist/src/core/device-flow.js +174 -0
- package/dist/src/core/device-flow.js.map +7 -0
- package/dist/src/core/feishu-fetch.js +12 -0
- package/dist/src/core/feishu-fetch.js.map +7 -0
- package/dist/src/core/footer-config.js +16 -0
- package/dist/src/core/footer-config.js.map +7 -0
- package/dist/src/core/lark-client.js +322 -0
- package/dist/src/core/lark-client.js.map +7 -0
- package/dist/src/core/lark-logger.js +92 -0
- package/dist/src/core/lark-logger.js.map +7 -0
- package/dist/src/core/lark-ticket.js +18 -0
- package/dist/src/core/lark-ticket.js.map +7 -0
- package/dist/src/core/message-unavailable.js +119 -0
- package/dist/src/core/message-unavailable.js.map +7 -0
- package/dist/src/core/owner-policy.js +25 -0
- package/dist/src/core/owner-policy.js.map +7 -0
- package/dist/src/core/permission-url.js +37 -0
- package/dist/src/core/permission-url.js.map +7 -0
- package/dist/src/core/project-auth.js +177 -0
- package/dist/src/core/project-auth.js.map +7 -0
- package/dist/src/core/project-oauth-flow.js +124 -0
- package/dist/src/core/project-oauth-flow.js.map +7 -0
- package/dist/src/core/project-token-store.js +172 -0
- package/dist/src/core/project-token-store.js.map +7 -0
- package/dist/src/core/raw-request.js +45 -0
- package/dist/src/core/raw-request.js.map +7 -0
- package/dist/src/core/scope-manager.js +62 -0
- package/dist/src/core/scope-manager.js.map +7 -0
- package/dist/src/core/security-check.js +118 -0
- package/dist/src/core/security-check.js.map +7 -0
- package/dist/src/core/shutdown-hooks.js +37 -0
- package/dist/src/core/shutdown-hooks.js.map +7 -0
- package/dist/src/core/targets.js +55 -0
- package/dist/src/core/targets.js.map +7 -0
- package/dist/src/core/token-store.js +215 -0
- package/dist/src/core/token-store.js.map +7 -0
- package/dist/src/core/tool-client.js +335 -0
- package/dist/src/core/tool-client.js.map +7 -0
- package/dist/src/core/tool-scopes.js +207 -0
- package/dist/src/core/tool-scopes.js.map +7 -0
- package/dist/src/core/tools-config.js +57 -0
- package/dist/src/core/tools-config.js.map +7 -0
- package/dist/src/core/types.js +1 -0
- package/dist/src/core/types.js.map +7 -0
- package/dist/src/core/uat-client.js +124 -0
- package/dist/src/core/uat-client.js.map +7 -0
- package/dist/src/core/version.js +27 -0
- package/dist/src/core/version.js.map +7 -0
- package/dist/src/messaging/converters/audio.js +19 -0
- package/dist/src/messaging/converters/audio.js.map +7 -0
- package/dist/src/messaging/converters/calendar.js +46 -0
- package/dist/src/messaging/converters/calendar.js.map +7 -0
- package/dist/src/messaging/converters/content-converter.js +61 -0
- package/dist/src/messaging/converters/content-converter.js.map +7 -0
- package/dist/src/messaging/converters/file.js +18 -0
- package/dist/src/messaging/converters/file.js.map +7 -0
- package/dist/src/messaging/converters/folder.js +18 -0
- package/dist/src/messaging/converters/folder.js.map +7 -0
- package/dist/src/messaging/converters/hongbao.js +14 -0
- package/dist/src/messaging/converters/hongbao.js.map +7 -0
- package/dist/src/messaging/converters/image.js +16 -0
- package/dist/src/messaging/converters/image.js.map +7 -0
- package/dist/src/messaging/converters/index.js +48 -0
- package/dist/src/messaging/converters/index.js.map +7 -0
- package/dist/src/messaging/converters/interactive/card-converter.js +1040 -0
- package/dist/src/messaging/converters/interactive/card-converter.js.map +7 -0
- package/dist/src/messaging/converters/interactive/card-utils.js +36 -0
- package/dist/src/messaging/converters/interactive/card-utils.js.map +7 -0
- package/dist/src/messaging/converters/interactive/index.js +19 -0
- package/dist/src/messaging/converters/interactive/index.js.map +7 -0
- package/dist/src/messaging/converters/interactive/legacy.js +53 -0
- package/dist/src/messaging/converters/interactive/legacy.js.map +7 -0
- package/dist/src/messaging/converters/interactive/types.js +23 -0
- package/dist/src/messaging/converters/interactive/types.js.map +7 -0
- package/dist/src/messaging/converters/location.js +17 -0
- package/dist/src/messaging/converters/location.js.map +7 -0
- package/dist/src/messaging/converters/merge-forward.js +143 -0
- package/dist/src/messaging/converters/merge-forward.js.map +7 -0
- package/dist/src/messaging/converters/post.js +113 -0
- package/dist/src/messaging/converters/post.js.map +7 -0
- package/dist/src/messaging/converters/share.js +22 -0
- package/dist/src/messaging/converters/share.js.map +7 -0
- package/dist/src/messaging/converters/sticker.js +16 -0
- package/dist/src/messaging/converters/sticker.js.map +7 -0
- package/dist/src/messaging/converters/system.js +25 -0
- package/dist/src/messaging/converters/system.js.map +7 -0
- package/dist/src/messaging/converters/text.js +12 -0
- package/dist/src/messaging/converters/text.js.map +7 -0
- package/dist/src/messaging/converters/todo.js +37 -0
- package/dist/src/messaging/converters/todo.js.map +7 -0
- package/dist/src/messaging/converters/types.js +1 -0
- package/dist/src/messaging/converters/types.js.map +7 -0
- package/dist/src/messaging/converters/unknown.js +13 -0
- package/dist/src/messaging/converters/unknown.js.map +7 -0
- package/dist/src/messaging/converters/utils.js +35 -0
- package/dist/src/messaging/converters/utils.js.map +7 -0
- package/dist/src/messaging/converters/video-chat.js +21 -0
- package/dist/src/messaging/converters/video-chat.js.map +7 -0
- package/dist/src/messaging/converters/video.js +30 -0
- package/dist/src/messaging/converters/video.js.map +7 -0
- package/dist/src/messaging/converters/vote.js +24 -0
- package/dist/src/messaging/converters/vote.js.map +7 -0
- package/dist/src/messaging/inbound/dedup.js +82 -0
- package/dist/src/messaging/inbound/dedup.js.map +7 -0
- package/dist/src/messaging/inbound/dispatch-builders.js +98 -0
- package/dist/src/messaging/inbound/dispatch-builders.js.map +7 -0
- package/dist/src/messaging/inbound/dispatch-commands.js +94 -0
- package/dist/src/messaging/inbound/dispatch-commands.js.map +7 -0
- package/dist/src/messaging/inbound/dispatch-context.js +96 -0
- package/dist/src/messaging/inbound/dispatch-context.js.map +7 -0
- package/dist/src/messaging/inbound/dispatch.js +150 -0
- package/dist/src/messaging/inbound/dispatch.js.map +7 -0
- package/dist/src/messaging/inbound/enrich.js +137 -0
- package/dist/src/messaging/inbound/enrich.js.map +7 -0
- package/dist/src/messaging/inbound/gate-effects.js +28 -0
- package/dist/src/messaging/inbound/gate-effects.js.map +7 -0
- package/dist/src/messaging/inbound/gate.js +163 -0
- package/dist/src/messaging/inbound/gate.js.map +7 -0
- package/dist/src/messaging/inbound/handler.js +132 -0
- package/dist/src/messaging/inbound/handler.js.map +7 -0
- package/dist/src/messaging/inbound/media-resolver.js +70 -0
- package/dist/src/messaging/inbound/media-resolver.js.map +7 -0
- package/dist/src/messaging/inbound/mention.js +50 -0
- package/dist/src/messaging/inbound/mention.js.map +7 -0
- package/dist/src/messaging/inbound/parse-io.js +41 -0
- package/dist/src/messaging/inbound/parse-io.js.map +7 -0
- package/dist/src/messaging/inbound/parse.js +79 -0
- package/dist/src/messaging/inbound/parse.js.map +7 -0
- package/dist/src/messaging/inbound/permission.js +30 -0
- package/dist/src/messaging/inbound/permission.js.map +7 -0
- package/dist/src/messaging/inbound/policy.js +83 -0
- package/dist/src/messaging/inbound/policy.js.map +7 -0
- package/dist/src/messaging/inbound/reaction-handler.js +162 -0
- package/dist/src/messaging/inbound/reaction-handler.js.map +7 -0
- package/dist/src/messaging/inbound/user-name-cache.js +172 -0
- package/dist/src/messaging/inbound/user-name-cache.js.map +7 -0
- package/dist/src/messaging/outbound/actions.js +239 -0
- package/dist/src/messaging/outbound/actions.js.map +7 -0
- package/dist/src/messaging/outbound/chat-manage.js +74 -0
- package/dist/src/messaging/outbound/chat-manage.js.map +7 -0
- package/dist/src/messaging/outbound/deliver.js +162 -0
- package/dist/src/messaging/outbound/deliver.js.map +7 -0
- package/dist/src/messaging/outbound/fetch.js +7 -0
- package/dist/src/messaging/outbound/fetch.js.map +7 -0
- package/dist/src/messaging/outbound/forward.js +31 -0
- package/dist/src/messaging/outbound/forward.js.map +7 -0
- package/dist/src/messaging/outbound/media-url-utils.js +101 -0
- package/dist/src/messaging/outbound/media-url-utils.js.map +7 -0
- package/dist/src/messaging/outbound/media.js +463 -0
- package/dist/src/messaging/outbound/media.js.map +7 -0
- package/dist/src/messaging/outbound/outbound.js +95 -0
- package/dist/src/messaging/outbound/outbound.js.map +7 -0
- package/dist/src/messaging/outbound/reactions.js +312 -0
- package/dist/src/messaging/outbound/reactions.js.map +7 -0
- package/dist/src/messaging/outbound/send.js +194 -0
- package/dist/src/messaging/outbound/send.js.map +7 -0
- package/dist/src/messaging/outbound/typing.js +77 -0
- package/dist/src/messaging/outbound/typing.js.map +7 -0
- package/dist/src/messaging/shared/message-lookup.js +84 -0
- package/dist/src/messaging/shared/message-lookup.js.map +7 -0
- package/dist/src/messaging/types.js +1 -0
- package/dist/src/messaging/types.js.map +7 -0
- package/dist/src/tools/auto-auth.js +714 -0
- package/dist/src/tools/auto-auth.js.map +7 -0
- package/dist/src/tools/helpers.js +133 -0
- package/dist/src/tools/helpers.js.map +7 -0
- package/dist/src/tools/mcp/doc/create.js +35 -0
- package/dist/src/tools/mcp/doc/create.js.map +7 -0
- package/dist/src/tools/mcp/doc/fetch.js +33 -0
- package/dist/src/tools/mcp/doc/fetch.js.map +7 -0
- package/dist/src/tools/mcp/doc/index.js +32 -0
- package/dist/src/tools/mcp/doc/index.js.map +7 -0
- package/dist/src/tools/mcp/doc/update.js +61 -0
- package/dist/src/tools/mcp/doc/update.js.map +7 -0
- package/dist/src/tools/mcp/project/endpoint.js +25 -0
- package/dist/src/tools/mcp/project/endpoint.js.map +7 -0
- package/dist/src/tools/mcp/project/index.js +27 -0
- package/dist/src/tools/mcp/project/index.js.map +7 -0
- package/dist/src/tools/mcp/project/tools.js +579 -0
- package/dist/src/tools/mcp/project/tools.js.map +7 -0
- package/dist/src/tools/mcp/shared.js +170 -0
- package/dist/src/tools/mcp/shared.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app-table-field.js +244 -0
- package/dist/src/tools/oapi/bitable/app-table-field.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app-table-record.js +501 -0
- package/dist/src/tools/oapi/bitable/app-table-record.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app-table-view.js +226 -0
- package/dist/src/tools/oapi/bitable/app-table-view.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app-table.js +278 -0
- package/dist/src/tools/oapi/bitable/app-table.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app.js +200 -0
- package/dist/src/tools/oapi/bitable/app.js.map +7 -0
- package/dist/src/tools/oapi/bitable/index.js +13 -0
- package/dist/src/tools/oapi/bitable/index.js.map +7 -0
- package/dist/src/tools/oapi/calendar/calendar.js +131 -0
- package/dist/src/tools/oapi/calendar/calendar.js.map +7 -0
- package/dist/src/tools/oapi/calendar/event-attendee.js +301 -0
- package/dist/src/tools/oapi/calendar/event-attendee.js.map +7 -0
- package/dist/src/tools/oapi/calendar/event.js +834 -0
- package/dist/src/tools/oapi/calendar/event.js.map +7 -0
- package/dist/src/tools/oapi/calendar/freebusy.js +111 -0
- package/dist/src/tools/oapi/calendar/freebusy.js.map +7 -0
- package/dist/src/tools/oapi/calendar/index.js +11 -0
- package/dist/src/tools/oapi/calendar/index.js.map +7 -0
- package/dist/src/tools/oapi/chat/chat.js +132 -0
- package/dist/src/tools/oapi/chat/chat.js.map +7 -0
- package/dist/src/tools/oapi/chat/index.js +11 -0
- package/dist/src/tools/oapi/chat/index.js.map +7 -0
- package/dist/src/tools/oapi/chat/members.js +83 -0
- package/dist/src/tools/oapi/chat/members.js.map +7 -0
- package/dist/src/tools/oapi/common/get-user.js +95 -0
- package/dist/src/tools/oapi/common/get-user.js.map +7 -0
- package/dist/src/tools/oapi/common/index.js +7 -0
- package/dist/src/tools/oapi/common/index.js.map +7 -0
- package/dist/src/tools/oapi/common/search-user.js +67 -0
- package/dist/src/tools/oapi/common/search-user.js.map +7 -0
- package/dist/src/tools/oapi/drive/doc-comments.js +310 -0
- package/dist/src/tools/oapi/drive/doc-comments.js.map +7 -0
- package/dist/src/tools/oapi/drive/doc-media.js +314 -0
- package/dist/src/tools/oapi/drive/doc-media.js.map +7 -0
- package/dist/src/tools/oapi/drive/file.js +548 -0
- package/dist/src/tools/oapi/drive/file.js.map +7 -0
- package/dist/src/tools/oapi/drive/index.js +29 -0
- package/dist/src/tools/oapi/drive/index.js.map +7 -0
- package/dist/src/tools/oapi/helpers.js +199 -0
- package/dist/src/tools/oapi/helpers.js.map +7 -0
- package/dist/src/tools/oapi/im/format-messages.js +128 -0
- package/dist/src/tools/oapi/im/format-messages.js.map +7 -0
- package/dist/src/tools/oapi/im/index.js +15 -0
- package/dist/src/tools/oapi/im/index.js.map +7 -0
- package/dist/src/tools/oapi/im/message-read.js +404 -0
- package/dist/src/tools/oapi/im/message-read.js.map +7 -0
- package/dist/src/tools/oapi/im/message.js +179 -0
- package/dist/src/tools/oapi/im/message.js.map +7 -0
- package/dist/src/tools/oapi/im/resource.js +126 -0
- package/dist/src/tools/oapi/im/resource.js.map +7 -0
- package/dist/src/tools/oapi/im/time-utils.js +169 -0
- package/dist/src/tools/oapi/im/time-utils.js.map +7 -0
- package/dist/src/tools/oapi/im/user-name-uat.js +103 -0
- package/dist/src/tools/oapi/im/user-name-uat.js.map +7 -0
- package/dist/src/tools/oapi/index.js +56 -0
- package/dist/src/tools/oapi/index.js.map +7 -0
- package/dist/src/tools/oapi/sdk-types.js +1 -0
- package/dist/src/tools/oapi/sdk-types.js.map +7 -0
- package/dist/src/tools/oapi/search/doc-search.js +215 -0
- package/dist/src/tools/oapi/search/doc-search.js.map +7 -0
- package/dist/src/tools/oapi/search/index.js +25 -0
- package/dist/src/tools/oapi/search/index.js.map +7 -0
- package/dist/src/tools/oapi/sheets/index.js +25 -0
- package/dist/src/tools/oapi/sheets/index.js.map +7 -0
- package/dist/src/tools/oapi/sheets/sheet.js +652 -0
- package/dist/src/tools/oapi/sheets/sheet.js.map +7 -0
- package/dist/src/tools/oapi/task/comment.js +151 -0
- package/dist/src/tools/oapi/task/comment.js.map +7 -0
- package/dist/src/tools/oapi/task/index.js +11 -0
- package/dist/src/tools/oapi/task/index.js.map +7 -0
- package/dist/src/tools/oapi/task/subtask.js +175 -0
- package/dist/src/tools/oapi/task/subtask.js.map +7 -0
- package/dist/src/tools/oapi/task/task.js +405 -0
- package/dist/src/tools/oapi/task/task.js.map +7 -0
- package/dist/src/tools/oapi/task/tasklist.js +366 -0
- package/dist/src/tools/oapi/task/tasklist.js.map +7 -0
- package/dist/src/tools/oapi/wiki/index.js +27 -0
- package/dist/src/tools/oapi/wiki/index.js.map +7 -0
- package/dist/src/tools/oapi/wiki/space-node.js +311 -0
- package/dist/src/tools/oapi/wiki/space-node.js.map +7 -0
- package/dist/src/tools/oapi/wiki/space.js +148 -0
- package/dist/src/tools/oapi/wiki/space.js.map +7 -0
- package/dist/src/tools/oauth-batch-auth.js +125 -0
- package/dist/src/tools/oauth-batch-auth.js.map +7 -0
- package/dist/src/tools/oauth-cards.js +269 -0
- package/dist/src/tools/oauth-cards.js.map +7 -0
- package/dist/src/tools/oauth.js +538 -0
- package/dist/src/tools/oauth.js.map +7 -0
- package/dist/src/tools/onboarding-auth.js +101 -0
- package/dist/src/tools/onboarding-auth.js.map +7 -0
- package/dist/src/tools/project-oauth.js +305 -0
- package/dist/src/tools/project-oauth.js.map +7 -0
- package/dist/src/tools/tat/im/index.js +9 -0
- package/dist/src/tools/tat/im/index.js.map +7 -0
- package/dist/src/tools/tat/im/resource.js +123 -0
- package/dist/src/tools/tat/im/resource.js.map +7 -0
- package/package.json +64 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createReplyPrefixContext,
|
|
3
|
+
createTypingCallbacks,
|
|
4
|
+
logTypingFailure
|
|
5
|
+
} from "openclaw/plugin-sdk";
|
|
6
|
+
import { getLarkAccount } from "../core/accounts";
|
|
7
|
+
import { resolveFooterConfig } from "../core/footer-config";
|
|
8
|
+
import { LarkClient } from "../core/lark-client";
|
|
9
|
+
import { larkLogger } from "../core/lark-logger";
|
|
10
|
+
import { sendMessageFeishu, sendMarkdownCardFeishu } from "../messaging/outbound/send";
|
|
11
|
+
import { addTypingIndicator, removeTypingIndicator } from "../messaging/outbound/typing";
|
|
12
|
+
import { resolveReplyMode, expandAutoMode, shouldUseCard } from "./reply-mode";
|
|
13
|
+
import { StreamingCardController } from "./streaming-card-controller";
|
|
14
|
+
import { UnavailableGuard } from "./unavailable-guard";
|
|
15
|
+
const log = larkLogger("card/reply-dispatcher");
|
|
16
|
+
function createFeishuReplyDispatcher(params) {
|
|
17
|
+
const core = LarkClient.runtime;
|
|
18
|
+
const { cfg, agentId, chatId, replyToMessageId, accountId, replyInThread } = params;
|
|
19
|
+
const account = getLarkAccount(cfg, accountId);
|
|
20
|
+
const feishuCfg = account.config;
|
|
21
|
+
const prefixContext = createReplyPrefixContext({ cfg, agentId });
|
|
22
|
+
const chatType = params.chatType;
|
|
23
|
+
const effectiveReplyMode = resolveReplyMode({ feishuCfg, chatType });
|
|
24
|
+
const replyMode = expandAutoMode({
|
|
25
|
+
mode: effectiveReplyMode,
|
|
26
|
+
streaming: feishuCfg?.streaming,
|
|
27
|
+
chatType
|
|
28
|
+
});
|
|
29
|
+
const useStreamingCards = replyMode === "streaming";
|
|
30
|
+
const enableBlockStreaming = feishuCfg?.blockStreaming === true && !useStreamingCards;
|
|
31
|
+
const resolvedFooter = resolveFooterConfig(feishuCfg?.footer);
|
|
32
|
+
log.info("reply mode resolved", {
|
|
33
|
+
effectiveReplyMode,
|
|
34
|
+
replyMode,
|
|
35
|
+
chatType
|
|
36
|
+
});
|
|
37
|
+
const textChunkLimit = core.channel.text.resolveTextChunkLimit(cfg, "feishu", accountId, { fallbackLimit: 4e3 });
|
|
38
|
+
const chunkMode = core.channel.text.resolveChunkMode(cfg, "feishu");
|
|
39
|
+
const tableMode = core.channel.text.resolveMarkdownTableMode({
|
|
40
|
+
cfg,
|
|
41
|
+
channel: "feishu"
|
|
42
|
+
});
|
|
43
|
+
const controller = useStreamingCards ? new StreamingCardController({
|
|
44
|
+
cfg,
|
|
45
|
+
accountId,
|
|
46
|
+
chatId,
|
|
47
|
+
replyToMessageId,
|
|
48
|
+
replyInThread,
|
|
49
|
+
resolvedFooter
|
|
50
|
+
}) : null;
|
|
51
|
+
let staticAborted = false;
|
|
52
|
+
const staticGuard = controller ? null : new UnavailableGuard({
|
|
53
|
+
replyToMessageId,
|
|
54
|
+
getCardMessageId: () => null,
|
|
55
|
+
onTerminate: () => {
|
|
56
|
+
staticAborted = true;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const shouldSkip = (source) => {
|
|
60
|
+
if (controller) return controller.shouldSkipForUnavailable(source);
|
|
61
|
+
return staticGuard?.shouldSkip(source) ?? false;
|
|
62
|
+
};
|
|
63
|
+
const isTerminated = () => {
|
|
64
|
+
if (controller) return controller.isTerminated;
|
|
65
|
+
return staticGuard?.isTerminated ?? false;
|
|
66
|
+
};
|
|
67
|
+
let typingState = null;
|
|
68
|
+
let typingStopped = false;
|
|
69
|
+
const typingCallbacks = createTypingCallbacks({
|
|
70
|
+
keepaliveIntervalMs: 0,
|
|
71
|
+
start: async () => {
|
|
72
|
+
if (shouldSkip("typing.start.precheck")) return;
|
|
73
|
+
if (!replyToMessageId || typingStopped || params.skipTyping) return;
|
|
74
|
+
if (typingState?.reactionId) return;
|
|
75
|
+
typingState = await addTypingIndicator({
|
|
76
|
+
cfg,
|
|
77
|
+
messageId: replyToMessageId,
|
|
78
|
+
accountId
|
|
79
|
+
});
|
|
80
|
+
if (shouldSkip("typing.start.postcheck")) return;
|
|
81
|
+
if (typingStopped && typingState) {
|
|
82
|
+
await removeTypingIndicator({ cfg, state: typingState, accountId });
|
|
83
|
+
typingState = null;
|
|
84
|
+
log.info("removed typing indicator (raced with stop)");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
log.info("added typing indicator reaction");
|
|
88
|
+
},
|
|
89
|
+
stop: async () => {
|
|
90
|
+
typingStopped = true;
|
|
91
|
+
if (!typingState) return;
|
|
92
|
+
await removeTypingIndicator({ cfg, state: typingState, accountId });
|
|
93
|
+
typingState = null;
|
|
94
|
+
log.info("removed typing indicator reaction");
|
|
95
|
+
},
|
|
96
|
+
onStartError: (err) => {
|
|
97
|
+
logTypingFailure({
|
|
98
|
+
log: (message) => log.warn(message),
|
|
99
|
+
channel: "feishu",
|
|
100
|
+
action: "start",
|
|
101
|
+
error: err
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
onStopError: (err) => {
|
|
105
|
+
logTypingFailure({
|
|
106
|
+
log: (message) => log.warn(message),
|
|
107
|
+
channel: "feishu",
|
|
108
|
+
action: "stop",
|
|
109
|
+
error: err
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
let dispatchFullyComplete = false;
|
|
114
|
+
const { dispatcher, replyOptions, markDispatchIdle } = core.channel.reply.createReplyDispatcherWithTyping({
|
|
115
|
+
responsePrefix: prefixContext.responsePrefix,
|
|
116
|
+
responsePrefixContextProvider: prefixContext.responsePrefixContextProvider,
|
|
117
|
+
humanDelay: core.channel.reply.resolveHumanDelayConfig(cfg, agentId),
|
|
118
|
+
onReplyStart: async () => {
|
|
119
|
+
if (shouldSkip("onReplyStart")) return;
|
|
120
|
+
await typingCallbacks.onReplyStart?.();
|
|
121
|
+
},
|
|
122
|
+
deliver: async (payload) => {
|
|
123
|
+
log.debug("deliver called", { textPreview: payload.text?.slice(0, 100) });
|
|
124
|
+
if (shouldSkip("deliver.entry")) return;
|
|
125
|
+
if (staticAborted || controller?.isTerminated || controller?.isAborted) {
|
|
126
|
+
log.debug("deliver: skipped (aborted)");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (dispatchFullyComplete) {
|
|
130
|
+
log.debug("deliver: skipped (dispatch already complete)");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const text = payload.text ?? "";
|
|
134
|
+
if (!text.trim()) {
|
|
135
|
+
log.debug("deliver: empty text, skipping");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (controller) {
|
|
139
|
+
await controller.ensureCardCreated();
|
|
140
|
+
if (controller.isTerminated) return;
|
|
141
|
+
if (controller.cardMessageId) {
|
|
142
|
+
await controller.onDeliver(payload);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
log.warn("deliver: card creation failed, falling back to static delivery");
|
|
146
|
+
}
|
|
147
|
+
if (shouldUseCard(text)) {
|
|
148
|
+
const chunks = core.channel.text.chunkTextWithMode(text, textChunkLimit, chunkMode);
|
|
149
|
+
log.info("deliver: sending card chunks", { count: chunks.length, chatId });
|
|
150
|
+
for (const chunk of chunks) {
|
|
151
|
+
try {
|
|
152
|
+
await sendMarkdownCardFeishu({
|
|
153
|
+
cfg,
|
|
154
|
+
to: chatId,
|
|
155
|
+
text: chunk,
|
|
156
|
+
replyToMessageId,
|
|
157
|
+
replyInThread,
|
|
158
|
+
accountId
|
|
159
|
+
});
|
|
160
|
+
} catch (err) {
|
|
161
|
+
if (staticGuard?.terminate("deliver.cardChunk", err)) return;
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
const converted = core.channel.text.convertMarkdownTables(text, tableMode);
|
|
167
|
+
const chunks = core.channel.text.chunkTextWithMode(converted, textChunkLimit, chunkMode);
|
|
168
|
+
log.info("deliver: sending text chunks", { count: chunks.length, chatId });
|
|
169
|
+
for (const chunk of chunks) {
|
|
170
|
+
try {
|
|
171
|
+
await sendMessageFeishu({
|
|
172
|
+
cfg,
|
|
173
|
+
to: chatId,
|
|
174
|
+
text: chunk,
|
|
175
|
+
replyToMessageId,
|
|
176
|
+
replyInThread,
|
|
177
|
+
accountId
|
|
178
|
+
});
|
|
179
|
+
} catch (err) {
|
|
180
|
+
if (staticGuard?.terminate("deliver.textChunk", err)) return;
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
onError: async (err, info) => {
|
|
187
|
+
if (controller) {
|
|
188
|
+
if (controller.terminateIfUnavailable("onError", err)) {
|
|
189
|
+
typingCallbacks.onIdle?.();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
await controller.onError(err, info);
|
|
193
|
+
typingCallbacks.onIdle?.();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (staticGuard?.terminate("onError", err)) {
|
|
197
|
+
typingCallbacks.onIdle?.();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
log.error(`${info.kind} reply failed`, { error: String(err) });
|
|
201
|
+
typingCallbacks.onIdle?.();
|
|
202
|
+
},
|
|
203
|
+
onIdle: async () => {
|
|
204
|
+
if (isTerminated() || shouldSkip("onIdle")) {
|
|
205
|
+
typingCallbacks.onIdle?.();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
if (!dispatchFullyComplete) {
|
|
209
|
+
typingCallbacks.onIdle?.();
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (controller) {
|
|
213
|
+
await controller.onIdle();
|
|
214
|
+
}
|
|
215
|
+
typingCallbacks.onIdle?.();
|
|
216
|
+
},
|
|
217
|
+
onCleanup: async () => {
|
|
218
|
+
typingCallbacks.onCleanup?.();
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
const abortCard = controller ? () => controller.abortCard() : async () => {
|
|
222
|
+
};
|
|
223
|
+
return {
|
|
224
|
+
dispatcher,
|
|
225
|
+
replyOptions: {
|
|
226
|
+
...replyOptions,
|
|
227
|
+
onModelSelected: prefixContext.onModelSelected,
|
|
228
|
+
disableBlockStreaming: !enableBlockStreaming,
|
|
229
|
+
...controller ? {
|
|
230
|
+
onReasoningStream: (payload) => controller.onReasoningStream(payload),
|
|
231
|
+
onPartialReply: (payload) => controller.onPartialReply(payload)
|
|
232
|
+
} : {}
|
|
233
|
+
},
|
|
234
|
+
markDispatchIdle,
|
|
235
|
+
markFullyComplete: () => {
|
|
236
|
+
dispatchFullyComplete = true;
|
|
237
|
+
controller?.markFullyComplete();
|
|
238
|
+
},
|
|
239
|
+
abortCard
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
export {
|
|
243
|
+
createFeishuReplyDispatcher
|
|
244
|
+
};
|
|
245
|
+
//# sourceMappingURL=reply-dispatcher.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/card/reply-dispatcher.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Reply dispatcher factory for the Lark/Feishu channel plugin.\n *\n * Thin factory function that:\n * 1. Resolves account, reply mode, and typing indicator config\n * 2. In streaming mode, delegates to StreamingCardController\n * 3. In static mode, delivers via sendMessageFeishu / sendMarkdownCardFeishu\n * 4. Assembles and returns FeishuReplyDispatcherResult\n */\n\nimport {\n createReplyPrefixContext,\n createTypingCallbacks,\n logTypingFailure,\n type ReplyPayload,\n} from 'openclaw/plugin-sdk';\nimport { getLarkAccount } from '../core/accounts';\nimport { resolveFooterConfig } from '../core/footer-config';\nimport { LarkClient } from '../core/lark-client';\nimport { larkLogger } from '../core/lark-logger';\nimport { sendMessageFeishu, sendMarkdownCardFeishu } from '../messaging/outbound/send';\nimport { addTypingIndicator, removeTypingIndicator, type TypingIndicatorState } from '../messaging/outbound/typing';\nimport { resolveReplyMode, expandAutoMode, shouldUseCard } from './reply-mode';\nimport { StreamingCardController } from './streaming-card-controller';\nimport { UnavailableGuard } from './unavailable-guard';\nimport type { CreateFeishuReplyDispatcherParams, FeishuReplyDispatcherResult } from './reply-dispatcher-types';\n\nconst log = larkLogger('card/reply-dispatcher');\n\n// Re-export the params type for backward compatibility with dispatch.ts\nexport type { CreateFeishuReplyDispatcherParams } from './reply-dispatcher-types';\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherParams): FeishuReplyDispatcherResult {\n const core = LarkClient.runtime;\n const { cfg, agentId, chatId, replyToMessageId, accountId, replyInThread } = params;\n\n // Resolve account so we can read per-account config (e.g. replyMode)\n const account = getLarkAccount(cfg, accountId);\n const feishuCfg = account.config;\n\n const prefixContext = createReplyPrefixContext({ cfg, agentId });\n\n // ---- Reply mode resolution ----\n const chatType = params.chatType;\n const effectiveReplyMode = resolveReplyMode({ feishuCfg, chatType });\n const replyMode = expandAutoMode({\n mode: effectiveReplyMode,\n streaming: feishuCfg?.streaming,\n chatType,\n });\n const useStreamingCards = replyMode === 'streaming';\n\n // ---- Block streaming for static mode ----\n const enableBlockStreaming = feishuCfg?.blockStreaming === true && !useStreamingCards;\n\n const resolvedFooter = resolveFooterConfig(feishuCfg?.footer);\n\n log.info('reply mode resolved', {\n effectiveReplyMode,\n replyMode,\n chatType,\n });\n\n // ---- Chunk & render settings (static mode only) ----\n const textChunkLimit = core.channel.text.resolveTextChunkLimit(cfg, 'feishu', accountId, { fallbackLimit: 4000 });\n const chunkMode = core.channel.text.resolveChunkMode(cfg, 'feishu');\n const tableMode = core.channel.text.resolveMarkdownTableMode({\n cfg,\n channel: 'feishu',\n });\n\n // ---- Streaming card controller (instantiated only when needed) ----\n const controller = useStreamingCards\n ? new StreamingCardController({\n cfg,\n accountId,\n chatId,\n replyToMessageId,\n replyInThread,\n resolvedFooter,\n })\n : null;\n\n // ---- Static mode unavailable guard ----\n // In streaming mode the controller owns its own guard; in static mode\n // we still need unavailable-message detection for typing and deliver.\n let staticAborted = false;\n const staticGuard = controller\n ? null\n : new UnavailableGuard({\n replyToMessageId,\n getCardMessageId: () => null,\n onTerminate: () => {\n staticAborted = true;\n },\n });\n\n const shouldSkip = (source: string): boolean => {\n if (controller) return controller.shouldSkipForUnavailable(source);\n return staticGuard?.shouldSkip(source) ?? false;\n };\n\n const isTerminated = (): boolean => {\n if (controller) return controller.isTerminated;\n return staticGuard?.isTerminated ?? false;\n };\n\n // ---- Typing indicator (reaction-based) ----\n let typingState: TypingIndicatorState | null = null;\n let typingStopped = false;\n\n const typingCallbacks = createTypingCallbacks({\n keepaliveIntervalMs: 0,\n start: async () => {\n if (shouldSkip('typing.start.precheck')) return;\n if (!replyToMessageId || typingStopped || params.skipTyping) return;\n if (typingState?.reactionId) return;\n\n typingState = await addTypingIndicator({\n cfg,\n messageId: replyToMessageId,\n accountId,\n });\n if (shouldSkip('typing.start.postcheck')) return;\n\n if (typingStopped && typingState) {\n await removeTypingIndicator({ cfg, state: typingState, accountId });\n typingState = null;\n log.info('removed typing indicator (raced with stop)');\n return;\n }\n log.info('added typing indicator reaction');\n },\n stop: async () => {\n typingStopped = true;\n if (!typingState) return;\n await removeTypingIndicator({ cfg, state: typingState, accountId });\n typingState = null;\n log.info('removed typing indicator reaction');\n },\n onStartError: (err) => {\n logTypingFailure({\n log: (message) => log.warn(message),\n channel: 'feishu',\n action: 'start',\n error: err,\n });\n },\n onStopError: (err) => {\n logTypingFailure({\n log: (message) => log.warn(message),\n channel: 'feishu',\n action: 'stop',\n error: err,\n });\n },\n });\n\n // ---- dispatchFullyComplete flag (static mode) ----\n let dispatchFullyComplete = false;\n\n // ---- Build dispatcher ----\n const { dispatcher, replyOptions, markDispatchIdle } = core.channel.reply.createReplyDispatcherWithTyping({\n responsePrefix: prefixContext.responsePrefix,\n responsePrefixContextProvider: prefixContext.responsePrefixContextProvider,\n humanDelay: core.channel.reply.resolveHumanDelayConfig(cfg, agentId),\n\n onReplyStart: async () => {\n if (shouldSkip('onReplyStart')) return;\n await typingCallbacks.onReplyStart?.();\n },\n\n deliver: async (payload: ReplyPayload) => {\n log.debug('deliver called', { textPreview: payload.text?.slice(0, 100) });\n\n if (shouldSkip('deliver.entry')) return;\n\n // ---- Abort guard ----\n // Only check aborted (not isTerminalPhase) so that\n // creation_failed can still fallthrough to static delivery.\n if (staticAborted || controller?.isTerminated || controller?.isAborted) {\n log.debug('deliver: skipped (aborted)');\n return;\n }\n\n // ---- Post-dispatch guard ----\n if (dispatchFullyComplete) {\n log.debug('deliver: skipped (dispatch already complete)');\n return;\n }\n\n const text = payload.text ?? '';\n if (!text.trim()) {\n log.debug('deliver: empty text, skipping');\n return;\n }\n\n // ---- Streaming card mode ----\n if (controller) {\n await controller.ensureCardCreated();\n if (controller.isTerminated) return;\n\n if (controller.cardMessageId) {\n await controller.onDeliver(payload);\n return;\n }\n // Card creation failed \u2014 fall through to static delivery\n log.warn('deliver: card creation failed, falling back to static delivery');\n }\n\n // ---- Static delivery ----\n if (shouldUseCard(text)) {\n const chunks = core.channel.text.chunkTextWithMode(text, textChunkLimit, chunkMode);\n log.info('deliver: sending card chunks', { count: chunks.length, chatId });\n for (const chunk of chunks) {\n try {\n await sendMarkdownCardFeishu({\n cfg,\n to: chatId,\n text: chunk,\n replyToMessageId,\n replyInThread,\n accountId,\n });\n } catch (err) {\n if (staticGuard?.terminate('deliver.cardChunk', err)) return;\n throw err;\n }\n }\n } else {\n const converted = core.channel.text.convertMarkdownTables(text, tableMode);\n const chunks = core.channel.text.chunkTextWithMode(converted, textChunkLimit, chunkMode);\n log.info('deliver: sending text chunks', { count: chunks.length, chatId });\n for (const chunk of chunks) {\n try {\n await sendMessageFeishu({\n cfg,\n to: chatId,\n text: chunk,\n replyToMessageId,\n replyInThread,\n accountId,\n });\n } catch (err) {\n if (staticGuard?.terminate('deliver.textChunk', err)) return;\n throw err;\n }\n }\n }\n },\n\n onError: async (err, info) => {\n if (controller) {\n if (controller.terminateIfUnavailable('onError', err)) {\n typingCallbacks.onIdle?.();\n return;\n }\n await controller.onError(err, info);\n typingCallbacks.onIdle?.();\n return;\n }\n\n // Static mode error handling\n if (staticGuard?.terminate('onError', err)) {\n typingCallbacks.onIdle?.();\n return;\n }\n log.error(`${info.kind} reply failed`, { error: String(err) });\n typingCallbacks.onIdle?.();\n },\n\n onIdle: async () => {\n if (isTerminated() || shouldSkip('onIdle')) {\n typingCallbacks.onIdle?.();\n return;\n }\n\n if (!dispatchFullyComplete) {\n typingCallbacks.onIdle?.();\n return;\n }\n\n if (controller) {\n await controller.onIdle();\n }\n\n typingCallbacks.onIdle?.();\n },\n\n onCleanup: async () => {\n typingCallbacks.onCleanup?.();\n },\n });\n\n // ---- Abort card (delegates to controller or no-op for static) ----\n const abortCard = controller ? () => controller.abortCard() : async () => {};\n\n return {\n dispatcher,\n replyOptions: {\n ...replyOptions,\n onModelSelected: prefixContext.onModelSelected,\n disableBlockStreaming: !enableBlockStreaming,\n ...(controller\n ? {\n onReasoningStream: (payload: ReplyPayload) => controller.onReasoningStream(payload),\n onPartialReply: (payload: ReplyPayload) => controller.onPartialReply(payload),\n }\n : {}),\n },\n markDispatchIdle,\n markFullyComplete: () => {\n dispatchFullyComplete = true;\n controller?.markFullyComplete();\n },\n abortCard,\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function resolveReplyMode(params) {
|
|
2
|
+
const { feishuCfg, chatType } = params;
|
|
3
|
+
if (feishuCfg?.streaming !== true) return "static";
|
|
4
|
+
const replyMode = feishuCfg?.replyMode;
|
|
5
|
+
if (!replyMode) return "auto";
|
|
6
|
+
if (typeof replyMode === "string") return replyMode;
|
|
7
|
+
const sceneMode = chatType === "group" ? replyMode.group : chatType === "p2p" ? replyMode.direct : void 0;
|
|
8
|
+
return sceneMode ?? replyMode.default ?? "auto";
|
|
9
|
+
}
|
|
10
|
+
function expandAutoMode(params) {
|
|
11
|
+
const { mode, streaming, chatType } = params;
|
|
12
|
+
if (mode !== "auto") return mode;
|
|
13
|
+
return streaming === true ? chatType === "group" ? "static" : "streaming" : "static";
|
|
14
|
+
}
|
|
15
|
+
function shouldUseCard(text) {
|
|
16
|
+
if (/```[\s\S]*?```/.test(text)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (/\|.+\|[\r\n]+\|[-:| ]+\|/.test(text)) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
expandAutoMode,
|
|
26
|
+
resolveReplyMode,
|
|
27
|
+
shouldUseCard
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=reply-mode.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/card/reply-mode.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Pure functions for resolving the Feishu reply mode.\n *\n * Extracted from reply-dispatcher.ts to enable independent testing\n * and eliminate `as any` casts on FeishuConfig.\n */\n\nimport type { FeishuConfig } from '../core/types';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype ReplyModeValue = 'auto' | 'static' | 'streaming';\n\n// ---------------------------------------------------------------------------\n// resolveReplyMode\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the effective reply mode based on configuration and chat type.\n *\n * Priority: replyMode.{scene} > replyMode.default > replyMode (string) > \"auto\"\n */\nexport function resolveReplyMode(params: {\n feishuCfg: FeishuConfig | undefined;\n chatType?: 'p2p' | 'group';\n}): ReplyModeValue {\n const { feishuCfg, chatType } = params;\n\n // streaming \u5E03\u5C14\u603B\u5F00\u5173\uFF1A\u4EC5 true \u65F6\u5141\u8BB8\u6D41\u5F0F\uFF0C\u672A\u8BBE\u7F6E\u6216 false \u4E00\u5F8B static\n if (feishuCfg?.streaming !== true) return 'static';\n\n const replyMode = feishuCfg?.replyMode;\n if (!replyMode) return 'auto';\n\n if (typeof replyMode === 'string') return replyMode;\n\n // Object form: pick scene-specific value\n const sceneMode = chatType === 'group' ? replyMode.group : chatType === 'p2p' ? replyMode.direct : undefined;\n return sceneMode ?? replyMode.default ?? 'auto';\n}\n\n// ---------------------------------------------------------------------------\n// expandAutoMode\n// ---------------------------------------------------------------------------\n\n/**\n * Expand \"auto\" mode to a concrete mode based on streaming flag and chat type.\n *\n * When streaming === true: group \u2192 static, direct \u2192 streaming (legacy behavior).\n * When streaming is unset: always static (new default).\n */\nexport function expandAutoMode(params: {\n mode: ReplyModeValue;\n streaming: boolean | undefined;\n chatType?: 'p2p' | 'group';\n}): 'static' | 'streaming' {\n const { mode, streaming, chatType } = params;\n if (mode !== 'auto') return mode;\n\n return streaming === true ? (chatType === 'group' ? 'static' : 'streaming') : 'static';\n}\n\n// ---------------------------------------------------------------------------\n// shouldUseCard\n// ---------------------------------------------------------------------------\n\n/**\n * Detect whether the text contains markdown elements that benefit from\n * being rendered inside a Feishu interactive card (fenced code blocks or\n * markdown tables).\n */\nexport function shouldUseCard(text: string): boolean {\n // Fenced code blocks\n if (/```[\\s\\S]*?```/.test(text)) {\n return true;\n }\n // Markdown tables (header + separator rows separated by pipes)\n if (/\\|.+\\|[\\r\\n]+\\|[-:| ]+\\|/.test(text)) {\n return true;\n }\n return false;\n}\n"],
|
|
5
|
+
"mappings": "AA2BO,SAAS,iBAAiB,QAGd;AACjB,QAAM,EAAE,WAAW,SAAS,IAAI;AAGhC,MAAI,WAAW,cAAc,KAAM,QAAO;AAE1C,QAAM,YAAY,WAAW;AAC7B,MAAI,CAAC,UAAW,QAAO;AAEvB,MAAI,OAAO,cAAc,SAAU,QAAO;AAG1C,QAAM,YAAY,aAAa,UAAU,UAAU,QAAQ,aAAa,QAAQ,UAAU,SAAS;AACnG,SAAO,aAAa,UAAU,WAAW;AAC3C;AAYO,SAAS,eAAe,QAIJ;AACzB,QAAM,EAAE,MAAM,WAAW,SAAS,IAAI;AACtC,MAAI,SAAS,OAAQ,QAAO;AAE5B,SAAO,cAAc,OAAQ,aAAa,UAAU,WAAW,cAAe;AAChF;AAWO,SAAS,cAAc,MAAuB;AAEnD,MAAI,iBAAiB,KAAK,IAAI,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,2BAA2B,KAAK,IAAI,GAAG;AACzC,WAAO;AAAA,EACT;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|