@zhin.js/core 1.1.34 → 1.1.35
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 +121 -65
- package/lib/adapter.d.ts +72 -23
- package/lib/adapter.js +222 -62
- package/lib/built/adapter-process.d.ts +20 -5
- package/lib/built/adapter-process.js +54 -7
- package/lib/built/agent-preset.d.ts +1 -2
- package/lib/built/agent-preset.js +1 -2
- 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 +104 -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 +6 -0
- package/lib/built/ai-outbound/types.d.ts +58 -0
- package/lib/built/ai-outbound/types.js +5 -0
- package/lib/built/ai-trigger.d.ts +17 -17
- package/lib/built/ai-trigger.js +65 -70
- package/lib/built/authorization.d.ts +10 -0
- package/lib/built/authorization.js +76 -0
- package/lib/built/command.d.ts +9 -5
- package/lib/built/command.js +20 -7
- package/lib/built/common-adapter-tools.d.ts +35 -29
- package/lib/built/common-adapter-tools.js +83 -67
- package/lib/built/component.d.ts +1 -3
- package/lib/built/component.js +2 -4
- package/lib/built/config.d.ts +4 -5
- package/lib/built/config.js +26 -9
- package/lib/built/connect-endpoint-instance.d.ts +17 -0
- package/lib/built/connect-endpoint-instance.js +42 -0
- package/lib/built/database.d.ts +5 -3
- package/lib/built/database.js +10 -4
- package/lib/built/dispatcher.d.ts +10 -8
- package/lib/built/dispatcher.js +31 -9
- package/lib/built/endpoint-commands.d.ts +3 -0
- package/lib/built/endpoint-commands.js +99 -0
- package/lib/built/endpoint-lifecycle-service.d.ts +28 -0
- package/lib/built/endpoint-lifecycle-service.js +242 -0
- package/lib/built/endpoint-lifecycle.d.ts +27 -0
- package/lib/built/endpoint-lifecycle.js +36 -0
- package/lib/built/endpoint-manager.d.ts +34 -0
- package/lib/built/endpoint-manager.js +1 -0
- package/lib/built/generated-qrcode.d.ts +24 -0
- package/lib/built/generated-qrcode.js +45 -0
- package/lib/built/generic-segment-mapper.d.ts +4 -0
- package/lib/built/generic-segment-mapper.js +190 -0
- package/lib/built/html-renderer-loader.d.ts +13 -0
- package/lib/built/html-renderer-loader.js +33 -0
- package/lib/built/html-segment-fallback.d.ts +2 -2
- 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 +37 -0
- package/lib/built/inbound-pipeline.js +63 -0
- package/lib/built/inbound-runner.d.ts +0 -1
- package/lib/built/inbound-runner.js +0 -3
- 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/fallback-store.d.ts +29 -0
- package/lib/built/interactive-segments/fallback-store.js +63 -0
- package/lib/built/interactive-segments/handlers.d.ts +16 -0
- package/lib/built/interactive-segments/handlers.js +74 -0
- package/lib/built/interactive-segments/index.d.ts +8 -0
- package/lib/built/interactive-segments/index.js +8 -0
- package/lib/built/interactive-segments/keyboard-segment.d.ts +11 -0
- package/lib/built/interactive-segments/keyboard-segment.js +12 -0
- package/lib/built/interactive-segments/onebot-keyboard.d.ts +7 -0
- package/lib/built/interactive-segments/onebot-keyboard.js +51 -0
- package/lib/built/interactive-segments/resolve.d.ts +15 -0
- package/lib/built/interactive-segments/resolve.js +110 -0
- package/lib/built/interactive-segments/types.d.ts +50 -0
- package/lib/built/interactive-segments/types.js +9 -0
- package/lib/built/introspection-format.d.ts +10 -0
- package/lib/built/introspection-format.js +28 -0
- package/lib/built/login-assist.d.ts +43 -9
- package/lib/built/login-assist.js +113 -11
- package/lib/built/management-command-guard.d.ts +15 -0
- package/lib/built/management-command-guard.js +25 -0
- package/lib/built/message-enrich.d.ts +38 -0
- package/lib/built/message-enrich.js +75 -0
- package/lib/built/message-filter.d.ts +4 -5
- package/lib/built/message-filter.js +5 -7
- 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 +22 -0
- package/lib/built/outbound-media-contract.js +10 -0
- package/lib/built/outbound-media-utils.d.ts +9 -0
- package/lib/built/outbound-media-utils.js +62 -0
- package/lib/built/permission.d.ts +3 -7
- package/lib/built/permission.js +39 -52
- package/lib/built/permit-check.d.ts +7 -0
- package/lib/built/permit-check.js +35 -0
- package/lib/built/permit-parse.d.ts +16 -0
- package/lib/built/permit-parse.js +32 -0
- package/lib/built/platform-permit.d.ts +20 -0
- package/lib/built/platform-permit.js +91 -0
- package/lib/built/queue-im-field-contract.d.ts +7 -2
- package/lib/built/queue-im-field-contract.js +13 -4
- package/lib/built/rich-segments/adapter-policies.d.ts +9 -0
- package/lib/built/rich-segments/adapter-policies.js +27 -0
- package/lib/built/rich-segments/base.d.ts +11 -0
- package/lib/built/rich-segments/base.js +24 -0
- package/lib/built/rich-segments/builtins.d.ts +4 -0
- package/lib/built/rich-segments/builtins.js +40 -0
- package/lib/built/rich-segments/capabilities.d.ts +6 -0
- package/lib/built/rich-segments/capabilities.js +38 -0
- package/lib/built/rich-segments/html-segment.d.ts +15 -0
- package/lib/built/rich-segments/html-segment.js +62 -0
- package/lib/built/rich-segments/index.d.ts +13 -0
- package/lib/built/rich-segments/index.js +13 -0
- package/lib/built/rich-segments/markdown-segment.d.ts +14 -0
- package/lib/built/rich-segments/markdown-segment.js +58 -0
- package/lib/built/rich-segments/markdown-to-text.d.ts +3 -0
- package/lib/built/rich-segments/markdown-to-text.js +27 -0
- package/lib/built/rich-segments/qrcode-segment.d.ts +18 -0
- package/lib/built/rich-segments/qrcode-segment.js +73 -0
- package/lib/built/rich-segments/registry.d.ts +16 -0
- package/lib/built/rich-segments/registry.js +52 -0
- package/lib/built/rich-segments/resolve.d.ts +5 -0
- package/lib/built/rich-segments/resolve.js +87 -0
- package/lib/built/rich-segments/tts-segment.d.ts +13 -0
- package/lib/built/rich-segments/tts-segment.js +51 -0
- package/lib/built/rich-segments/types.d.ts +79 -0
- package/lib/built/rich-segments/types.js +17 -0
- package/lib/built/roles.d.ts +4 -5
- package/lib/built/roles.js +4 -5
- 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 +17 -0
- package/lib/built/schema-endpoint-manager.js +73 -0
- 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 +7 -0
- package/lib/built/segment-contract/assert.js +39 -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 +10 -0
- package/lib/built/segment-contract/index.js +9 -0
- package/lib/built/segment-contract/json-schema.d.ts +28 -0
- package/lib/built/segment-contract/json-schema.js +128 -0
- package/lib/built/segment-contract/media.d.ts +12 -0
- package/lib/built/segment-contract/media.js +22 -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/text.d.ts +7 -0
- package/lib/built/segment-contract/text.js +34 -0
- package/lib/built/segment-contract/types.d.ts +58 -0
- package/lib/built/segment-contract/types.js +1 -0
- package/lib/built/segment-contract/validate.d.ts +229 -0
- package/lib/built/segment-contract/validate.js +174 -0
- package/lib/built/skill.d.ts +0 -1
- package/lib/built/skill.js +0 -1
- package/lib/built/speech-loader.d.ts +14 -0
- package/lib/built/speech-loader.js +32 -0
- package/lib/built/tool.d.ts +14 -13
- package/lib/built/tool.js +30 -25
- package/lib/built/user-interaction.d.ts +30 -0
- package/lib/built/user-interaction.js +248 -0
- package/lib/command.d.ts +19 -11
- package/lib/command.js +42 -11
- package/lib/component.d.ts +0 -1
- package/lib/component.js +30 -14
- package/lib/endpoint-capabilities.d.ts +46 -0
- package/lib/endpoint-capabilities.js +55 -0
- package/lib/endpoint.d.ts +19 -0
- package/lib/endpoint.js +3 -0
- package/lib/errors.d.ts +2 -3
- package/lib/errors.js +4 -5
- package/lib/feature/adapter.d.ts +2 -0
- package/lib/feature/adapter.js +2 -0
- package/lib/feature/command.d.ts +2 -0
- package/lib/feature/command.js +2 -0
- package/lib/feature/component.d.ts +2 -0
- package/lib/feature/component.js +2 -0
- package/lib/feature/handler.d.ts +52 -0
- package/lib/feature/handler.js +26 -0
- package/lib/feature/middleware.d.ts +2 -0
- package/lib/feature/middleware.js +2 -0
- package/lib/host-plugin-registry.d.ts +8 -0
- package/lib/host-plugin-registry.js +12 -0
- package/lib/im-scene.d.ts +29 -0
- package/lib/im-scene.js +75 -0
- package/lib/im-session-id.d.ts +39 -0
- package/lib/im-session-id.js +47 -0
- package/lib/index.d.ts +59 -25
- package/lib/index.js +53 -31
- package/lib/jsx-dev-runtime.d.ts +0 -1
- package/lib/jsx-dev-runtime.js +0 -1
- package/lib/jsx-runtime.d.ts +1 -1
- package/lib/jsx-runtime.js +0 -1
- package/lib/jsx.d.ts +19 -22
- package/lib/jsx.js +0 -1
- package/lib/message.d.ts +16 -10
- package/lib/message.js +16 -13
- 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 +16 -59
- package/lib/notice.js +1 -4
- package/lib/plugin-context.d.ts +27 -0
- package/lib/plugin-context.js +64 -0
- package/lib/plugin-runtime/im/contracts.d.ts +191 -0
- package/lib/plugin-runtime/im/contracts.js +169 -0
- package/lib/plugin-runtime/im/im-runtime.d.ts +177 -0
- package/lib/plugin-runtime/im/im-runtime.js +1204 -0
- package/lib/plugin-runtime/im/index.d.ts +9 -0
- package/lib/plugin-runtime/im/index.js +9 -0
- package/lib/plugin-runtime/im/interactive.d.ts +26 -0
- package/lib/plugin-runtime/im/interactive.js +46 -0
- package/lib/plugin-runtime/im/login-assist-host.d.ts +6 -0
- package/lib/plugin-runtime/im/login-assist-host.js +6 -0
- package/lib/plugin-runtime/im/message-bus.d.ts +38 -0
- package/lib/plugin-runtime/im/message-bus.js +40 -0
- package/lib/plugin-runtime/im/message-dispatcher.d.ts +18 -0
- package/lib/plugin-runtime/im/message-dispatcher.js +107 -0
- package/lib/plugin-runtime/im/outbound-renderer.d.ts +7 -0
- package/lib/plugin-runtime/im/outbound-renderer.js +70 -0
- package/lib/plugin-runtime/im/outbound-segments.d.ts +72 -0
- package/lib/plugin-runtime/im/outbound-segments.js +220 -0
- package/lib/plugin-runtime/im/public-api.d.ts +6 -0
- package/lib/plugin-runtime/im/public-api.js +6 -0
- package/lib/plugin-runtime/im/service-tokens.d.ts +18 -0
- package/lib/plugin-runtime/im/service-tokens.js +13 -0
- package/lib/plugin.d.ts +34 -24
- package/lib/plugin.js +119 -224
- package/lib/request.d.ts +17 -61
- package/lib/request.js +0 -4
- package/lib/{prompt.d.ts → schema-interaction.d.ts} +6 -7
- package/lib/{prompt.js → schema-interaction.js} +20 -17
- package/lib/side-event/base.d.ts +52 -0
- package/lib/side-event/base.js +30 -0
- package/lib/side-event/dispatch.d.ts +15 -0
- package/lib/side-event/dispatch.js +140 -0
- package/lib/side-event/index.d.ts +4 -0
- package/lib/side-event/index.js +4 -0
- package/lib/side-event/normalize.d.ts +42 -0
- package/lib/side-event/normalize.js +121 -0
- package/lib/side-event/types.d.ts +23 -0
- package/lib/side-event/types.js +55 -0
- package/lib/system-event.d.ts +15 -0
- package/lib/system-event.js +7 -0
- package/lib/tool-zod.d.ts +18 -3
- package/lib/tool-zod.js +140 -54
- package/lib/types.d.ts +44 -95
- package/lib/types.js +0 -1
- package/lib/utils.d.ts +61 -13
- package/lib/utils.js +66 -25
- package/package.json +98 -10
- package/lib/adapter.d.ts.map +0 -1
- package/lib/adapter.js.map +0 -1
- package/lib/agent-prompt.d.ts +0 -37
- package/lib/agent-prompt.d.ts.map +0 -1
- package/lib/agent-prompt.js +0 -2
- package/lib/agent-prompt.js.map +0 -1
- package/lib/bot.d.ts +0 -38
- package/lib/bot.d.ts.map +0 -1
- package/lib/bot.js +0 -2
- package/lib/bot.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/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/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/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-runner.d.ts.map +0 -1
- package/lib/built/inbound-runner.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/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-filter.d.ts.map +0 -1
- package/lib/built/message-filter.js.map +0 -1
- package/lib/built/permission.d.ts.map +0 -1
- package/lib/built/permission.js.map +0 -1
- package/lib/built/prepend-quote-context.d.ts +0 -35
- package/lib/built/prepend-quote-context.d.ts.map +0 -1
- package/lib/built/prepend-quote-context.js +0 -131
- package/lib/built/prepend-quote-context.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/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-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/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/errors.d.ts.map +0 -1
- package/lib/errors.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 +0 -11
- package/lib/message-quote.d.ts.map +0 -1
- package/lib/message-quote.js +0 -91
- 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.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 +0 -6
- package/lib/types-generator.d.ts.map +0 -1
- package/lib/types-generator.js +0 -72
- 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/lib/adapter.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import { assertOutbound, DEFAULT_ENDPOINT_CAPABILITIES, hasInbound, } from "./endpoint-capabilities.js";
|
|
2
|
+
import { endpointControlOf } from "@zhin.js/adapter";
|
|
3
|
+
import { connectEndpointInstance, disconnectEndpointInstance } from "./built/connect-endpoint-instance.js";
|
|
1
4
|
import { EventEmitter } from "node:events";
|
|
2
5
|
import { getOutboundReplyStore } from "./built/dispatcher.js";
|
|
3
|
-
import {
|
|
6
|
+
import { DEFAULT_OUTBOUND_RICH_SEGMENT_POLICY, resolveRichSegments, } from "./built/rich-segments/index.js";
|
|
7
|
+
import { DEFAULT_INTERACTIVE_POLICY, collectKeyboardFallbackMaps, keyboardFallbackStore, resolveKeyboardSegments, } from "./built/interactive-segments/index.js";
|
|
8
|
+
import { DEFAULT_AI_OUTBOUND_CAPABILITIES, } from "./built/ai-outbound/index.js";
|
|
9
|
+
import { createRichSegmentRenderContext } from "./built/rich-segments/capabilities.js";
|
|
10
|
+
import { collectOutboundMediaKinds } from "./built/outbound-media-utils.js";
|
|
4
11
|
import { segment } from "./utils.js";
|
|
5
|
-
import {
|
|
6
|
-
import { formatCompact, truncatePreview } from '@zhin.js/logger';
|
|
12
|
+
import { InboundMessagePipeline } from "./built/inbound-pipeline.js";
|
|
13
|
+
import { formatCompact, truncatePreview, formatContentChainLog, CONTENT_CHAIN_STAGE } from '@zhin.js/logger';
|
|
7
14
|
/**
|
|
8
15
|
* Adapter类:适配器抽象,管理多平台Bot实例。
|
|
9
16
|
* 负责根据配置启动/关闭各平台机器人,统一异常处理。
|
|
@@ -14,8 +21,21 @@ export class Adapter extends EventEmitter {
|
|
|
14
21
|
plugin;
|
|
15
22
|
name;
|
|
16
23
|
config;
|
|
17
|
-
|
|
18
|
-
|
|
24
|
+
endpoints = new Map();
|
|
25
|
+
recallMessageHandler;
|
|
26
|
+
/** Adapter 支持的能力上限(子类覆盖) */
|
|
27
|
+
static capabilities = DEFAULT_ENDPOINT_CAPABILITIES;
|
|
28
|
+
/** 出站富媒体段渲染策略(子类 override static) */
|
|
29
|
+
static outboundRichSegmentPolicy = DEFAULT_OUTBOUND_RICH_SEGMENT_POLICY;
|
|
30
|
+
/** 交互段出站策略:native 保留按钮段,text 降级为编号文本 */
|
|
31
|
+
static interactivePolicy = DEFAULT_INTERACTIVE_POLICY;
|
|
32
|
+
/** AI 结构化出站能力声明(mentions / richSegments / interactive) */
|
|
33
|
+
static aiOutboundCapabilities = DEFAULT_AI_OUTBOUND_CAPABILITIES;
|
|
34
|
+
/** 平台特有 extensions schema + 解析(对齐各 SDK 文档子集) */
|
|
35
|
+
static aiOutboundExtensions;
|
|
36
|
+
getInteractivePolicy() {
|
|
37
|
+
return this.constructor.interactivePolicy;
|
|
38
|
+
}
|
|
19
39
|
/** 入站消息并发计数 */
|
|
20
40
|
#pendingMessages = 0;
|
|
21
41
|
/** 并发上限,0 表示不限制(默认) */
|
|
@@ -35,61 +55,54 @@ export class Adapter extends EventEmitter {
|
|
|
35
55
|
return this.#pendingMessages;
|
|
36
56
|
}
|
|
37
57
|
/**
|
|
38
|
-
*
|
|
58
|
+
* 创建一个适配器运行实例。
|
|
59
|
+
* @param plugin 拥有该适配器的插件实例
|
|
39
60
|
* @param name 适配器名称(如 'process'、'qq' 等)
|
|
40
|
-
* @param
|
|
61
|
+
* @param config Endpoint 配置列表
|
|
41
62
|
*/
|
|
42
63
|
constructor(plugin, name, config) {
|
|
43
64
|
super();
|
|
44
65
|
this.plugin = plugin;
|
|
45
66
|
this.name = name;
|
|
46
67
|
this.config = config;
|
|
47
|
-
this.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
this.logger
|
|
52
|
-
|
|
68
|
+
this.recallMessageHandler = (endpoint_id, id) => this.recallEndpointMessage(endpoint_id, id);
|
|
69
|
+
this.on('call.recallMessage', this.recallMessageHandler);
|
|
70
|
+
this.inboundPipeline = new InboundMessagePipeline({
|
|
71
|
+
getPlugin: () => this.plugin,
|
|
72
|
+
logger: this.logger,
|
|
73
|
+
getMaxConcurrentMessages: () => this.maxConcurrentMessages,
|
|
74
|
+
getPendingMessages: () => this.#pendingMessages,
|
|
75
|
+
decrementPending: () => {
|
|
76
|
+
// stop() may zero the counter while in-flight receives still finish;
|
|
77
|
+
// never let the budget go negative.
|
|
78
|
+
this.#pendingMessages = Math.max(0, this.#pendingMessages - 1);
|
|
79
|
+
},
|
|
53
80
|
});
|
|
54
81
|
}
|
|
82
|
+
/** 入站消息管线(替代 emit override 的隐式管线) */
|
|
83
|
+
inboundPipeline;
|
|
55
84
|
/**
|
|
56
|
-
* 重写 emit:拦截 message.receive
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* 以属性 + `EventEmitter.prototype.emit` 调用满足 Node @types 25 对泛型 `emit` 的可赋值检查。
|
|
85
|
+
* 重写 emit:拦截 message.receive/notice.receive/request.receive 事件,
|
|
86
|
+
* 将入站处理委托给 InboundMessagePipeline。
|
|
60
87
|
*/
|
|
61
88
|
emit = ((event, ...args) => {
|
|
89
|
+
if (event === 'notice.receive' || event === 'request.receive') {
|
|
90
|
+
return this.inboundPipeline.bridgeNoticeOrRequest(event, args, () => EventEmitter.prototype.emit.call(this, event, ...args));
|
|
91
|
+
}
|
|
62
92
|
if (event !== 'message.receive') {
|
|
63
93
|
return EventEmitter.prototype.emit.call(this, event, ...args);
|
|
64
94
|
}
|
|
65
95
|
const message = args[0];
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
preview: truncatePreview(segment.raw(message.$content)),
|
|
70
|
-
...(message.$quote_id ? { quote_id: message.$quote_id } : {}),
|
|
71
|
-
}));
|
|
72
|
-
// 背压控制:limit > 0 时启用,超出并发上限丢弃消息并告警
|
|
73
|
-
const limit = this.maxConcurrentMessages;
|
|
74
|
-
if (limit > 0 && this.#pendingMessages >= limit) {
|
|
75
|
-
this.logger.warn(formatCompact({ drop: 'concurrency', limit }));
|
|
96
|
+
// 背压控制:同步返回 false 表示丢弃
|
|
97
|
+
if (this.inboundPipeline.shouldDropDueToBackpressure()) {
|
|
98
|
+
this.logger.warn(formatCompact({ op: 'backpressure_drop', limit: this.maxConcurrentMessages }));
|
|
76
99
|
return false;
|
|
77
100
|
}
|
|
101
|
+
// 同步计数,保证背压判断的准确性
|
|
78
102
|
this.#pendingMessages++;
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
plugin: this.plugin,
|
|
83
|
-
message,
|
|
84
|
-
emitAdapterObservers: () => {
|
|
85
|
-
EventEmitter.prototype.emit.call(this, event, ...args);
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
};
|
|
89
|
-
processing().catch((e) => {
|
|
90
|
-
this.logger.warn(`message.receive handling error: ${e instanceof Error ? e.message : String(e)}`);
|
|
91
|
-
}).finally(() => {
|
|
92
|
-
this.#pendingMessages--;
|
|
103
|
+
// 异步入站管线(middleware → dispatcher → 生命周期 → 观察者)
|
|
104
|
+
this.inboundPipeline.receive(message, () => {
|
|
105
|
+
EventEmitter.prototype.emit.call(this, event, ...args);
|
|
93
106
|
});
|
|
94
107
|
return true;
|
|
95
108
|
});
|
|
@@ -101,6 +114,28 @@ export class Adapter extends EventEmitter {
|
|
|
101
114
|
binding(plugin) {
|
|
102
115
|
this.plugin = plugin;
|
|
103
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* 同步等待入站管线结束(middleware → dispatcher → 生命周期 → 观察者)。
|
|
119
|
+
* 用于 QQ 等需在被动回复完成后再 ack 交互的平台事件。
|
|
120
|
+
*/
|
|
121
|
+
async receiveMessageAwait(message) {
|
|
122
|
+
if (this.inboundPipeline.shouldDropDueToBackpressure()) {
|
|
123
|
+
this.logger.warn(formatCompact({ drop: 'concurrency', limit: this.maxConcurrentMessages }));
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
this.#pendingMessages++;
|
|
127
|
+
try {
|
|
128
|
+
await this.inboundPipeline.receive(message, () => {
|
|
129
|
+
EventEmitter.prototype.emit.call(this, 'message.receive', message);
|
|
130
|
+
});
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
// Inbound pipeline errors must not leak the concurrency budget; the
|
|
135
|
+
// non-await path uses InboundMessagePipeline.decrementPending in finally.
|
|
136
|
+
this.#pendingMessages = Math.max(0, this.#pendingMessages - 1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
104
139
|
/**
|
|
105
140
|
* 出站富媒体能力(Publisher 按此过滤/降级;各 adapter 可覆盖)。
|
|
106
141
|
*/
|
|
@@ -113,29 +148,72 @@ export class Adapter extends EventEmitter {
|
|
|
113
148
|
maxAttachmentBytes: 26_214_400,
|
|
114
149
|
};
|
|
115
150
|
}
|
|
151
|
+
getOutboundRichSegmentPolicy() {
|
|
152
|
+
return this.constructor.outboundRichSegmentPolicy;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 出站两阶段:
|
|
156
|
+
* 1. resolveRichSegments — 语义段 → 标准 IM 段(image/audio/text)
|
|
157
|
+
* 2. Endpoint materializeOutboundMedia — base64/本地路径 → 平台 URL(各 adapter 可选)
|
|
158
|
+
* @see docs/essentials/rich-segment-adapters.md
|
|
159
|
+
*/
|
|
116
160
|
async renderSendMessage(options) {
|
|
161
|
+
if (options.content != null) {
|
|
162
|
+
options = {
|
|
163
|
+
...options,
|
|
164
|
+
content: await resolveRichSegments(options.content, this.getOutboundRichSegmentPolicy(), createRichSegmentRenderContext({
|
|
165
|
+
getConfig: () => {
|
|
166
|
+
const cfg = this.plugin.root.inject('config')?.getPrimary();
|
|
167
|
+
return cfg;
|
|
168
|
+
},
|
|
169
|
+
warn: (msg) => this.logger.warn(msg),
|
|
170
|
+
logContentChain: (fields) => {
|
|
171
|
+
this.logger.debug(formatContentChainLog({ ...fields, adapter: this.name }));
|
|
172
|
+
},
|
|
173
|
+
})),
|
|
174
|
+
};
|
|
175
|
+
// 'text' 策略端点:keyboard 即将降级为编号文本,先把有效 fallback
|
|
176
|
+
// 映射写入中央存储(频道键与入站回跳解析一致),供数字回跳路由。
|
|
177
|
+
if (this.getInteractivePolicy() === 'text') {
|
|
178
|
+
const channelKey = `${this.name}-${options.endpoint}-${options.type}:${options.id}`;
|
|
179
|
+
for (const map of collectKeyboardFallbackMaps(options.content)) {
|
|
180
|
+
keyboardFallbackStore.remember(channelKey, map);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
options = {
|
|
184
|
+
...options,
|
|
185
|
+
content: resolveKeyboardSegments(options.content, this.getInteractivePolicy()),
|
|
186
|
+
};
|
|
187
|
+
const mediaKinds = collectOutboundMediaKinds(options.content);
|
|
188
|
+
if (mediaKinds.length > 0) {
|
|
189
|
+
this.logger.debug(formatContentChainLog({
|
|
190
|
+
stage: CONTENT_CHAIN_STAGE.OUTBOUND,
|
|
191
|
+
adapter: this.name,
|
|
192
|
+
endpoint: options.endpoint,
|
|
193
|
+
media: mediaKinds.join(','),
|
|
194
|
+
}));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
117
197
|
const fns = this.plugin.root.listeners('before.sendMessage');
|
|
118
198
|
for (const fn of fns) {
|
|
119
199
|
const result = await fn(options);
|
|
120
200
|
if (result)
|
|
121
201
|
options = result;
|
|
122
202
|
}
|
|
123
|
-
if (options.content != null) {
|
|
124
|
-
options = { ...options, content: coerceHtmlSegmentsToText(options.content) };
|
|
125
|
-
}
|
|
126
203
|
return options;
|
|
127
204
|
}
|
|
128
205
|
async sendMessage(options) {
|
|
129
206
|
options = await this.renderSendMessage(options);
|
|
130
|
-
const
|
|
131
|
-
if (!
|
|
132
|
-
throw new Error(`
|
|
133
|
-
|
|
207
|
+
const endpoint = this.endpoints.get(options.endpoint);
|
|
208
|
+
if (!endpoint)
|
|
209
|
+
throw new Error(`Endpoint ${options.endpoint} not found`);
|
|
210
|
+
assertOutbound(endpoint);
|
|
211
|
+
this.logger.debug(formatCompact({
|
|
134
212
|
send: `${options.type}(${options.id})`,
|
|
135
|
-
|
|
213
|
+
endpoint: options.endpoint,
|
|
136
214
|
preview: truncatePreview(segment.raw(options.content)),
|
|
137
215
|
}));
|
|
138
|
-
const messageId = await
|
|
216
|
+
const messageId = await endpoint.$sendMessage(options);
|
|
139
217
|
const replyStore = getOutboundReplyStore();
|
|
140
218
|
this.plugin.root.dispatch('message.send', {
|
|
141
219
|
adapter: this.name,
|
|
@@ -146,7 +224,81 @@ export class Adapter extends EventEmitter {
|
|
|
146
224
|
});
|
|
147
225
|
return messageId;
|
|
148
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* `call.recallMessage` 事件链(prompt.ts 超时撤回等)的统一出口:
|
|
229
|
+
* 经 canonical `EndpointControl` 端口撤回。
|
|
230
|
+
*/
|
|
231
|
+
async recallEndpointMessage(endpointKey, messageId) {
|
|
232
|
+
const endpoint = this.endpoints.get(endpointKey);
|
|
233
|
+
if (!endpoint)
|
|
234
|
+
throw new Error(`Endpoint ${endpointKey} not found`);
|
|
235
|
+
assertOutbound(endpoint);
|
|
236
|
+
const control = endpointControlOf(endpoint);
|
|
237
|
+
if (!control?.recall) {
|
|
238
|
+
throw new Error(`Endpoint ${endpointKey} does not support recall`);
|
|
239
|
+
}
|
|
240
|
+
this.logger.debug(formatCompact({ op: 'recall_message', msgId: messageId, endpoint: endpointKey }));
|
|
241
|
+
await control.recall({
|
|
242
|
+
conversation: {
|
|
243
|
+
endpoint: { id: endpointKey, adapter: String(this.name) },
|
|
244
|
+
kind: 'private',
|
|
245
|
+
id: endpointKey,
|
|
246
|
+
},
|
|
247
|
+
id: messageId,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* 编辑已发送的消息。
|
|
252
|
+
* - 如果 Endpoint 的 control 端口实现了 edit,调用平台编辑 API
|
|
253
|
+
* - 否则 fallback 到发送新消息
|
|
254
|
+
* @returns 消息 ID(编辑时返回原 ID,fallback 时返回新消息 ID)
|
|
255
|
+
*/
|
|
256
|
+
async editMessage(options) {
|
|
257
|
+
const endpoint = this.endpoints.get(options.endpoint);
|
|
258
|
+
if (!endpoint)
|
|
259
|
+
throw new Error(`Endpoint ${options.endpoint} not found`);
|
|
260
|
+
assertOutbound(endpoint);
|
|
261
|
+
const control = endpointControlOf(endpoint);
|
|
262
|
+
if (control?.edit) {
|
|
263
|
+
const rendered = await this.renderSendMessage({
|
|
264
|
+
context: options.context,
|
|
265
|
+
endpoint: options.endpoint,
|
|
266
|
+
id: options.id,
|
|
267
|
+
type: options.type,
|
|
268
|
+
content: options.content,
|
|
269
|
+
});
|
|
270
|
+
await control.edit({
|
|
271
|
+
conversation: {
|
|
272
|
+
endpoint: { id: options.endpoint, adapter: String(this.name) },
|
|
273
|
+
kind: options.type === 'group' ? 'group' : 'private',
|
|
274
|
+
id: options.id,
|
|
275
|
+
},
|
|
276
|
+
id: options.messageId,
|
|
277
|
+
}, rendered.content);
|
|
278
|
+
this.logger.debug(formatCompact({
|
|
279
|
+
edit: `${options.type}(${options.id})`,
|
|
280
|
+
endpoint: options.endpoint,
|
|
281
|
+
messageId: options.messageId,
|
|
282
|
+
}));
|
|
283
|
+
return options.messageId;
|
|
284
|
+
}
|
|
285
|
+
this.logger.debug(formatCompact({
|
|
286
|
+
editFallback: 'sendMessage',
|
|
287
|
+
endpoint: options.endpoint,
|
|
288
|
+
reason: 'control.edit not implemented',
|
|
289
|
+
}));
|
|
290
|
+
return this.sendMessage({
|
|
291
|
+
context: options.context,
|
|
292
|
+
endpoint: options.endpoint,
|
|
293
|
+
id: options.id,
|
|
294
|
+
type: options.type,
|
|
295
|
+
content: options.content,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
149
298
|
async start() {
|
|
299
|
+
if (this.endpoints.size > 0) {
|
|
300
|
+
await this.stop();
|
|
301
|
+
}
|
|
150
302
|
const rootAdapters = this.plugin.root.adapters;
|
|
151
303
|
if (!rootAdapters.some((n) => String(n) === String(this.name))) {
|
|
152
304
|
rootAdapters.push(this.name);
|
|
@@ -154,31 +306,38 @@ export class Adapter extends EventEmitter {
|
|
|
154
306
|
if (!this.config?.length)
|
|
155
307
|
return;
|
|
156
308
|
for (const config of this.config) {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
309
|
+
const endpoint = await connectEndpointInstance({
|
|
310
|
+
plugin: this.plugin,
|
|
311
|
+
adapter: this,
|
|
312
|
+
config: config,
|
|
313
|
+
});
|
|
314
|
+
this.logger.debug(formatCompact({ connect: endpoint.$id, adapter: this.name }));
|
|
315
|
+
this.endpoints.set(endpoint.$id, endpoint);
|
|
161
316
|
}
|
|
162
317
|
this.logger.debug(formatCompact({ adapter: this.name }));
|
|
163
318
|
}
|
|
164
319
|
/**
|
|
165
|
-
* 停止适配器,断开并移除所有
|
|
166
|
-
* @param plugin 所属插件实例
|
|
320
|
+
* 停止适配器,断开并移除所有 Endpoint 实例
|
|
167
321
|
*/
|
|
168
322
|
async stop() {
|
|
169
323
|
const errors = [];
|
|
170
|
-
for (const [id,
|
|
324
|
+
for (const [id, endpoint] of this.endpoints) {
|
|
171
325
|
try {
|
|
172
|
-
|
|
326
|
+
if (hasInbound(endpoint)) {
|
|
327
|
+
await disconnectEndpointInstance(this.plugin, this, endpoint);
|
|
328
|
+
}
|
|
173
329
|
this.logger.debug(formatCompact({ disconnect: id, adapter: this.name }));
|
|
174
330
|
}
|
|
175
331
|
catch (error) {
|
|
176
332
|
errors.push(error instanceof Error ? error : new Error(String(error)));
|
|
177
|
-
this.logger.error(`
|
|
333
|
+
this.logger.error(`endpoint ${id} of adapter ${this.name} disconnect failed:`, error);
|
|
178
334
|
}
|
|
179
335
|
}
|
|
180
336
|
// 无论是否有错误,始终完成清理
|
|
181
|
-
this.
|
|
337
|
+
this.endpoints.clear();
|
|
338
|
+
// Drop in-flight concurrency counter so a subsequent start() does not
|
|
339
|
+
// inherit a stale backpressure budget from the previous generation.
|
|
340
|
+
this.#pendingMessages = 0;
|
|
182
341
|
// 从 adapters 数组中移除(可能因重复 start 出现多条同名,需全部删掉)
|
|
183
342
|
const rootAdapters = this.plugin.root.adapters;
|
|
184
343
|
for (let i = rootAdapters.length - 1; i >= 0; i--) {
|
|
@@ -187,9 +346,11 @@ export class Adapter extends EventEmitter {
|
|
|
187
346
|
}
|
|
188
347
|
// 移除所有事件监听器
|
|
189
348
|
this.removeAllListeners();
|
|
349
|
+
this.recallMessageHandler = (endpoint_id, id) => this.recallEndpointMessage(endpoint_id, id);
|
|
350
|
+
this.on('call.recallMessage', this.recallMessageHandler);
|
|
190
351
|
this.logger.debug(formatCompact({ stop: this.name }));
|
|
191
352
|
if (errors.length) {
|
|
192
|
-
throw new AggregateError(errors, `adapter ${this.name}: ${errors.length}
|
|
353
|
+
throw new AggregateError(errors, `adapter ${this.name}: ${errors.length} endpoint(s) failed to disconnect`);
|
|
193
354
|
}
|
|
194
355
|
}
|
|
195
356
|
}
|
|
@@ -214,4 +375,3 @@ export class Adapter extends EventEmitter {
|
|
|
214
375
|
}
|
|
215
376
|
Adapter.register = register;
|
|
216
377
|
})(Adapter || (Adapter = {}));
|
|
217
|
-
//# sourceMappingURL=adapter.js.map
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { Adapter
|
|
2
|
-
|
|
1
|
+
import { Adapter } from "../adapter.js";
|
|
2
|
+
import { Plugin } from "../plugin.js";
|
|
3
|
+
import { Endpoint } from "../endpoint.js";
|
|
4
|
+
import { Message } from "../message.js";
|
|
5
|
+
import type { SendOptions } from "../types.js";
|
|
6
|
+
import type { OutboundRichSegmentPolicy } from "./rich-segments/types.js";
|
|
7
|
+
export declare class ProcessEndpoint implements Endpoint<{
|
|
3
8
|
owner?: string;
|
|
4
9
|
}, {
|
|
5
10
|
content: string;
|
|
@@ -26,18 +31,28 @@ export declare class ProcessBot implements Bot<{
|
|
|
26
31
|
content: string;
|
|
27
32
|
ts: number;
|
|
28
33
|
}>;
|
|
34
|
+
get control(): {
|
|
35
|
+
recall: (message: {
|
|
36
|
+
id: string;
|
|
37
|
+
}) => Promise<void>;
|
|
38
|
+
};
|
|
29
39
|
$recallMessage(id: string): Promise<void>;
|
|
30
40
|
$sendMessage(options: SendOptions): Promise<string>;
|
|
31
41
|
$connect(): Promise<void>;
|
|
32
42
|
$disconnect(): Promise<void>;
|
|
33
43
|
}
|
|
34
|
-
export declare class ProcessAdapter extends Adapter<
|
|
44
|
+
export declare class ProcessAdapter extends Adapter<ProcessEndpoint> {
|
|
45
|
+
static readonly capabilities: readonly ["inbound", "outbound"];
|
|
46
|
+
static outboundRichSegmentPolicy: OutboundRichSegmentPolicy;
|
|
35
47
|
constructor(plugin: Plugin);
|
|
36
|
-
|
|
48
|
+
/**
|
|
49
|
+
* process 出站由 $sendMessage 写入 stdout;父类 INFO preview 会与终端输出重复,故仅 debug 元数据。
|
|
50
|
+
*/
|
|
51
|
+
sendMessage(options: SendOptions): Promise<string>;
|
|
52
|
+
createEndpoint(config: Adapter.EndpointConfig<ProcessEndpoint>): ProcessEndpoint;
|
|
37
53
|
}
|
|
38
54
|
declare module '../adapter.js' {
|
|
39
55
|
interface Adapters {
|
|
40
56
|
process: ProcessAdapter;
|
|
41
57
|
}
|
|
42
58
|
}
|
|
43
|
-
//# sourceMappingURL=adapter-process.d.ts.map
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { formatCompact } from "@zhin.js/logger";
|
|
2
|
+
import { Adapter } from "../adapter.js";
|
|
3
|
+
import { Message } from "../message.js";
|
|
4
|
+
import { segment } from "../utils.js";
|
|
5
|
+
import { assertOutbound } from "../endpoint-capabilities.js";
|
|
6
|
+
import { getOutboundReplyStore } from "./dispatcher.js";
|
|
2
7
|
import { bindStdin, runtimePid, runtimeUser } from "./runtime-io.js";
|
|
3
|
-
|
|
8
|
+
import { interpretOriginQrcodeForProcess } from "./rich-segments/qrcode-segment.js";
|
|
9
|
+
export class ProcessEndpoint {
|
|
4
10
|
adapter;
|
|
5
11
|
$config;
|
|
6
12
|
$id = runtimePid();
|
|
@@ -28,7 +34,7 @@ export class ProcessBot {
|
|
|
28
34
|
const base = {
|
|
29
35
|
$id: `${event.ts}`,
|
|
30
36
|
$adapter: 'process',
|
|
31
|
-
$
|
|
37
|
+
$endpoint: runtimePid(),
|
|
32
38
|
$sender: {
|
|
33
39
|
id: runtimeUser(),
|
|
34
40
|
name: runtimeUser(),
|
|
@@ -47,7 +53,7 @@ export class ProcessBot {
|
|
|
47
53
|
$reply: async (content) => {
|
|
48
54
|
return await this.adapter.sendMessage({
|
|
49
55
|
context: 'process',
|
|
50
|
-
|
|
56
|
+
endpoint: base.$endpoint,
|
|
51
57
|
content,
|
|
52
58
|
id: base.$sender.id,
|
|
53
59
|
type: base.$channel.type,
|
|
@@ -56,9 +62,21 @@ export class ProcessBot {
|
|
|
56
62
|
};
|
|
57
63
|
return Message.from(event, base);
|
|
58
64
|
}
|
|
65
|
+
get control() {
|
|
66
|
+
return {
|
|
67
|
+
recall: async (message) => this.$recallMessage(message.id),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
59
70
|
async $recallMessage(id) {
|
|
60
71
|
}
|
|
61
72
|
async $sendMessage(options) {
|
|
73
|
+
const content = await interpretOriginQrcodeForProcess(options.content ?? '');
|
|
74
|
+
if (content != null) {
|
|
75
|
+
const preview = segment.raw(content);
|
|
76
|
+
if (preview) {
|
|
77
|
+
process.stdout.write(`${preview}\n`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
62
80
|
return `${Date.now()}`;
|
|
63
81
|
}
|
|
64
82
|
async $connect() {
|
|
@@ -71,11 +89,40 @@ export class ProcessBot {
|
|
|
71
89
|
}
|
|
72
90
|
}
|
|
73
91
|
export class ProcessAdapter extends Adapter {
|
|
92
|
+
static capabilities = ['inbound', 'outbound'];
|
|
93
|
+
static outboundRichSegmentPolicy = {
|
|
94
|
+
qrcode: 'origin',
|
|
95
|
+
html: 'text',
|
|
96
|
+
markdown: 'text',
|
|
97
|
+
};
|
|
74
98
|
constructor(plugin) {
|
|
75
99
|
super(plugin, 'process', [{ owner: runtimePid() }]);
|
|
76
100
|
}
|
|
77
|
-
|
|
78
|
-
|
|
101
|
+
/**
|
|
102
|
+
* process 出站由 $sendMessage 写入 stdout;父类 INFO preview 会与终端输出重复,故仅 debug 元数据。
|
|
103
|
+
*/
|
|
104
|
+
async sendMessage(options) {
|
|
105
|
+
options = await this.renderSendMessage(options);
|
|
106
|
+
const endpoint = this.endpoints.get(options.endpoint);
|
|
107
|
+
if (!endpoint)
|
|
108
|
+
throw new Error(`Endpoint ${options.endpoint} not found`);
|
|
109
|
+
assertOutbound(endpoint);
|
|
110
|
+
this.logger.debug(formatCompact({
|
|
111
|
+
send: `${options.type}(${options.id})`,
|
|
112
|
+
endpoint: options.endpoint,
|
|
113
|
+
}));
|
|
114
|
+
const messageId = await endpoint.$sendMessage(options);
|
|
115
|
+
const replyStore = getOutboundReplyStore();
|
|
116
|
+
this.plugin.root.dispatch('message.send', {
|
|
117
|
+
adapter: this.name,
|
|
118
|
+
options,
|
|
119
|
+
messageId,
|
|
120
|
+
replySource: replyStore?.source,
|
|
121
|
+
replyMessage: replyStore?.message,
|
|
122
|
+
});
|
|
123
|
+
return messageId;
|
|
124
|
+
}
|
|
125
|
+
createEndpoint(config) {
|
|
126
|
+
return new ProcessEndpoint(this, config);
|
|
79
127
|
}
|
|
80
128
|
}
|
|
81
|
-
//# sourceMappingURL=adapter-process.js.map
|
|
@@ -48,7 +48,7 @@ declare module '../plugin.js' {
|
|
|
48
48
|
export declare class AgentPresetFeature extends Feature<AgentPreset> {
|
|
49
49
|
#private;
|
|
50
50
|
readonly name: "agentPreset";
|
|
51
|
-
readonly icon = "
|
|
51
|
+
readonly icon = "Endpoint";
|
|
52
52
|
readonly desc = "Agent \u9884\u8BBE";
|
|
53
53
|
readonly byName: Map<string, AgentPreset>;
|
|
54
54
|
add(preset: AgentPreset, pluginName: string): () => void;
|
|
@@ -62,4 +62,3 @@ export declare class AgentPresetFeature extends Feature<AgentPreset> {
|
|
|
62
62
|
}): AgentPreset[];
|
|
63
63
|
toJSON(pluginName?: string): FeatureJSON;
|
|
64
64
|
}
|
|
65
|
-
//# sourceMappingURL=agent-preset.d.ts.map
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { Feature } from '@zhin.js/kernel';
|
|
13
13
|
export class AgentPresetFeature extends Feature {
|
|
14
14
|
name = 'agentPreset';
|
|
15
|
-
icon = '
|
|
15
|
+
icon = 'Endpoint';
|
|
16
16
|
desc = 'Agent 预设';
|
|
17
17
|
byName = new Map();
|
|
18
18
|
add(preset, pluginName) {
|
|
@@ -77,4 +77,3 @@ export class AgentPresetFeature extends Feature {
|
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
//# sourceMappingURL=agent-preset.js.map
|
|
@@ -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
|
+
}
|