@zhin.js/core 1.3.2 → 1.3.4
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/README.md +7 -7
- package/lib/adapter.d.ts +22 -2
- package/lib/adapter.js +72 -2
- package/lib/agent-prompt.d.ts +0 -1
- package/lib/agent-prompt.js +0 -1
- package/lib/built/adapter-process.d.ts +0 -1
- package/lib/built/adapter-process.js +0 -1
- package/lib/built/agent-preset.d.ts +0 -1
- package/lib/built/agent-preset.js +0 -1
- package/lib/built/ai-access.d.ts +36 -0
- package/lib/built/ai-access.js +46 -0
- package/lib/built/ai-outbound/adapter-access.d.ts +3 -0
- package/lib/built/ai-outbound/adapter-access.js +9 -0
- package/lib/built/ai-outbound/extensions/onebot-keyboard.d.ts +2 -0
- package/lib/built/ai-outbound/extensions/onebot-keyboard.js +67 -0
- package/lib/built/ai-outbound/extensions/qq-message.d.ts +3 -0
- package/lib/built/ai-outbound/extensions/qq-message.js +23 -0
- package/lib/built/ai-outbound/index.d.ts +9 -0
- package/lib/built/ai-outbound/index.js +9 -0
- package/lib/built/ai-outbound/parse.d.ts +13 -0
- package/lib/built/ai-outbound/parse.js +108 -0
- package/lib/built/ai-outbound/plain-mention-rewrite.d.ts +6 -0
- package/lib/built/ai-outbound/plain-mention-rewrite.js +37 -0
- package/lib/built/ai-outbound/prompt.d.ts +11 -0
- package/lib/built/ai-outbound/prompt.js +44 -0
- package/lib/built/ai-outbound/resolve.d.ts +4 -0
- package/lib/built/ai-outbound/resolve.js +64 -0
- package/lib/built/ai-outbound/structured-detect.d.ts +3 -0
- package/lib/built/ai-outbound/structured-detect.js +7 -0
- package/lib/built/ai-outbound/types.d.ts +60 -0
- package/lib/built/ai-outbound/types.js +5 -0
- package/lib/built/ai-trigger.d.ts +5 -1
- package/lib/built/ai-trigger.js +3 -7
- package/lib/built/authorization.d.ts +0 -1
- package/lib/built/authorization.js +0 -1
- package/lib/built/command.d.ts +0 -1
- package/lib/built/command.js +1 -3
- package/lib/built/common-adapter-tools.d.ts +25 -26
- package/lib/built/common-adapter-tools.js +48 -49
- package/lib/built/component.d.ts +1 -3
- package/lib/built/component.js +2 -4
- package/lib/built/config.d.ts +4 -1
- package/lib/built/config.js +26 -5
- package/lib/built/connect-endpoint-instance.d.ts +0 -1
- package/lib/built/connect-endpoint-instance.js +3 -2
- package/lib/built/database.d.ts +1 -3
- package/lib/built/database.js +2 -4
- package/lib/built/dispatcher.d.ts +7 -7
- package/lib/built/dispatcher.js +20 -8
- package/lib/built/endpoint-commands.d.ts +0 -1
- package/lib/built/endpoint-commands.js +6 -9
- package/lib/built/endpoint-lifecycle-service.d.ts +2 -1
- package/lib/built/endpoint-lifecycle-service.js +26 -3
- package/lib/built/endpoint-lifecycle.d.ts +0 -1
- package/lib/built/endpoint-lifecycle.js +4 -4
- package/lib/built/endpoint-manager.d.ts +0 -1
- package/lib/built/endpoint-manager.js +0 -1
- package/lib/built/generated-qrcode.d.ts +0 -1
- package/lib/built/generated-qrcode.js +0 -1
- package/lib/built/generic-segment-mapper.d.ts +6 -0
- package/lib/built/generic-segment-mapper.js +232 -0
- package/lib/built/html-renderer-loader.d.ts +2 -1
- package/lib/built/html-renderer-loader.js +6 -2
- package/lib/built/html-segment-fallback.d.ts +0 -1
- package/lib/built/html-segment-fallback.js +0 -1
- package/lib/built/html-to-text.d.ts +0 -1
- package/lib/built/html-to-text.js +15 -15
- package/lib/built/inbound-pipeline.d.ts +1 -2
- package/lib/built/inbound-pipeline.js +1 -2
- package/lib/built/inbound-runner.d.ts +0 -1
- package/lib/built/inbound-runner.js +0 -1
- package/lib/built/interactive-segment-contract.d.ts +6 -0
- package/lib/built/interactive-segment-contract.js +9 -0
- package/lib/built/interactive-segments/action.d.ts +17 -0
- package/lib/built/interactive-segments/action.js +69 -0
- package/lib/built/interactive-segments/button-spec.d.ts +10 -0
- package/lib/built/interactive-segments/button-spec.js +21 -0
- package/lib/built/interactive-segments/handlers.d.ts +9 -0
- package/lib/built/interactive-segments/handlers.js +58 -0
- package/lib/built/interactive-segments/index.d.ts +7 -0
- package/lib/built/interactive-segments/index.js +7 -0
- package/lib/built/interactive-segments/keyboard-segment.d.ts +12 -0
- package/lib/built/interactive-segments/keyboard-segment.js +13 -0
- package/lib/built/interactive-segments/onebot-keyboard.d.ts +10 -0
- package/lib/built/interactive-segments/onebot-keyboard.js +53 -0
- package/lib/built/interactive-segments/resolve.d.ts +9 -0
- package/lib/built/interactive-segments/resolve.js +84 -0
- package/lib/built/interactive-segments/types.d.ts +62 -0
- package/lib/built/interactive-segments/types.js +13 -0
- package/lib/built/introspection-format.d.ts +0 -1
- package/lib/built/introspection-format.js +1 -1
- package/lib/built/login-assist.d.ts +0 -1
- package/lib/built/login-assist.js +0 -1
- package/lib/built/management-command-guard.d.ts +5 -1
- package/lib/built/management-command-guard.js +5 -1
- package/lib/built/message-enrich.d.ts +1 -2
- package/lib/built/message-enrich.js +0 -1
- package/lib/built/message-filter.d.ts +0 -1
- package/lib/built/message-filter.js +1 -3
- package/lib/built/optional-peer-import.d.ts +3 -0
- package/lib/built/optional-peer-import.js +33 -0
- package/lib/built/outbound-media-contract.d.ts +0 -1
- package/lib/built/outbound-media-contract.js +0 -1
- package/lib/built/outbound-media-utils.d.ts +0 -1
- package/lib/built/outbound-media-utils.js +0 -1
- package/lib/built/permission.d.ts +0 -1
- package/lib/built/permission.js +1 -3
- package/lib/built/permit-check.d.ts +1 -2
- package/lib/built/permit-check.js +0 -1
- package/lib/built/permit-parse.d.ts +0 -1
- package/lib/built/permit-parse.js +0 -1
- package/lib/built/platform-permit.d.ts +5 -6
- package/lib/built/platform-permit.js +11 -12
- package/lib/built/prepend-quote-context.d.ts +0 -1
- package/lib/built/prepend-quote-context.js +0 -1
- package/lib/built/qrcode-segment.d.ts +0 -1
- package/lib/built/qrcode-segment.js +0 -1
- package/lib/built/queue-im-field-contract.d.ts +6 -1
- package/lib/built/queue-im-field-contract.js +10 -1
- package/lib/built/rich-segments/adapter-policies.d.ts +1 -2
- package/lib/built/rich-segments/adapter-policies.js +0 -1
- package/lib/built/rich-segments/base.d.ts +0 -1
- package/lib/built/rich-segments/base.js +0 -1
- package/lib/built/rich-segments/builtins.d.ts +0 -1
- package/lib/built/rich-segments/builtins.js +0 -1
- package/lib/built/rich-segments/capabilities.d.ts +0 -1
- package/lib/built/rich-segments/capabilities.js +0 -1
- package/lib/built/rich-segments/html-segment.d.ts +1 -2
- package/lib/built/rich-segments/html-segment.js +0 -1
- package/lib/built/rich-segments/index.d.ts +0 -1
- package/lib/built/rich-segments/index.js +0 -1
- package/lib/built/rich-segments/markdown-segment.d.ts +1 -2
- package/lib/built/rich-segments/markdown-segment.js +0 -1
- package/lib/built/rich-segments/markdown-to-text.d.ts +0 -1
- package/lib/built/rich-segments/markdown-to-text.js +0 -1
- package/lib/built/rich-segments/qrcode-segment.d.ts +1 -2
- package/lib/built/rich-segments/qrcode-segment.js +0 -1
- package/lib/built/rich-segments/registry.d.ts +0 -1
- package/lib/built/rich-segments/registry.js +0 -1
- package/lib/built/rich-segments/resolve.d.ts +1 -2
- package/lib/built/rich-segments/resolve.js +0 -1
- package/lib/built/rich-segments/tts-segment.d.ts +1 -2
- package/lib/built/rich-segments/tts-segment.js +0 -1
- package/lib/built/rich-segments/types.d.ts +0 -1
- package/lib/built/rich-segments/types.js +0 -1
- package/lib/built/roles.d.ts +0 -1
- package/lib/built/roles.js +0 -1
- package/lib/built/runtime-io.d.ts +0 -1
- package/lib/built/runtime-io.js +0 -1
- package/lib/built/schedule.d.ts +54 -0
- package/lib/built/schedule.js +112 -0
- package/lib/built/schema-endpoint-manager.d.ts +0 -1
- package/lib/built/schema-endpoint-manager.js +0 -1
- package/lib/built/schema-feature.d.ts +0 -1
- package/lib/built/schema-feature.js +1 -3
- package/lib/built/segment-contract/assert.d.ts +4 -0
- package/lib/built/segment-contract/assert.js +30 -0
- package/lib/built/segment-contract/delivery.d.ts +5 -0
- package/lib/built/segment-contract/delivery.js +40 -0
- package/lib/built/segment-contract/image.d.ts +5 -0
- package/lib/built/segment-contract/image.js +10 -0
- package/lib/built/segment-contract/index.d.ts +8 -0
- package/lib/built/segment-contract/index.js +7 -0
- package/lib/built/segment-contract/media.d.ts +8 -0
- package/lib/built/segment-contract/media.js +39 -0
- package/lib/built/segment-contract/mention.d.ts +10 -0
- package/lib/built/segment-contract/mention.js +26 -0
- package/lib/built/segment-contract/preview.d.ts +3 -0
- package/lib/built/segment-contract/preview.js +159 -0
- package/lib/built/segment-contract/types.d.ts +70 -0
- package/lib/built/segment-contract/types.js +5 -0
- package/lib/built/segment-contract/validate.d.ts +138 -0
- package/lib/built/segment-contract/validate.js +124 -0
- package/lib/built/skill.d.ts +0 -1
- package/lib/built/skill.js +0 -1
- package/lib/built/speech-loader.d.ts +2 -1
- package/lib/built/speech-loader.js +6 -2
- package/lib/built/tool.d.ts +0 -1
- package/lib/built/tool.js +1 -3
- package/lib/command.d.ts +12 -7
- package/lib/command.js +38 -16
- package/lib/component.d.ts +0 -1
- package/lib/component.js +28 -12
- package/lib/endpoint-capabilities.d.ts +3 -1
- package/lib/endpoint-capabilities.js +0 -1
- package/lib/endpoint.d.ts +0 -1
- package/lib/endpoint.js +0 -1
- package/lib/errors.d.ts +0 -1
- package/lib/errors.js +0 -1
- package/lib/host-plugin-registry.d.ts +0 -1
- package/lib/host-plugin-registry.js +0 -1
- package/lib/im-scene.d.ts +29 -0
- package/lib/im-scene.js +77 -0
- package/lib/im-session-id.d.ts +25 -12
- package/lib/im-session-id.js +35 -17
- package/lib/index.d.ts +14 -7
- package/lib/index.js +12 -6
- package/lib/jsx-dev-runtime.d.ts +0 -1
- package/lib/jsx-dev-runtime.js +0 -1
- package/lib/jsx-runtime.d.ts +0 -1
- package/lib/jsx-runtime.js +0 -1
- package/lib/jsx.d.ts +0 -1
- package/lib/jsx.js +0 -1
- package/lib/message-quote.d.ts +1 -2
- package/lib/message-quote.js +2 -3
- package/lib/message.d.ts +7 -5
- package/lib/message.js +16 -1
- package/lib/models/system-log.d.ts +0 -1
- package/lib/models/system-log.js +0 -1
- package/lib/models/user.d.ts +0 -1
- package/lib/models/user.js +0 -1
- package/lib/notice.d.ts +15 -59
- package/lib/notice.js +1 -4
- package/lib/plugin-context.d.ts +0 -1
- package/lib/plugin-context.js +0 -1
- package/lib/plugin.d.ts +13 -6
- package/lib/plugin.js +31 -15
- package/lib/prompt.d.ts +0 -1
- package/lib/prompt.js +0 -1
- package/lib/request.d.ts +16 -60
- package/lib/request.js +0 -4
- package/lib/side-event/base.d.ts +45 -0
- package/lib/side-event/base.js +30 -0
- package/lib/side-event/index.d.ts +3 -0
- package/lib/side-event/index.js +3 -0
- package/lib/side-event/normalize.d.ts +40 -0
- package/lib/side-event/normalize.js +117 -0
- package/lib/side-event/types.d.ts +25 -0
- package/lib/side-event/types.js +55 -0
- package/lib/tool-zod.d.ts +0 -1
- package/lib/tool-zod.js +0 -1
- package/lib/types-generator.d.ts +0 -1
- package/lib/types-generator.js +0 -1
- package/lib/types.d.ts +30 -11
- package/lib/types.js +0 -1
- package/lib/utils.d.ts +36 -1
- package/lib/utils.js +33 -25
- package/package.json +15 -8
- package/lib/adapter.d.ts.map +0 -1
- package/lib/adapter.js.map +0 -1
- package/lib/agent-prompt.d.ts.map +0 -1
- package/lib/agent-prompt.js.map +0 -1
- package/lib/built/adapter-process.d.ts.map +0 -1
- package/lib/built/adapter-process.js.map +0 -1
- package/lib/built/agent-preset.d.ts.map +0 -1
- package/lib/built/agent-preset.js.map +0 -1
- package/lib/built/ai-trigger.d.ts.map +0 -1
- package/lib/built/ai-trigger.js.map +0 -1
- package/lib/built/authorization.d.ts.map +0 -1
- package/lib/built/authorization.js.map +0 -1
- package/lib/built/command.d.ts.map +0 -1
- package/lib/built/command.js.map +0 -1
- package/lib/built/common-adapter-tools.d.ts.map +0 -1
- package/lib/built/common-adapter-tools.js.map +0 -1
- package/lib/built/component.d.ts.map +0 -1
- package/lib/built/component.js.map +0 -1
- package/lib/built/config.d.ts.map +0 -1
- package/lib/built/config.js.map +0 -1
- package/lib/built/connect-endpoint-instance.d.ts.map +0 -1
- package/lib/built/connect-endpoint-instance.js.map +0 -1
- package/lib/built/cron.d.ts +0 -75
- package/lib/built/cron.d.ts.map +0 -1
- package/lib/built/cron.js +0 -122
- package/lib/built/cron.js.map +0 -1
- package/lib/built/database.d.ts.map +0 -1
- package/lib/built/database.js.map +0 -1
- package/lib/built/dispatcher.d.ts.map +0 -1
- package/lib/built/dispatcher.js.map +0 -1
- package/lib/built/endpoint-commands.d.ts.map +0 -1
- package/lib/built/endpoint-commands.js.map +0 -1
- package/lib/built/endpoint-lifecycle-service.d.ts.map +0 -1
- package/lib/built/endpoint-lifecycle-service.js.map +0 -1
- package/lib/built/endpoint-lifecycle.d.ts.map +0 -1
- package/lib/built/endpoint-lifecycle.js.map +0 -1
- package/lib/built/endpoint-manager.d.ts.map +0 -1
- package/lib/built/endpoint-manager.js.map +0 -1
- package/lib/built/generated-qrcode.d.ts.map +0 -1
- package/lib/built/generated-qrcode.js.map +0 -1
- package/lib/built/html-renderer-loader.d.ts.map +0 -1
- package/lib/built/html-renderer-loader.js.map +0 -1
- package/lib/built/html-segment-fallback.d.ts.map +0 -1
- package/lib/built/html-segment-fallback.js.map +0 -1
- package/lib/built/html-to-text.d.ts.map +0 -1
- package/lib/built/html-to-text.js.map +0 -1
- package/lib/built/inbound-pipeline.d.ts.map +0 -1
- package/lib/built/inbound-pipeline.js.map +0 -1
- package/lib/built/inbound-runner.d.ts.map +0 -1
- package/lib/built/inbound-runner.js.map +0 -1
- package/lib/built/introspection-format.d.ts.map +0 -1
- package/lib/built/introspection-format.js.map +0 -1
- package/lib/built/login-assist.d.ts.map +0 -1
- package/lib/built/login-assist.js.map +0 -1
- package/lib/built/management-command-guard.d.ts.map +0 -1
- package/lib/built/management-command-guard.js.map +0 -1
- package/lib/built/mcp-mesh-registrar.d.ts +0 -9
- package/lib/built/mcp-mesh-registrar.d.ts.map +0 -1
- package/lib/built/mcp-mesh-registrar.js +0 -17
- package/lib/built/mcp-mesh-registrar.js.map +0 -1
- package/lib/built/message-enrich.d.ts.map +0 -1
- package/lib/built/message-enrich.js.map +0 -1
- package/lib/built/message-filter.d.ts.map +0 -1
- package/lib/built/message-filter.js.map +0 -1
- package/lib/built/outbound-media-contract.d.ts.map +0 -1
- package/lib/built/outbound-media-contract.js.map +0 -1
- package/lib/built/outbound-media-utils.d.ts.map +0 -1
- package/lib/built/outbound-media-utils.js.map +0 -1
- package/lib/built/permission.d.ts.map +0 -1
- package/lib/built/permission.js.map +0 -1
- package/lib/built/permit-check.d.ts.map +0 -1
- package/lib/built/permit-check.js.map +0 -1
- package/lib/built/permit-parse.d.ts.map +0 -1
- package/lib/built/permit-parse.js.map +0 -1
- package/lib/built/platform-permit.d.ts.map +0 -1
- package/lib/built/platform-permit.js.map +0 -1
- package/lib/built/prepend-quote-context.d.ts.map +0 -1
- package/lib/built/prepend-quote-context.js.map +0 -1
- package/lib/built/qrcode-segment.d.ts.map +0 -1
- package/lib/built/qrcode-segment.js.map +0 -1
- package/lib/built/queue-im-field-contract.d.ts.map +0 -1
- package/lib/built/queue-im-field-contract.js.map +0 -1
- package/lib/built/rich-segments/adapter-policies.d.ts.map +0 -1
- package/lib/built/rich-segments/adapter-policies.js.map +0 -1
- package/lib/built/rich-segments/base.d.ts.map +0 -1
- package/lib/built/rich-segments/base.js.map +0 -1
- package/lib/built/rich-segments/builtins.d.ts.map +0 -1
- package/lib/built/rich-segments/builtins.js.map +0 -1
- package/lib/built/rich-segments/capabilities.d.ts.map +0 -1
- package/lib/built/rich-segments/capabilities.js.map +0 -1
- package/lib/built/rich-segments/html-segment.d.ts.map +0 -1
- package/lib/built/rich-segments/html-segment.js.map +0 -1
- package/lib/built/rich-segments/index.d.ts.map +0 -1
- package/lib/built/rich-segments/index.js.map +0 -1
- package/lib/built/rich-segments/markdown-segment.d.ts.map +0 -1
- package/lib/built/rich-segments/markdown-segment.js.map +0 -1
- package/lib/built/rich-segments/markdown-to-text.d.ts.map +0 -1
- package/lib/built/rich-segments/markdown-to-text.js.map +0 -1
- package/lib/built/rich-segments/qrcode-segment.d.ts.map +0 -1
- package/lib/built/rich-segments/qrcode-segment.js.map +0 -1
- package/lib/built/rich-segments/registry.d.ts.map +0 -1
- package/lib/built/rich-segments/registry.js.map +0 -1
- package/lib/built/rich-segments/resolve.d.ts.map +0 -1
- package/lib/built/rich-segments/resolve.js.map +0 -1
- package/lib/built/rich-segments/tts-segment.d.ts.map +0 -1
- package/lib/built/rich-segments/tts-segment.js.map +0 -1
- package/lib/built/rich-segments/types.d.ts.map +0 -1
- package/lib/built/rich-segments/types.js.map +0 -1
- package/lib/built/roles.d.ts.map +0 -1
- package/lib/built/roles.js.map +0 -1
- package/lib/built/runtime-io.d.ts.map +0 -1
- package/lib/built/runtime-io.js.map +0 -1
- package/lib/built/schema-endpoint-manager.d.ts.map +0 -1
- package/lib/built/schema-endpoint-manager.js.map +0 -1
- package/lib/built/schema-feature.d.ts.map +0 -1
- package/lib/built/schema-feature.js.map +0 -1
- package/lib/built/skill.d.ts.map +0 -1
- package/lib/built/skill.js.map +0 -1
- package/lib/built/speech-loader.d.ts.map +0 -1
- package/lib/built/speech-loader.js.map +0 -1
- package/lib/built/tool.d.ts.map +0 -1
- package/lib/built/tool.js.map +0 -1
- package/lib/command.d.ts.map +0 -1
- package/lib/command.js.map +0 -1
- package/lib/component.d.ts.map +0 -1
- package/lib/component.js.map +0 -1
- package/lib/endpoint-capabilities.d.ts.map +0 -1
- package/lib/endpoint-capabilities.js.map +0 -1
- package/lib/endpoint.d.ts.map +0 -1
- package/lib/endpoint.js.map +0 -1
- package/lib/errors.d.ts.map +0 -1
- package/lib/errors.js.map +0 -1
- package/lib/host-plugin-registry.d.ts.map +0 -1
- package/lib/host-plugin-registry.js.map +0 -1
- package/lib/im-session-id.d.ts.map +0 -1
- package/lib/im-session-id.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/jsx-dev-runtime.d.ts.map +0 -1
- package/lib/jsx-dev-runtime.js.map +0 -1
- package/lib/jsx-runtime.d.ts.map +0 -1
- package/lib/jsx-runtime.js.map +0 -1
- package/lib/jsx.d.ts.map +0 -1
- package/lib/jsx.js.map +0 -1
- package/lib/message-quote.d.ts.map +0 -1
- package/lib/message-quote.js.map +0 -1
- package/lib/message.d.ts.map +0 -1
- package/lib/message.js.map +0 -1
- package/lib/models/system-log.d.ts.map +0 -1
- package/lib/models/system-log.js.map +0 -1
- package/lib/models/user.d.ts.map +0 -1
- package/lib/models/user.js.map +0 -1
- package/lib/notice.d.ts.map +0 -1
- package/lib/notice.js.map +0 -1
- package/lib/plugin-context.d.ts.map +0 -1
- package/lib/plugin-context.js.map +0 -1
- package/lib/plugin.d.ts.map +0 -1
- package/lib/plugin.js.map +0 -1
- package/lib/prompt.d.ts.map +0 -1
- package/lib/prompt.js.map +0 -1
- package/lib/request.d.ts.map +0 -1
- package/lib/request.js.map +0 -1
- package/lib/scheduler/scheduler.d.ts +0 -49
- package/lib/scheduler/scheduler.d.ts.map +0 -1
- package/lib/scheduler/scheduler.js +0 -352
- package/lib/scheduler/scheduler.js.map +0 -1
- package/lib/scheduler/types.d.ts +0 -71
- package/lib/scheduler/types.d.ts.map +0 -1
- package/lib/scheduler/types.js +0 -8
- package/lib/scheduler/types.js.map +0 -1
- package/lib/tool-zod.d.ts.map +0 -1
- package/lib/tool-zod.js.map +0 -1
- package/lib/types-generator.d.ts.map +0 -1
- package/lib/types-generator.js.map +0 -1
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js.map +0 -1
- package/lib/utils.d.ts.map +0 -1
- package/lib/utils.js.map +0 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Zhin.js **IM/多通道运行时**包:Plugin、Adapter、**Endpoint**、Message
|
|
|
13
13
|
```typescript
|
|
14
14
|
import { usePlugin, MessageCommand } from '@zhin.js/core'
|
|
15
15
|
|
|
16
|
-
const { addCommand, addTool,
|
|
16
|
+
const { addCommand, addTool, addSchedule, onMounted, onDispose } = usePlugin()
|
|
17
17
|
|
|
18
18
|
onMounted(() => console.log('插件已挂载'))
|
|
19
19
|
onDispose(() => console.log('插件已卸载'))
|
|
@@ -55,7 +55,7 @@ Feature (抽象基类)
|
|
|
55
55
|
├── CommandFeature — 消息命令 addCommand()
|
|
56
56
|
├── ToolFeature — AI 可调用工具 addTool()
|
|
57
57
|
├── SkillFeature — 技能记录 Agent 从 SKILL.md 注入
|
|
58
|
-
├──
|
|
58
|
+
├── ScheduleFeature — 调度任务 addSchedule()
|
|
59
59
|
├── DatabaseFeature — 数据模型 defineModel()
|
|
60
60
|
├── ComponentFeature — 消息组件 addComponent()
|
|
61
61
|
├── ConfigFeature — 插件配置 addConfig()
|
|
@@ -150,9 +150,9 @@ class MyAdapter extends Adapter {
|
|
|
150
150
|
Adapter.register('my-platform', MyAdapter)
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
每个适配器可以通过 `addTool()` 注册平台特有工具,标准群管操作通过覆写 `
|
|
153
|
+
每个适配器可以通过 `addTool()` 注册平台特有工具,标准群管操作通过覆写 `ISceneManagement` 方法自动注册。
|
|
154
154
|
|
|
155
|
-
**群管理能力自动检测:** 适配器基类声明了 `
|
|
155
|
+
**群管理能力自动检测:** 适配器基类声明了 `ISceneManagement` 接口中的可选方法(`kickMember`、`muteMember`、`banMember` 等),子类只需覆写自己平台支持的方法,`start()` 会自动检测哪些方法已实现,生成对应的 Tool 并注册为"群聊管理"Skill。目前所有 9 个 IM 适配器(ICQQ、OneBot11、QQ 官方、Telegram、Discord、KOOK、Slack、钉钉、飞书)均已采用此模式:
|
|
156
156
|
|
|
157
157
|
```typescript
|
|
158
158
|
class IcqqAdapter extends Adapter<IcqqEndpoint> {
|
|
@@ -197,7 +197,7 @@ Core **不包含** ZhinAgent 实现。IM 侧的 AI 对话、工具收集、执
|
|
|
197
197
|
|------|----------|
|
|
198
198
|
| Provider | `OpenAIProvider`、`OllamaProvider`、`AnthropicProvider` 等 |
|
|
199
199
|
| Agent 原语 | `Agent`、`createAgent`、`ModelRegistry` |
|
|
200
|
-
| 会话 / 上下文 | `
|
|
200
|
+
| 会话 / 上下文 | `ContextRepository`、`ImTranscriptStore`、`ContextManager`、`ConversationMemory` |
|
|
201
201
|
| 压缩 / 限流 / 输出 | `compactSession`、`RateLimiter`、`parseOutput`、`CostTracker` |
|
|
202
202
|
|
|
203
203
|
完整 Agent 能力与配置见 [`@zhin.js/agent`](../agent/README.md) 与 [AI 模块](https://zhin.js.org/advanced/ai)。
|
|
@@ -212,7 +212,7 @@ export { Plugin, usePlugin, getPlugin, definePlugin } from './plugin.js'
|
|
|
212
212
|
|
|
213
213
|
// Feature 体系(Cron / Scheduler 来自 @zhin.js/kernel)
|
|
214
214
|
export { Feature, Cron, Scheduler } from '@zhin.js/kernel'
|
|
215
|
-
export { CommandFeature, ToolFeature, SkillFeature,
|
|
215
|
+
export { CommandFeature, ToolFeature, SkillFeature, ScheduleFeature, DatabaseFeature, ... } from './built/*.js'
|
|
216
216
|
|
|
217
217
|
// 消息路由
|
|
218
218
|
export { createMessageDispatcher } from './built/dispatcher.js'
|
|
@@ -236,7 +236,7 @@ export { htmlToFallbackText, coerceHtmlSegmentsToText, registerHtmlSegmentFallba
|
|
|
236
236
|
// AI 原语(来自 @zhin.js/ai,非 ZhinAgent)
|
|
237
237
|
export {
|
|
238
238
|
OpenAIProvider, OllamaProvider, Agent, createAgent, ModelRegistry,
|
|
239
|
-
|
|
239
|
+
ContextRepository, ContextManager, ConversationMemory, compactSession, ...
|
|
240
240
|
} from '@zhin.js/ai'
|
|
241
241
|
```
|
|
242
242
|
|
package/lib/adapter.d.ts
CHANGED
|
@@ -6,8 +6,10 @@ import { EventEmitter } from "node:events";
|
|
|
6
6
|
import { Message } from "./message.js";
|
|
7
7
|
import { Notice } from "./notice.js";
|
|
8
8
|
import { Request } from "./request.js";
|
|
9
|
-
import { SendOptions } from "./types.js";
|
|
9
|
+
import { EditMessageOptions, SendOptions } from "./types.js";
|
|
10
10
|
import { type OutboundRichSegmentPolicy } from "./built/rich-segments/index.js";
|
|
11
|
+
import { type InteractivePolicy } from "./built/interactive-segments/index.js";
|
|
12
|
+
import { type AiOutboundCapabilities, type AiOutboundExtensionDefinition } from "./built/ai-outbound/index.js";
|
|
11
13
|
import type { Schema } from '@zhin.js/schema';
|
|
12
14
|
/**
|
|
13
15
|
* Adapter类:适配器抽象,管理多平台Bot实例。
|
|
@@ -26,6 +28,13 @@ export declare abstract class Adapter<R extends Endpoint = Endpoint, const Caps
|
|
|
26
28
|
static readonly capabilities: readonly EndpointCapability[];
|
|
27
29
|
/** 出站富媒体段渲染策略(子类 override static) */
|
|
28
30
|
static outboundRichSegmentPolicy: OutboundRichSegmentPolicy;
|
|
31
|
+
/** 交互段出站策略:native 保留按钮段,text 降级为编号文本 */
|
|
32
|
+
static interactivePolicy: InteractivePolicy;
|
|
33
|
+
/** AI 结构化出站能力声明(mentions / richSegments / interactive) */
|
|
34
|
+
static aiOutboundCapabilities: AiOutboundCapabilities;
|
|
35
|
+
/** 平台特有 extensions schema + 解析(对齐各 SDK 文档子集) */
|
|
36
|
+
static aiOutboundExtensions?: readonly AiOutboundExtensionDefinition[];
|
|
37
|
+
protected getInteractivePolicy(): InteractivePolicy;
|
|
29
38
|
/** 并发上限,0 表示不限制(默认) */
|
|
30
39
|
static DEFAULT_MAX_CONCURRENT_MESSAGES: number;
|
|
31
40
|
get maxConcurrentMessages(): number;
|
|
@@ -47,6 +56,11 @@ export declare abstract class Adapter<R extends Endpoint = Endpoint, const Caps
|
|
|
47
56
|
abstract createEndpoint(config: Adapter.EndpointConfig<R>): R;
|
|
48
57
|
get logger(): import("@zhin.js/logger").Logger;
|
|
49
58
|
binding(plugin: Plugin): void;
|
|
59
|
+
/**
|
|
60
|
+
* 同步等待入站管线结束(middleware → dispatcher → 生命周期 → 观察者)。
|
|
61
|
+
* 用于 QQ 等需在被动回复完成后再 ack 交互的平台事件。
|
|
62
|
+
*/
|
|
63
|
+
receiveMessageAwait(message: Message): Promise<boolean>;
|
|
50
64
|
/** 运行时 Endpoint 管理(add/remove/edit/start/stop);未实现则 core 尝试 endpointConfigSchema 通用向导 */
|
|
51
65
|
getEndpointManager?(): EndpointManager | null;
|
|
52
66
|
/** 通用 schema 驱动 add/edit 时的字段定义 */
|
|
@@ -72,6 +86,13 @@ export declare abstract class Adapter<R extends Endpoint = Endpoint, const Caps
|
|
|
72
86
|
*/
|
|
73
87
|
protected renderSendMessage(options: SendOptions): Promise<SendOptions>;
|
|
74
88
|
sendMessage(options: SendOptions): Promise<string>;
|
|
89
|
+
/**
|
|
90
|
+
* 编辑已发送的消息。
|
|
91
|
+
* - 如果 Endpoint 实现了 $editMessage,调用平台编辑 API
|
|
92
|
+
* - 否则 fallback 到发送新消息
|
|
93
|
+
* @returns 消息 ID(编辑时返回原 ID,fallback 时返回新消息 ID)
|
|
94
|
+
*/
|
|
95
|
+
editMessage(options: EditMessageOptions): Promise<string>;
|
|
75
96
|
start(): Promise<void>;
|
|
76
97
|
/**
|
|
77
98
|
* 停止适配器,断开并移除所有 Endpoint 实例
|
|
@@ -113,4 +134,3 @@ export declare namespace Adapter {
|
|
|
113
134
|
*/
|
|
114
135
|
function register(name: string, factory: Factory): void;
|
|
115
136
|
}
|
|
116
|
-
//# sourceMappingURL=adapter.d.ts.map
|
package/lib/adapter.js
CHANGED
|
@@ -3,6 +3,8 @@ import { connectEndpointInstance, disconnectEndpointInstance } from "./built/con
|
|
|
3
3
|
import { EventEmitter } from "node:events";
|
|
4
4
|
import { getOutboundReplyStore } from "./built/dispatcher.js";
|
|
5
5
|
import { DEFAULT_OUTBOUND_RICH_SEGMENT_POLICY, resolveRichSegments, } from "./built/rich-segments/index.js";
|
|
6
|
+
import { DEFAULT_INTERACTIVE_POLICY, resolveInteractiveSegments, } from "./built/interactive-segments/index.js";
|
|
7
|
+
import { DEFAULT_AI_OUTBOUND_CAPABILITIES, } from "./built/ai-outbound/index.js";
|
|
6
8
|
import { createRichSegmentRenderContext } from "./built/rich-segments/capabilities.js";
|
|
7
9
|
import { collectOutboundMediaKinds } from "./built/outbound-media-utils.js";
|
|
8
10
|
import { segment } from "./utils.js";
|
|
@@ -24,6 +26,15 @@ export class Adapter extends EventEmitter {
|
|
|
24
26
|
static capabilities = DEFAULT_ENDPOINT_CAPABILITIES;
|
|
25
27
|
/** 出站富媒体段渲染策略(子类 override static) */
|
|
26
28
|
static outboundRichSegmentPolicy = DEFAULT_OUTBOUND_RICH_SEGMENT_POLICY;
|
|
29
|
+
/** 交互段出站策略:native 保留按钮段,text 降级为编号文本 */
|
|
30
|
+
static interactivePolicy = DEFAULT_INTERACTIVE_POLICY;
|
|
31
|
+
/** AI 结构化出站能力声明(mentions / richSegments / interactive) */
|
|
32
|
+
static aiOutboundCapabilities = DEFAULT_AI_OUTBOUND_CAPABILITIES;
|
|
33
|
+
/** 平台特有 extensions schema + 解析(对齐各 SDK 文档子集) */
|
|
34
|
+
static aiOutboundExtensions;
|
|
35
|
+
getInteractivePolicy() {
|
|
36
|
+
return this.constructor.interactivePolicy;
|
|
37
|
+
}
|
|
27
38
|
/** 入站消息并发计数 */
|
|
28
39
|
#pendingMessages = 0;
|
|
29
40
|
/** 并发上限,0 表示不限制(默认) */
|
|
@@ -104,6 +115,21 @@ export class Adapter extends EventEmitter {
|
|
|
104
115
|
binding(plugin) {
|
|
105
116
|
this.plugin = plugin;
|
|
106
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* 同步等待入站管线结束(middleware → dispatcher → 生命周期 → 观察者)。
|
|
120
|
+
* 用于 QQ 等需在被动回复完成后再 ack 交互的平台事件。
|
|
121
|
+
*/
|
|
122
|
+
async receiveMessageAwait(message) {
|
|
123
|
+
if (this.inboundPipeline.shouldDropDueToBackpressure()) {
|
|
124
|
+
this.logger.warn(formatCompact({ drop: 'concurrency', limit: this.maxConcurrentMessages }));
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
this.#pendingMessages++;
|
|
128
|
+
await this.inboundPipeline.receive(message, () => {
|
|
129
|
+
EventEmitter.prototype.emit.call(this, 'message.receive', message);
|
|
130
|
+
});
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
107
133
|
/**
|
|
108
134
|
* 出站富媒体能力(Publisher 按此过滤/降级;各 adapter 可覆盖)。
|
|
109
135
|
*/
|
|
@@ -140,6 +166,10 @@ export class Adapter extends EventEmitter {
|
|
|
140
166
|
},
|
|
141
167
|
})),
|
|
142
168
|
};
|
|
169
|
+
options = {
|
|
170
|
+
...options,
|
|
171
|
+
content: resolveInteractiveSegments(options.content, this.getInteractivePolicy()),
|
|
172
|
+
};
|
|
143
173
|
const mediaKinds = collectOutboundMediaKinds(options.content);
|
|
144
174
|
if (mediaKinds.length > 0) {
|
|
145
175
|
this.logger.debug(formatContentChainLog({
|
|
@@ -164,7 +194,7 @@ export class Adapter extends EventEmitter {
|
|
|
164
194
|
if (!endpoint)
|
|
165
195
|
throw new Error(`Endpoint ${options.endpoint} not found`);
|
|
166
196
|
assertOutbound(endpoint);
|
|
167
|
-
this.logger.
|
|
197
|
+
this.logger.debug(formatCompact({
|
|
168
198
|
send: `${options.type}(${options.id})`,
|
|
169
199
|
endpoint: options.endpoint,
|
|
170
200
|
preview: truncatePreview(segment.raw(options.content)),
|
|
@@ -180,6 +210,47 @@ export class Adapter extends EventEmitter {
|
|
|
180
210
|
});
|
|
181
211
|
return messageId;
|
|
182
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* 编辑已发送的消息。
|
|
215
|
+
* - 如果 Endpoint 实现了 $editMessage,调用平台编辑 API
|
|
216
|
+
* - 否则 fallback 到发送新消息
|
|
217
|
+
* @returns 消息 ID(编辑时返回原 ID,fallback 时返回新消息 ID)
|
|
218
|
+
*/
|
|
219
|
+
async editMessage(options) {
|
|
220
|
+
const endpoint = this.endpoints.get(options.endpoint);
|
|
221
|
+
if (!endpoint)
|
|
222
|
+
throw new Error(`Endpoint ${options.endpoint} not found`);
|
|
223
|
+
assertOutbound(endpoint);
|
|
224
|
+
const editable = endpoint;
|
|
225
|
+
if (editable.$editMessage) {
|
|
226
|
+
const rendered = await this.renderSendMessage({
|
|
227
|
+
context: options.context,
|
|
228
|
+
endpoint: options.endpoint,
|
|
229
|
+
id: options.id,
|
|
230
|
+
type: options.type,
|
|
231
|
+
content: options.content,
|
|
232
|
+
});
|
|
233
|
+
await editable.$editMessage({ ...options, content: rendered.content });
|
|
234
|
+
this.logger.debug(formatCompact({
|
|
235
|
+
edit: `${options.type}(${options.id})`,
|
|
236
|
+
endpoint: options.endpoint,
|
|
237
|
+
messageId: options.messageId,
|
|
238
|
+
}));
|
|
239
|
+
return options.messageId;
|
|
240
|
+
}
|
|
241
|
+
this.logger.debug(formatCompact({
|
|
242
|
+
editFallback: 'sendMessage',
|
|
243
|
+
endpoint: options.endpoint,
|
|
244
|
+
reason: '$editMessage not implemented',
|
|
245
|
+
}));
|
|
246
|
+
return this.sendMessage({
|
|
247
|
+
context: options.context,
|
|
248
|
+
endpoint: options.endpoint,
|
|
249
|
+
id: options.id,
|
|
250
|
+
type: options.type,
|
|
251
|
+
content: options.content,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
183
254
|
async start() {
|
|
184
255
|
if (this.endpoints.size > 0) {
|
|
185
256
|
await this.stop();
|
|
@@ -264,4 +335,3 @@ export class Adapter extends EventEmitter {
|
|
|
264
335
|
}
|
|
265
336
|
Adapter.register = register;
|
|
266
337
|
})(Adapter || (Adapter = {}));
|
|
267
|
-
//# sourceMappingURL=adapter.js.map
|
package/lib/agent-prompt.d.ts
CHANGED
|
@@ -38,4 +38,3 @@ export interface AgentPromptContributor {
|
|
|
38
38
|
/** Non-null replaces default TF-IDF deferred tool selection. */
|
|
39
39
|
selectDeferredTools?(query: string, goal: string, catalog: DeferredToolCatalogItem[], maxTools: number): DeferredToolCatalogItem[] | null;
|
|
40
40
|
}
|
|
41
|
-
//# sourceMappingURL=agent-prompt.d.ts.map
|
package/lib/agent-prompt.js
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Access Gate — 控制 LLM 回复路径是否对当前会话开放(平台 AIGC 合规等)
|
|
3
|
+
*/
|
|
4
|
+
import type { Message } from '../message.js';
|
|
5
|
+
export type AIAccessMode = 'open' | 'closed' | 'whitelist';
|
|
6
|
+
/** Endpoint 或全局 ai.access 配置块 */
|
|
7
|
+
export interface AIAccessScopeConfig {
|
|
8
|
+
mode?: AIAccessMode;
|
|
9
|
+
/** 允许触发 AI 的 sender.id */
|
|
10
|
+
users?: string[];
|
|
11
|
+
/** 允许触发 AI 的 group/channel id */
|
|
12
|
+
groups?: string[];
|
|
13
|
+
/** 私聊拒绝时的回复文案 */
|
|
14
|
+
denyMessage?: string;
|
|
15
|
+
}
|
|
16
|
+
/** 全局 ai.access 配置(与 AIAccessScopeConfig 同形) */
|
|
17
|
+
export type AIAccessConfig = AIAccessScopeConfig;
|
|
18
|
+
export interface ResolvedAIAccessConfig {
|
|
19
|
+
mode: AIAccessMode;
|
|
20
|
+
users: string[];
|
|
21
|
+
groups: string[];
|
|
22
|
+
denyMessage: string;
|
|
23
|
+
}
|
|
24
|
+
export interface AIAccessResult {
|
|
25
|
+
allowed: boolean;
|
|
26
|
+
reason: string;
|
|
27
|
+
/** 私聊拒绝时返回;群/频道拒绝为 undefined(静默) */
|
|
28
|
+
replyMessage?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare const DEFAULT_AI_ACCESS_DENY_MESSAGE = "\u5F53\u524D\u4F1A\u8BDD\u672A\u5F00\u653E AI \u529F\u80FD\u3002";
|
|
31
|
+
export declare function resolveAIAccessConfig(global: AIAccessConfig | undefined, endpointScope?: AIAccessScopeConfig): ResolvedAIAccessConfig;
|
|
32
|
+
/**
|
|
33
|
+
* 判定当前消息是否允许进入 AI Handler(LLM 回复路径)。
|
|
34
|
+
* 不影响命令、游戏等其它 Dispatcher 分支。
|
|
35
|
+
*/
|
|
36
|
+
export declare function checkAIAccess(message: Message<any>, globalConfig: AIAccessConfig | undefined, endpointScope?: AIAccessScopeConfig): AIAccessResult;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export const DEFAULT_AI_ACCESS_DENY_MESSAGE = '当前会话未开放 AI 功能。';
|
|
2
|
+
const DEFAULT_MODE = 'open';
|
|
3
|
+
export function resolveAIAccessConfig(global, endpointScope) {
|
|
4
|
+
const base = global ?? {};
|
|
5
|
+
const endpoint = endpointScope ?? {};
|
|
6
|
+
return {
|
|
7
|
+
mode: endpoint.mode ?? base.mode ?? DEFAULT_MODE,
|
|
8
|
+
users: endpoint.users ?? base.users ?? [],
|
|
9
|
+
groups: endpoint.groups ?? base.groups ?? [],
|
|
10
|
+
denyMessage: endpoint.denyMessage ?? base.denyMessage ?? DEFAULT_AI_ACCESS_DENY_MESSAGE,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function isWhitelisted(message, config) {
|
|
14
|
+
const userId = String(message.$sender?.id ?? '');
|
|
15
|
+
if (userId && config.users.includes(userId))
|
|
16
|
+
return true;
|
|
17
|
+
const scope = message.$channel?.type;
|
|
18
|
+
if (scope === 'group' || scope === 'channel') {
|
|
19
|
+
const channelId = String(message.$channel?.id ?? '');
|
|
20
|
+
if (channelId && config.groups.includes(channelId))
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
function denyResult(message, config, reason) {
|
|
26
|
+
const scope = message.$channel?.type;
|
|
27
|
+
const replyMessage = scope === 'private' ? config.denyMessage : undefined;
|
|
28
|
+
return { allowed: false, reason, replyMessage };
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 判定当前消息是否允许进入 AI Handler(LLM 回复路径)。
|
|
32
|
+
* 不影响命令、游戏等其它 Dispatcher 分支。
|
|
33
|
+
*/
|
|
34
|
+
export function checkAIAccess(message, globalConfig, endpointScope) {
|
|
35
|
+
const config = resolveAIAccessConfig(globalConfig, endpointScope);
|
|
36
|
+
if (config.mode === 'open') {
|
|
37
|
+
return { allowed: true, reason: 'mode: open' };
|
|
38
|
+
}
|
|
39
|
+
if (config.mode === 'closed') {
|
|
40
|
+
return denyResult(message, config, 'mode: closed');
|
|
41
|
+
}
|
|
42
|
+
if (isWhitelisted(message, config)) {
|
|
43
|
+
return { allowed: true, reason: 'whitelist: matched' };
|
|
44
|
+
}
|
|
45
|
+
return denyResult(message, config, 'whitelist: not matched');
|
|
46
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type AiOutboundCapabilities, type AiOutboundExtensionDefinition } from './types.js';
|
|
2
|
+
export declare function getAdapterAiOutboundCapabilities(adapterInstance: object): AiOutboundCapabilities;
|
|
3
|
+
export declare function getAdapterAiOutboundExtensions(adapterInstance: object): readonly AiOutboundExtensionDefinition[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DEFAULT_AI_OUTBOUND_CAPABILITIES, } from './types.js';
|
|
2
|
+
export function getAdapterAiOutboundCapabilities(adapterInstance) {
|
|
3
|
+
const ctor = adapterInstance.constructor;
|
|
4
|
+
return ctor.aiOutboundCapabilities ?? DEFAULT_AI_OUTBOUND_CAPABILITIES;
|
|
5
|
+
}
|
|
6
|
+
export function getAdapterAiOutboundExtensions(adapterInstance) {
|
|
7
|
+
const ctor = adapterInstance.constructor;
|
|
8
|
+
return ctor.aiOutboundExtensions ?? [];
|
|
9
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { KeyboardSegment } from '../../interactive-segments/keyboard-segment.js';
|
|
2
|
+
const ONEBOT_KEYBOARD_SCHEMA = {
|
|
3
|
+
type: 'object',
|
|
4
|
+
properties: {
|
|
5
|
+
rows: {
|
|
6
|
+
type: 'array',
|
|
7
|
+
items: {
|
|
8
|
+
type: 'array',
|
|
9
|
+
items: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
label: { type: 'string' },
|
|
13
|
+
payload: { type: 'string' },
|
|
14
|
+
id: { type: 'string' },
|
|
15
|
+
},
|
|
16
|
+
required: ['label', 'payload'],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
required: ['rows'],
|
|
22
|
+
};
|
|
23
|
+
function toKeyboardSegment(ext) {
|
|
24
|
+
if (!ext || typeof ext !== 'object')
|
|
25
|
+
return null;
|
|
26
|
+
const obj = ext;
|
|
27
|
+
const rowsRaw = obj.rows;
|
|
28
|
+
if (!Array.isArray(rowsRaw))
|
|
29
|
+
return null;
|
|
30
|
+
const rows = [];
|
|
31
|
+
for (const row of rowsRaw) {
|
|
32
|
+
if (!Array.isArray(row))
|
|
33
|
+
continue;
|
|
34
|
+
const buttons = [];
|
|
35
|
+
for (const btn of row) {
|
|
36
|
+
if (!btn || typeof btn !== 'object')
|
|
37
|
+
continue;
|
|
38
|
+
const b = btn;
|
|
39
|
+
const label = typeof b.label === 'string' ? b.label : '';
|
|
40
|
+
const payload = typeof b.payload === 'string' ? b.payload : '';
|
|
41
|
+
if (!label || !payload)
|
|
42
|
+
continue;
|
|
43
|
+
buttons.push({
|
|
44
|
+
id: typeof b.id === 'string' ? b.id : payload,
|
|
45
|
+
label,
|
|
46
|
+
payload,
|
|
47
|
+
disabled: b.disabled === true,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (buttons.length)
|
|
51
|
+
rows.push(buttons);
|
|
52
|
+
}
|
|
53
|
+
if (!rows.length)
|
|
54
|
+
return null;
|
|
55
|
+
return new KeyboardSegment({ rows }).toElement();
|
|
56
|
+
}
|
|
57
|
+
export const ONEBOT_KEYBOARD_AI_OUTBOUND_EXTENSION = {
|
|
58
|
+
key: 'onebot.keyboard',
|
|
59
|
+
schema: ONEBOT_KEYBOARD_SCHEMA,
|
|
60
|
+
examples: [
|
|
61
|
+
'{"extensions":{"onebot.keyboard":{"rows":[[{"label":"确认","payload":"ok","id":"ok"}]]}}}',
|
|
62
|
+
],
|
|
63
|
+
toMessageElements(ext, _ctx) {
|
|
64
|
+
const seg = toKeyboardSegment(ext);
|
|
65
|
+
return seg ? [seg] : [];
|
|
66
|
+
},
|
|
67
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const QQ_MARKDOWN_SCHEMA = {
|
|
2
|
+
type: 'object',
|
|
3
|
+
properties: {
|
|
4
|
+
content: { type: 'string' },
|
|
5
|
+
},
|
|
6
|
+
required: ['content'],
|
|
7
|
+
};
|
|
8
|
+
export const QQ_MARKDOWN_AI_OUTBOUND_EXTENSION = {
|
|
9
|
+
key: 'qq.markdown',
|
|
10
|
+
schema: QQ_MARKDOWN_SCHEMA,
|
|
11
|
+
examples: ['{"extensions":{"qq.markdown":{"content":"# Title\\nBody"}}}'],
|
|
12
|
+
toMessageElements(ext, _ctx) {
|
|
13
|
+
if (!ext || typeof ext !== 'object')
|
|
14
|
+
return [];
|
|
15
|
+
const content = ext.content;
|
|
16
|
+
if (typeof content !== 'string' || !content.trim())
|
|
17
|
+
return [];
|
|
18
|
+
return [{ type: 'markdown', data: { content: content.trim() } }];
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
export const QQ_AI_OUTBOUND_EXTENSIONS = [
|
|
22
|
+
QQ_MARKDOWN_AI_OUTBOUND_EXTENSION,
|
|
23
|
+
];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './parse.js';
|
|
3
|
+
export * from './plain-mention-rewrite.js';
|
|
4
|
+
export * from './resolve.js';
|
|
5
|
+
export * from './prompt.js';
|
|
6
|
+
export * from './structured-detect.js';
|
|
7
|
+
export * from './adapter-access.js';
|
|
8
|
+
export * from './extensions/onebot-keyboard.js';
|
|
9
|
+
export * from './extensions/qq-message.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './parse.js';
|
|
3
|
+
export * from './plain-mention-rewrite.js';
|
|
4
|
+
export * from './resolve.js';
|
|
5
|
+
export * from './prompt.js';
|
|
6
|
+
export * from './structured-detect.js';
|
|
7
|
+
export * from './adapter-access.js';
|
|
8
|
+
export * from './extensions/onebot-keyboard.js';
|
|
9
|
+
export * from './extensions/qq-message.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Segment } from '../segment-contract/types.js';
|
|
2
|
+
import type { ZhinAiOutboundPayload } from './types.js';
|
|
3
|
+
/** 解析单条 outbound segment(canonical 或 legacy kind/mode)。 */
|
|
4
|
+
export declare function parseOutboundSegment(raw: unknown): Segment | null;
|
|
5
|
+
/** 去掉嵌入 JSON 候选末尾的 markdown 围栏(模型常见 ```json … ``` 误输出)。 */
|
|
6
|
+
export declare function trimTrailingMarkdownFence(raw: string): string;
|
|
7
|
+
export declare function unwrapAiOutboundJsonCandidate(raw: string): string;
|
|
8
|
+
/** 从「正文 + 嵌入 JSON」混合文本中提取 AI outbound JSON(协作群常见误输出)。 */
|
|
9
|
+
export declare function extractEmbeddedAiOutboundJson(plain: string): {
|
|
10
|
+
prose: string;
|
|
11
|
+
jsonRaw: string;
|
|
12
|
+
} | null;
|
|
13
|
+
export declare function parseAiOutboundJson(raw: string): ZhinAiOutboundPayload | null;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { isCanonicalSegment } from '../segment-contract/assert.js';
|
|
2
|
+
function isPlainObject(value) {
|
|
3
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
/** 解析单条 outbound segment(canonical 或 legacy kind/mode)。 */
|
|
6
|
+
export function parseOutboundSegment(raw) {
|
|
7
|
+
if (!isPlainObject(raw))
|
|
8
|
+
return null;
|
|
9
|
+
const type = typeof raw.type === 'string' && raw.type.trim()
|
|
10
|
+
? raw.type.trim()
|
|
11
|
+
: typeof raw.kind === 'string' && raw.kind.trim()
|
|
12
|
+
? raw.kind.trim()
|
|
13
|
+
: undefined;
|
|
14
|
+
if (!type)
|
|
15
|
+
return null;
|
|
16
|
+
const data = isPlainObject(raw.data) ? raw.data : {};
|
|
17
|
+
const platform = isPlainObject(raw.platform) ? raw.platform : undefined;
|
|
18
|
+
const segment = platform ? { type, data, platform } : { type, data };
|
|
19
|
+
return isCanonicalSegment(segment) ? segment : null;
|
|
20
|
+
}
|
|
21
|
+
/** 去掉嵌入 JSON 候选末尾的 markdown 围栏(模型常见 ```json … ``` 误输出)。 */
|
|
22
|
+
export function trimTrailingMarkdownFence(raw) {
|
|
23
|
+
let s = raw.trim();
|
|
24
|
+
if (s.endsWith('```'))
|
|
25
|
+
s = s.slice(0, -3).trimEnd();
|
|
26
|
+
return s;
|
|
27
|
+
}
|
|
28
|
+
export function unwrapAiOutboundJsonCandidate(raw) {
|
|
29
|
+
const trimmed = raw.trim();
|
|
30
|
+
const fenced = readMarkdownFence(trimmed);
|
|
31
|
+
if (fenced && fenced.full)
|
|
32
|
+
return fenced.body.trim();
|
|
33
|
+
if (fenced && trimmed.indexOf('{') >= 0) {
|
|
34
|
+
return trimTrailingMarkdownFence(fenced.body.trim());
|
|
35
|
+
}
|
|
36
|
+
return trimTrailingMarkdownFence(trimmed);
|
|
37
|
+
}
|
|
38
|
+
/** 从「正文 + 嵌入 JSON」混合文本中提取 AI outbound JSON(协作群常见误输出)。 */
|
|
39
|
+
export function extractEmbeddedAiOutboundJson(plain) {
|
|
40
|
+
const trimmed = plain.trim();
|
|
41
|
+
if (!trimmed.includes('{'))
|
|
42
|
+
return null;
|
|
43
|
+
const fenced = readMarkdownFence(trimmed);
|
|
44
|
+
if (fenced) {
|
|
45
|
+
const jsonRaw = trimTrailingMarkdownFence(fenced.body.trim());
|
|
46
|
+
const payload = parseAiOutboundJson(jsonRaw);
|
|
47
|
+
if (payload?.mentions?.length && payload.text?.trim()) {
|
|
48
|
+
const prose = trimmed.slice(0, fenced.start).trim();
|
|
49
|
+
return { prose, jsonRaw };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
let idx = trimmed.indexOf('{');
|
|
53
|
+
while (idx >= 0) {
|
|
54
|
+
const jsonRaw = trimTrailingMarkdownFence(trimmed.slice(idx).trim());
|
|
55
|
+
const payload = parseAiOutboundJson(jsonRaw);
|
|
56
|
+
if (payload?.mentions?.length && payload.text?.trim()) {
|
|
57
|
+
return { prose: trimmed.slice(0, idx).trim(), jsonRaw };
|
|
58
|
+
}
|
|
59
|
+
idx = trimmed.indexOf('{', idx + 1);
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function readMarkdownFence(text) {
|
|
64
|
+
const start = text.indexOf('```');
|
|
65
|
+
if (start < 0)
|
|
66
|
+
return null;
|
|
67
|
+
let bodyStart = start + 3;
|
|
68
|
+
const langEnd = text.indexOf('\n', bodyStart);
|
|
69
|
+
if (langEnd >= 0) {
|
|
70
|
+
const lang = text.slice(bodyStart, langEnd).trim().toLowerCase();
|
|
71
|
+
if (lang === '' || lang === 'json')
|
|
72
|
+
bodyStart = langEnd + 1;
|
|
73
|
+
}
|
|
74
|
+
const end = text.indexOf('```', bodyStart);
|
|
75
|
+
if (end < 0)
|
|
76
|
+
return null;
|
|
77
|
+
return { start, body: text.slice(bodyStart, end), full: start === 0 && text.slice(end + 3).trim() === '' };
|
|
78
|
+
}
|
|
79
|
+
export function parseAiOutboundJson(raw) {
|
|
80
|
+
const candidate = unwrapAiOutboundJsonCandidate(raw);
|
|
81
|
+
if (!candidate.startsWith('{'))
|
|
82
|
+
return null;
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(candidate);
|
|
85
|
+
const text = typeof parsed.text === 'string' ? parsed.text.trim() : undefined;
|
|
86
|
+
const mentionsRaw = parsed.mentions;
|
|
87
|
+
const mentions = Array.isArray(mentionsRaw)
|
|
88
|
+
? mentionsRaw.map((m) => String(m).trim()).filter(Boolean)
|
|
89
|
+
: undefined;
|
|
90
|
+
const segmentsRaw = parsed.segments;
|
|
91
|
+
const segments = Array.isArray(segmentsRaw)
|
|
92
|
+
? segmentsRaw
|
|
93
|
+
.map((item) => parseOutboundSegment(item))
|
|
94
|
+
.filter((s) => s != null)
|
|
95
|
+
: undefined;
|
|
96
|
+
const extensions = parsed.extensions != null && typeof parsed.extensions === 'object' && !Array.isArray(parsed.extensions)
|
|
97
|
+
? parsed.extensions
|
|
98
|
+
: undefined;
|
|
99
|
+
if (!text && !mentions?.length && !segments?.length && !extensions)
|
|
100
|
+
return null;
|
|
101
|
+
if (mentions?.length && !text)
|
|
102
|
+
return null;
|
|
103
|
+
return { text, mentions, segments, extensions };
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AiOutboundMentionResolver, ZhinAiOutboundPayload } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 从正文中提取 cell roster 可识别的假 @(@researcher / @210723495 等),
|
|
4
|
+
* 剥离后返回等效 ZhinAiOutboundPayload。
|
|
5
|
+
*/
|
|
6
|
+
export declare function rewritePlainTextMentions(plainText: string, mentionResolver: AiOutboundMentionResolver): ZhinAiOutboundPayload | null;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const PLAIN_MENTION_PATTERN = /@([\w-]+)/g;
|
|
2
|
+
/**
|
|
3
|
+
* 从正文中提取 cell roster 可识别的假 @(@researcher / @210723495 等),
|
|
4
|
+
* 剥离后返回等效 ZhinAiOutboundPayload。
|
|
5
|
+
*/
|
|
6
|
+
export function rewritePlainTextMentions(plainText, mentionResolver) {
|
|
7
|
+
const trimmed = plainText.trim();
|
|
8
|
+
if (!trimmed)
|
|
9
|
+
return null;
|
|
10
|
+
const mentions = [];
|
|
11
|
+
let rewritten = trimmed;
|
|
12
|
+
for (const match of trimmed.matchAll(PLAIN_MENTION_PATTERN)) {
|
|
13
|
+
const token = match[1];
|
|
14
|
+
if (!token)
|
|
15
|
+
continue;
|
|
16
|
+
const endpointId = mentionResolver(token);
|
|
17
|
+
if (!endpointId)
|
|
18
|
+
continue;
|
|
19
|
+
const ref = token;
|
|
20
|
+
if (!mentions.includes(ref))
|
|
21
|
+
mentions.push(ref);
|
|
22
|
+
}
|
|
23
|
+
if (mentions.length === 0)
|
|
24
|
+
return null;
|
|
25
|
+
rewritten = trimmed.replace(PLAIN_MENTION_PATTERN, (full, token) => {
|
|
26
|
+
const endpointId = mentionResolver(token);
|
|
27
|
+
return endpointId ? '' : full;
|
|
28
|
+
});
|
|
29
|
+
rewritten = rewritten
|
|
30
|
+
.replace(/[ \t]+\n/g, '\n')
|
|
31
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
32
|
+
.replace(/^\s+|\s+$/g, '')
|
|
33
|
+
.trim();
|
|
34
|
+
if (!rewritten)
|
|
35
|
+
return null;
|
|
36
|
+
return { mentions, text: rewritten };
|
|
37
|
+
}
|