@zhin.js/core 1.3.1 → 1.3.3
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 +66 -11
- package/lib/adapter.d.ts +41 -3
- package/lib/adapter.js +110 -6
- package/lib/agent-prompt.d.ts +0 -1
- package/lib/agent-prompt.js +0 -1
- package/lib/built/adapter-process.d.ts +11 -2
- package/lib/built/adapter-process.js +43 -2
- 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 +94 -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 +2 -1
- package/lib/built/command.js +14 -4
- 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 +0 -1
- package/lib/built/component.js +1 -3
- 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 +0 -1
- package/lib/built/database.js +1 -3
- package/lib/built/dispatcher.d.ts +6 -6
- package/lib/built/dispatcher.js +20 -8
- 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 +241 -0
- package/lib/built/endpoint-lifecycle.d.ts +0 -1
- package/lib/built/endpoint-lifecycle.js +0 -1
- 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 +6 -0
- package/lib/built/generic-segment-mapper.js +232 -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 +0 -1
- package/lib/built/inbound-pipeline.d.ts +0 -1
- package/lib/built/inbound-pipeline.js +0 -1
- 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 +54 -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 +10 -0
- package/lib/built/introspection-format.js +28 -0
- package/lib/built/login-assist.d.ts +1 -2
- package/lib/built/login-assist.js +0 -1
- 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 +0 -1
- 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 +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 +0 -1
- package/lib/built/permission.js +1 -3
- package/lib/built/permit-check.d.ts +0 -1
- 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 +18 -0
- package/lib/built/qrcode-segment.js +78 -0
- 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 +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 +39 -0
- package/lib/built/rich-segments/html-segment.d.ts +15 -0
- package/lib/built/rich-segments/html-segment.js +65 -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 +61 -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 +84 -0
- package/lib/built/rich-segments/types.js +17 -0
- 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 +55 -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 +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 +14 -0
- package/lib/built/speech-loader.js +32 -0
- 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 +0 -1
- 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 +25 -5
- package/lib/index.js +22 -4
- 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 +12 -2
- 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 +0 -1
- package/lib/notice.js +0 -1
- package/lib/plugin-context.d.ts +0 -1
- package/lib/plugin-context.js +0 -1
- package/lib/plugin.d.ts +11 -2
- package/lib/plugin.js +22 -23
- package/lib/prompt.d.ts +0 -1
- package/lib/prompt.js +1 -2
- package/lib/request.d.ts +0 -1
- package/lib/request.js +0 -1
- 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 +57 -12
- package/lib/utils.js +54 -19
- package/package.json +18 -9
- 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-lifecycle.d.ts.map +0 -1
- package/lib/built/endpoint-lifecycle.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/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-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/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/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/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
|
@@ -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,94 @@
|
|
|
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
|
+
const trailingFence = s.match(/^([\s\S]*?)\s*```\s*$/);
|
|
25
|
+
if (trailingFence)
|
|
26
|
+
s = trailingFence[1].trim();
|
|
27
|
+
return s;
|
|
28
|
+
}
|
|
29
|
+
export function unwrapAiOutboundJsonCandidate(raw) {
|
|
30
|
+
const trimmed = raw.trim();
|
|
31
|
+
const fenced = trimmed.match(/^```(?:json)?\s*([\s\S]*?)```\s*$/i);
|
|
32
|
+
if (fenced)
|
|
33
|
+
return fenced[1].trim();
|
|
34
|
+
const embeddedFence = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
35
|
+
if (embeddedFence && trimmed.indexOf('{') >= 0) {
|
|
36
|
+
return trimTrailingMarkdownFence(embeddedFence[1].trim());
|
|
37
|
+
}
|
|
38
|
+
return trimTrailingMarkdownFence(trimmed);
|
|
39
|
+
}
|
|
40
|
+
/** 从「正文 + 嵌入 JSON」混合文本中提取 AI outbound JSON(协作群常见误输出)。 */
|
|
41
|
+
export function extractEmbeddedAiOutboundJson(plain) {
|
|
42
|
+
const trimmed = plain.trim();
|
|
43
|
+
if (!trimmed.includes('{'))
|
|
44
|
+
return null;
|
|
45
|
+
const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
46
|
+
if (fenced) {
|
|
47
|
+
const jsonRaw = trimTrailingMarkdownFence(fenced[1].trim());
|
|
48
|
+
const payload = parseAiOutboundJson(jsonRaw);
|
|
49
|
+
if (payload?.mentions?.length && payload.text?.trim()) {
|
|
50
|
+
const prose = trimmed.slice(0, fenced.index).trim();
|
|
51
|
+
return { prose, jsonRaw };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
let idx = trimmed.indexOf('{');
|
|
55
|
+
while (idx >= 0) {
|
|
56
|
+
const jsonRaw = trimTrailingMarkdownFence(trimmed.slice(idx).trim());
|
|
57
|
+
const payload = parseAiOutboundJson(jsonRaw);
|
|
58
|
+
if (payload?.mentions?.length && payload.text?.trim()) {
|
|
59
|
+
return { prose: trimmed.slice(0, idx).trim(), jsonRaw };
|
|
60
|
+
}
|
|
61
|
+
idx = trimmed.indexOf('{', idx + 1);
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
export function parseAiOutboundJson(raw) {
|
|
66
|
+
const candidate = unwrapAiOutboundJsonCandidate(raw);
|
|
67
|
+
if (!candidate.startsWith('{'))
|
|
68
|
+
return null;
|
|
69
|
+
try {
|
|
70
|
+
const parsed = JSON.parse(candidate);
|
|
71
|
+
const text = typeof parsed.text === 'string' ? parsed.text.trim() : undefined;
|
|
72
|
+
const mentionsRaw = parsed.mentions;
|
|
73
|
+
const mentions = Array.isArray(mentionsRaw)
|
|
74
|
+
? mentionsRaw.map((m) => String(m).trim()).filter(Boolean)
|
|
75
|
+
: undefined;
|
|
76
|
+
const segmentsRaw = parsed.segments;
|
|
77
|
+
const segments = Array.isArray(segmentsRaw)
|
|
78
|
+
? segmentsRaw
|
|
79
|
+
.map((item) => parseOutboundSegment(item))
|
|
80
|
+
.filter((s) => s != null)
|
|
81
|
+
: undefined;
|
|
82
|
+
const extensions = parsed.extensions != null && typeof parsed.extensions === 'object' && !Array.isArray(parsed.extensions)
|
|
83
|
+
? parsed.extensions
|
|
84
|
+
: undefined;
|
|
85
|
+
if (!text && !mentions?.length && !segments?.length && !extensions)
|
|
86
|
+
return null;
|
|
87
|
+
if (mentions?.length && !text)
|
|
88
|
+
return null;
|
|
89
|
+
return { text, mentions, segments, extensions };
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AiOutboundCapabilities, AiOutboundExtensionDefinition } from './types.js';
|
|
2
|
+
export declare const AI_OUTBOUND_JSON_EXAMPLE = "{\"mentions\":[\"researcher\",\"210723495\"],\"text\":\"\u6B63\u6587\"}";
|
|
3
|
+
export declare function buildCoreAiOutboundPromptHint(capabilities?: AiOutboundCapabilities): string;
|
|
4
|
+
export declare function buildAiOutboundPromptHint(input: {
|
|
5
|
+
capabilities?: AiOutboundCapabilities;
|
|
6
|
+
extensions?: readonly AiOutboundExtensionDefinition[];
|
|
7
|
+
rosterLines?: string[];
|
|
8
|
+
forceJsonOnly?: boolean;
|
|
9
|
+
}): string;
|
|
10
|
+
/** 检测入站是否含 handoff / @ 意图(协作群 structured_only 信号)。 */
|
|
11
|
+
export declare function detectInboundHandoffIntent(content: string): boolean;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const AI_OUTBOUND_JSON_EXAMPLE = '{"mentions":["researcher","210723495"],"text":"正文"}';
|
|
2
|
+
export function buildCoreAiOutboundPromptHint(capabilities) {
|
|
3
|
+
const lines = [
|
|
4
|
+
'When your reply must @ peers, send rich media, buttons, or delegate — output JSON only (no Markdown wrapper):',
|
|
5
|
+
AI_OUTBOUND_JSON_EXAMPLE,
|
|
6
|
+
'mentions: peer endpoint ID or pipelineRole; text: message body.',
|
|
7
|
+
'Do NOT write "@researcher" in plain text — the framework converts JSON mentions to real platform @ segments.',
|
|
8
|
+
];
|
|
9
|
+
if (capabilities?.richSegments?.length) {
|
|
10
|
+
lines.push(`Rich segments (optional "segments" array): ${capabilities.richSegments.join(', ')}.`);
|
|
11
|
+
}
|
|
12
|
+
if (capabilities?.interactive === 'native') {
|
|
13
|
+
lines.push('Interactive buttons: use extensions field per adapter schema.');
|
|
14
|
+
}
|
|
15
|
+
return lines.join('\n');
|
|
16
|
+
}
|
|
17
|
+
export function buildAiOutboundPromptHint(input) {
|
|
18
|
+
const lines = [];
|
|
19
|
+
if (input.rosterLines?.length) {
|
|
20
|
+
lines.push(...input.rosterLines);
|
|
21
|
+
}
|
|
22
|
+
lines.push(buildCoreAiOutboundPromptHint(input.capabilities));
|
|
23
|
+
if (input.extensions?.length) {
|
|
24
|
+
lines.push('Adapter extensions (optional "extensions" object):');
|
|
25
|
+
for (const ext of input.extensions) {
|
|
26
|
+
lines.push(`- ${ext.key}: see platform schema`);
|
|
27
|
+
if (ext.examples[0])
|
|
28
|
+
lines.push(` example: ${ext.examples[0]}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (input.forceJsonOnly) {
|
|
32
|
+
lines.push('MUST reply with JSON only when @ peers or handoff — no Markdown body with plain "@role" text.');
|
|
33
|
+
}
|
|
34
|
+
return lines.join('\n');
|
|
35
|
+
}
|
|
36
|
+
/** 检测入站是否含 handoff / @ 意图(协作群 structured_only 信号)。 */
|
|
37
|
+
export function detectInboundHandoffIntent(content) {
|
|
38
|
+
const t = content.trim();
|
|
39
|
+
if (!t)
|
|
40
|
+
return false;
|
|
41
|
+
if (t.includes('@'))
|
|
42
|
+
return true;
|
|
43
|
+
return /依次|自我介绍|叫大家|请各位|handoff|delegate/i.test(t);
|
|
44
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MessageElement } from '../../types.js';
|
|
2
|
+
import type { AiOutboundParseContext, ZhinAiOutboundPayload } from './types.js';
|
|
3
|
+
/** 将 ZhinAiOutboundPayload 转为 MessageElement[](canonical segments + extensions)。 */
|
|
4
|
+
export declare function resolveAiOutboundToMessageElements(payload: ZhinAiOutboundPayload, ctx: AiOutboundParseContext): Promise<MessageElement[] | null>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { segmentsForImDelivery } from '../segment-contract/delivery.js';
|
|
2
|
+
function buildMentionSegments(endpointIds, text, ctx) {
|
|
3
|
+
const segments = [];
|
|
4
|
+
for (const endpointId of endpointIds) {
|
|
5
|
+
const target = ctx.atIdResolver?.(endpointId) ?? endpointId;
|
|
6
|
+
segments.push({ type: 'mention', data: { target } });
|
|
7
|
+
}
|
|
8
|
+
const body = text.trim();
|
|
9
|
+
segments.push({
|
|
10
|
+
type: 'text',
|
|
11
|
+
data: { text: body.startsWith(' ') ? body : ` ${body}` },
|
|
12
|
+
});
|
|
13
|
+
return segments;
|
|
14
|
+
}
|
|
15
|
+
function resolveMentionEndpointIds(mentions, ctx) {
|
|
16
|
+
if (!mentions?.length) {
|
|
17
|
+
return { ok: false, error: 'mentions 不能为空' };
|
|
18
|
+
}
|
|
19
|
+
if (!ctx.mentionResolver) {
|
|
20
|
+
return { ok: false, error: 'mentionResolver 未配置' };
|
|
21
|
+
}
|
|
22
|
+
const endpointIds = [];
|
|
23
|
+
for (const ref of mentions) {
|
|
24
|
+
const resolved = ctx.mentionResolver(ref);
|
|
25
|
+
if (!resolved) {
|
|
26
|
+
return { ok: false, error: `未知 peer "${ref}"` };
|
|
27
|
+
}
|
|
28
|
+
if (!endpointIds.includes(resolved))
|
|
29
|
+
endpointIds.push(resolved);
|
|
30
|
+
}
|
|
31
|
+
return { ok: true, endpointIds };
|
|
32
|
+
}
|
|
33
|
+
/** 将 ZhinAiOutboundPayload 转为 MessageElement[](canonical segments + extensions)。 */
|
|
34
|
+
export async function resolveAiOutboundToMessageElements(payload, ctx) {
|
|
35
|
+
const segments = [];
|
|
36
|
+
if (payload.mentions?.length) {
|
|
37
|
+
const resolved = resolveMentionEndpointIds(payload.mentions, ctx);
|
|
38
|
+
if (!resolved.ok)
|
|
39
|
+
return null;
|
|
40
|
+
const text = payload.text?.trim() ?? '';
|
|
41
|
+
if (!text)
|
|
42
|
+
return null;
|
|
43
|
+
segments.push(...buildMentionSegments(resolved.endpointIds, text, ctx));
|
|
44
|
+
}
|
|
45
|
+
else if (payload.text?.trim()) {
|
|
46
|
+
segments.push({ type: 'text', data: { text: payload.text.trim() } });
|
|
47
|
+
}
|
|
48
|
+
if (payload.segments?.length) {
|
|
49
|
+
segments.push(...payload.segments);
|
|
50
|
+
}
|
|
51
|
+
const parts = segments.length
|
|
52
|
+
? segmentsForImDelivery(segments)
|
|
53
|
+
: [];
|
|
54
|
+
if (payload.extensions && ctx.extensions?.length) {
|
|
55
|
+
for (const def of ctx.extensions) {
|
|
56
|
+
const ext = payload.extensions[def.key];
|
|
57
|
+
if (ext == null || !def.toMessageElements)
|
|
58
|
+
continue;
|
|
59
|
+
const extSegments = await def.toMessageElements(ext, ctx);
|
|
60
|
+
parts.push(...(Array.isArray(extSegments) ? extSegments : [extSegments]));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return parts.length ? parts : null;
|
|
64
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Message } from '../../message.js';
|
|
2
|
+
import type { MessageElement } from '../../types.js';
|
|
3
|
+
import type { InteractivePolicy } from '../interactive-segments/types.js';
|
|
4
|
+
import type { Segment } from '../segment-contract/types.js';
|
|
5
|
+
/** AI 结构化出站 payload — 平台无关 DSL(Adapter extensions 承载平台特有段)。 */
|
|
6
|
+
export interface ZhinAiOutboundPayload {
|
|
7
|
+
text?: string;
|
|
8
|
+
mentions?: string[];
|
|
9
|
+
segments?: Segment[];
|
|
10
|
+
extensions?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated 使用 canonical `Segment`(`type` + `data` + 可选 `platform`)。
|
|
14
|
+
* 历史 `kind` → `type`;`mode` 已删除。
|
|
15
|
+
*/
|
|
16
|
+
export interface AiOutboundSegment {
|
|
17
|
+
kind: string;
|
|
18
|
+
mode?: string;
|
|
19
|
+
data?: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
export interface AiOutboundCapabilities {
|
|
22
|
+
mentions?: boolean;
|
|
23
|
+
richSegments?: readonly string[];
|
|
24
|
+
interactive?: InteractivePolicy;
|
|
25
|
+
}
|
|
26
|
+
export interface AiOutboundExtensionDefinition {
|
|
27
|
+
/** 平台扩展字段名,如 qq.ark / onebot.keyboard */
|
|
28
|
+
key: string;
|
|
29
|
+
/** JSON Schema 子集,对齐平台 SDK 文档 */
|
|
30
|
+
schema: Record<string, unknown>;
|
|
31
|
+
examples: readonly string[];
|
|
32
|
+
toMessageElements?: (ext: unknown, ctx: AiOutboundParseContext) => MessageElement[] | Promise<MessageElement[]>;
|
|
33
|
+
}
|
|
34
|
+
export interface AiOutboundMentionResolver {
|
|
35
|
+
(ref: string): string | undefined;
|
|
36
|
+
}
|
|
37
|
+
export interface AiOutboundAtIdResolver {
|
|
38
|
+
(endpointId: string): string;
|
|
39
|
+
}
|
|
40
|
+
/** 解析 AI 出站 JSON 时的上下文。 */
|
|
41
|
+
export interface AiOutboundParseContext {
|
|
42
|
+
message: Message;
|
|
43
|
+
/** 将 peer ref(role/endpoint/primary)解析为 endpointId */
|
|
44
|
+
mentionResolver?: AiOutboundMentionResolver;
|
|
45
|
+
/** 将 endpointId 解析为 platform @ id */
|
|
46
|
+
atIdResolver?: AiOutboundAtIdResolver;
|
|
47
|
+
/** Adapter 声明的 extensions(运行时从 Adapter 静态属性注入) */
|
|
48
|
+
extensions?: readonly AiOutboundExtensionDefinition[];
|
|
49
|
+
}
|
|
50
|
+
export interface StructuredOutboundDetectInput {
|
|
51
|
+
/** 协作 Cell 活跃且可能 @ peer */
|
|
52
|
+
collaborationCell?: boolean;
|
|
53
|
+
/** 工具链要求结构化出站(如 group_delegate message JSON) */
|
|
54
|
+
toolRequiresStructured?: boolean;
|
|
55
|
+
/** 用户入站含 handoff / @ 意图 */
|
|
56
|
+
inboundHandoffIntent?: boolean;
|
|
57
|
+
/** Adapter 声明 extensions 且非空 */
|
|
58
|
+
adapterHasExtensions?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export declare const DEFAULT_AI_OUTBOUND_CAPABILITIES: AiOutboundCapabilities;
|
|
@@ -39,6 +39,11 @@ export interface AITriggerConfig {
|
|
|
39
39
|
trusted?: string[];
|
|
40
40
|
/** 是否在 AI 入参前拉取 $quote_id 对应消息正文(默认 true) */
|
|
41
41
|
resolveQuotedMessages?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* 协作单元内 peer Bot 入站策略(ADR 0023)。
|
|
44
|
+
* mention-only:仅被 @ 时触发;off:与普通人消息相同规则。
|
|
45
|
+
*/
|
|
46
|
+
peerMode?: 'mention-only' | 'off';
|
|
42
47
|
}
|
|
43
48
|
/**
|
|
44
49
|
* AI 触发检查结果
|
|
@@ -97,4 +102,3 @@ export declare function shouldTriggerAI<T extends object>(message: Message<T>, c
|
|
|
97
102
|
* 合并配置
|
|
98
103
|
*/
|
|
99
104
|
export declare function mergeAITriggerConfig(config: AITriggerConfig): Required<AITriggerConfig>;
|
|
100
|
-
//# sourceMappingURL=ai-trigger.d.ts.map
|
package/lib/built/ai-trigger.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* 4. 关键词触发 - 非群/频道场景下匹配关键词时触发
|
|
10
10
|
*/
|
|
11
11
|
import { segment } from "../utils.js";
|
|
12
|
+
import { readMentionSegmentTarget } from './segment-contract/mention.js';
|
|
12
13
|
import { normalizeSenderRoles, } from './roles.js';
|
|
13
14
|
// ============================================================================
|
|
14
15
|
// 默认配置
|
|
@@ -26,6 +27,7 @@ export const DEFAULT_AI_TRIGGER_CONFIG = {
|
|
|
26
27
|
masters: [],
|
|
27
28
|
trusted: [],
|
|
28
29
|
resolveQuotedMessages: true,
|
|
30
|
+
peerMode: 'mention-only',
|
|
29
31
|
};
|
|
30
32
|
// ============================================================================
|
|
31
33
|
// 工具函数
|
|
@@ -35,12 +37,7 @@ function normalizeAtIds(endpointAtIds) {
|
|
|
35
37
|
return [...new Set(ids.map((id) => String(id)).filter(Boolean))];
|
|
36
38
|
}
|
|
37
39
|
function segmentAtUserId(seg) {
|
|
38
|
-
|
|
39
|
-
if (!data || typeof data !== 'object')
|
|
40
|
-
return '';
|
|
41
|
-
const record = data;
|
|
42
|
-
const raw = record.user_id ?? record.qq ?? record.id;
|
|
43
|
-
return raw == null ? '' : String(raw);
|
|
40
|
+
return readMentionSegmentTarget(seg);
|
|
44
41
|
}
|
|
45
42
|
function isAtSegmentForEndpoint(seg, endpointIds) {
|
|
46
43
|
if (seg.type !== 'at' && seg.type !== 'mention')
|
|
@@ -233,4 +230,3 @@ export function shouldTriggerAI(message, config, options) {
|
|
|
233
230
|
export function mergeAITriggerConfig(config) {
|
|
234
231
|
return { ...DEFAULT_AI_TRIGGER_CONFIG, ...config };
|
|
235
232
|
}
|
|
236
|
-
//# sourceMappingURL=ai-trigger.js.map
|
|
@@ -8,4 +8,3 @@ import { type SenderRolesResult } from './ai-trigger.js';
|
|
|
8
8
|
* 从 ConfigFeature + Message 重算发送者角色(含群角色与 master/trusted)
|
|
9
9
|
*/
|
|
10
10
|
export declare function resolveSubjectRoles(plugin: Plugin, message: Message<any>): SenderRolesResult;
|
|
11
|
-
//# sourceMappingURL=authorization.d.ts.map
|
package/lib/built/command.d.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
import { Feature, FeatureJSON } from "@zhin.js/kernel";
|
|
6
6
|
/** 命令 pattern 的首个词(用于前缀排序) */
|
|
7
7
|
export declare function commandLeadingToken(pattern: string): string;
|
|
8
|
+
/** 命令匹配优先级:首词越长越优先;同首词则完整 pattern 越长越优先 */
|
|
9
|
+
export declare function compareCommandPatterns(a: string, b: string): number;
|
|
8
10
|
import { MessageCommand } from "../command.js";
|
|
9
11
|
import { Message } from "../message.js";
|
|
10
12
|
import { Plugin } from "../plugin.js";
|
|
@@ -65,4 +67,3 @@ export declare class CommandFeature extends Feature<MessageCommand<RegisteredAda
|
|
|
65
67
|
addCommand<T extends RegisteredAdapter>(command: MessageCommand<T>): () => void;
|
|
66
68
|
};
|
|
67
69
|
}
|
|
68
|
-
//# sourceMappingURL=command.d.ts.map
|
package/lib/built/command.js
CHANGED
|
@@ -7,7 +7,18 @@ import { Feature } from "@zhin.js/kernel";
|
|
|
7
7
|
export function commandLeadingToken(pattern) {
|
|
8
8
|
return pattern.split(/\s/)[0] ?? "";
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
/** 命令匹配优先级:首词越长越优先;同首词则完整 pattern 越长越优先 */
|
|
11
|
+
export function compareCommandPatterns(a, b) {
|
|
12
|
+
const leadDiff = commandLeadingToken(b).length - commandLeadingToken(a).length;
|
|
13
|
+
if (leadDiff !== 0)
|
|
14
|
+
return leadDiff;
|
|
15
|
+
const lenDiff = b.length - a.length;
|
|
16
|
+
if (lenDiff !== 0)
|
|
17
|
+
return lenDiff;
|
|
18
|
+
const tokA = a.trim().split(/\s+/).length;
|
|
19
|
+
const tokB = b.trim().split(/\s+/).length;
|
|
20
|
+
return tokB - tokA;
|
|
21
|
+
}
|
|
11
22
|
/**
|
|
12
23
|
* 命令服务 Feature
|
|
13
24
|
*/
|
|
@@ -41,7 +52,7 @@ export class CommandFeature extends Feature {
|
|
|
41
52
|
* 处理消息,依次尝试匹配命令(较长前缀优先,避免 `teach` 抢 `teach-list`)
|
|
42
53
|
*/
|
|
43
54
|
async handle(message, plugin) {
|
|
44
|
-
const commands = [...this.items].sort((a, b) =>
|
|
55
|
+
const commands = [...this.items].sort((a, b) => compareCommandPatterns(a.pattern, b.pattern));
|
|
45
56
|
for (const command of commands) {
|
|
46
57
|
const result = await command.handle(message, plugin);
|
|
47
58
|
if (result)
|
|
@@ -80,7 +91,7 @@ export class CommandFeature extends Feature {
|
|
|
80
91
|
const feature = this;
|
|
81
92
|
return {
|
|
82
93
|
addCommand(command) {
|
|
83
|
-
const plugin =
|
|
94
|
+
const plugin = this;
|
|
84
95
|
const dispose = feature.add(command, plugin.name);
|
|
85
96
|
plugin.recordFeatureContribution(feature.name, command.pattern);
|
|
86
97
|
plugin.onDispose(dispose);
|
|
@@ -89,4 +100,3 @@ export class CommandFeature extends Feature {
|
|
|
89
100
|
};
|
|
90
101
|
}
|
|
91
102
|
}
|
|
92
|
-
//# sourceMappingURL=command.js.map
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Scene Management — 方法规范与 Tool 工厂
|
|
3
3
|
*
|
|
4
4
|
* 设计理念:
|
|
5
|
-
* 各 IM
|
|
5
|
+
* 各 IM 平台在适配器内自行实现场景治理方法(removeMember、muteMember 等),
|
|
6
6
|
* 并自行注册 Tool;平台说明使用包内 `skills/<adapter>/SKILL.md`。
|
|
7
7
|
*
|
|
8
8
|
* 使用方式(在各适配器 start 或注册方法中):
|
|
9
9
|
*
|
|
10
|
-
* import {
|
|
11
|
-
* const tools =
|
|
10
|
+
* import { createSceneManagementTools, SCENE_MANAGEMENT_SKILL_KEYWORDS, SCENE_MANAGEMENT_SKILL_TAGS } from 'zhin.js';
|
|
11
|
+
* const tools = createSceneManagementTools(this, this.name);
|
|
12
12
|
* tools.forEach(t => this.addTool(t));
|
|
13
13
|
* // 另:包内 skills/<name>/SKILL.md 供 Agent 发现
|
|
14
14
|
*/
|
|
15
15
|
import type { Tool } from '../types.js';
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* 场景治理能力接口。
|
|
18
18
|
* Adapter 基类通过此接口声明方法签名,子类选择性覆写。
|
|
19
19
|
*/
|
|
20
|
-
export interface
|
|
21
|
-
|
|
20
|
+
export interface ISceneManagement {
|
|
21
|
+
removeMember?(endpointId: string, sceneId: string, userId: string): Promise<any>;
|
|
22
22
|
muteMember?(endpointId: string, sceneId: string, userId: string, duration?: number): Promise<any>;
|
|
23
23
|
setMemberNickname?(endpointId: string, sceneId: string, userId: string, nickname: string): Promise<any>;
|
|
24
|
-
|
|
24
|
+
setModerator?(endpointId: string, sceneId: string, userId: string, enable?: boolean): Promise<any>;
|
|
25
25
|
listMembers?(endpointId: string, sceneId: string): Promise<any>;
|
|
26
26
|
banMember?(endpointId: string, sceneId: string, userId: string, reason?: string): Promise<any>;
|
|
27
27
|
unbanMember?(endpointId: string, sceneId: string, userId: string): Promise<any>;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
renameScene?(endpointId: string, sceneId: string, name: string): Promise<any>;
|
|
29
|
+
setSceneMuted?(endpointId: string, sceneId: string, enable?: boolean): Promise<any>;
|
|
30
|
+
getSceneInfo?(endpointId: string, sceneId: string): Promise<any>;
|
|
31
31
|
}
|
|
32
|
-
export interface
|
|
33
|
-
method: keyof
|
|
32
|
+
export interface SceneManagementMethodSpec {
|
|
33
|
+
method: keyof ISceneManagement;
|
|
34
34
|
toolSuffix: string;
|
|
35
35
|
description: string;
|
|
36
36
|
keywords: string[];
|
|
@@ -43,20 +43,19 @@ export interface GroupMethodSpec {
|
|
|
43
43
|
extraRequired?: string[];
|
|
44
44
|
preExecutable?: boolean;
|
|
45
45
|
}
|
|
46
|
-
export declare const
|
|
47
|
-
export declare const
|
|
48
|
-
export declare const
|
|
49
|
-
export interface
|
|
50
|
-
(spec:
|
|
46
|
+
export declare const SCENE_MANAGEMENT_METHOD_SPECS: SceneManagementMethodSpec[];
|
|
47
|
+
export declare const SCENE_MANAGEMENT_SKILL_TAGS: string[];
|
|
48
|
+
export declare const SCENE_MANAGEMENT_SKILL_KEYWORDS: string[];
|
|
49
|
+
export interface SceneManagementToolFactory<T> {
|
|
50
|
+
(spec: SceneManagementMethodSpec, prefix: string, execute: (args: Record<string, any>) => Promise<any>): T;
|
|
51
51
|
}
|
|
52
|
-
export declare function
|
|
53
|
-
export interface
|
|
54
|
-
/** 将
|
|
52
|
+
export declare function defaultScenePermitResolver(adapterPrefix: string): (logicalPerm: string) => string;
|
|
53
|
+
export interface CreateSceneManagementToolsOptions {
|
|
54
|
+
/** 将 SCENE_MANAGEMENT_METHOD_SPECS 逻辑 perm(scene_admin/scene_owner)映射为 platform(...) 字符串 */
|
|
55
55
|
permitResolver?: (logicalPerm: string) => string | undefined;
|
|
56
|
-
/** 是否注册默认 QQ 系
|
|
56
|
+
/** 是否注册默认 QQ 系 scene checker(默认 true) */
|
|
57
57
|
registerChecker?: boolean;
|
|
58
58
|
}
|
|
59
|
-
export declare function
|
|
60
|
-
export declare function
|
|
61
|
-
export declare function
|
|
62
|
-
//# sourceMappingURL=common-adapter-tools.d.ts.map
|
|
59
|
+
export declare function createSceneManagementTools(adapter: ISceneManagement, prefix: string, options?: CreateSceneManagementToolsOptions): Tool[];
|
|
60
|
+
export declare function createSceneManagementToolsRaw<T>(adapter: ISceneManagement, prefix: string, factory: SceneManagementToolFactory<T>): T[];
|
|
61
|
+
export declare function buildSceneMethodArgs(method: keyof ISceneManagement, endpointId: string, sceneId: string, rest: Record<string, any>): any[];
|