@zhin.js/core 1.1.33 → 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 +140 -61
- package/lib/adapter.d.ts +72 -23
- package/lib/adapter.js +222 -58
- 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 +9 -0
- package/lib/built/html-segment-fallback.js +49 -0
- package/lib/built/html-to-text.d.ts +4 -1
- package/lib/built/html-to-text.js +47 -16
- 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 +67 -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 -21
- package/lib/index.js +53 -28
- 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 -85
- package/lib/types.js +0 -1
- package/lib/utils.d.ts +68 -1
- package/lib/utils.js +73 -11
- 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-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/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 -33
- package/lib/built/prepend-quote-context.d.ts.map +0 -1
- package/lib/built/prepend-quote-context.js +0 -129
- 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
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScheduleFeature — 管理插件注册的内存定时任务
|
|
3
|
+
*/
|
|
4
|
+
import { Feature, FeatureJSON, type ScheduleKind, type HolidayInput, type ScatterInput } from '@zhin.js/kernel';
|
|
5
|
+
export interface ScheduleDescriptor {
|
|
6
|
+
kind: ScheduleKind | 'every' | 'at';
|
|
7
|
+
/** 6 段 cron(solar/lunar/workday/freeDay/holiday) */
|
|
8
|
+
cron?: string;
|
|
9
|
+
everyMs?: number;
|
|
10
|
+
atMs?: number;
|
|
11
|
+
scatterInput?: ScatterInput;
|
|
12
|
+
holidayInput?: HolidayInput;
|
|
13
|
+
tz?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ScheduleHandle {
|
|
16
|
+
id: string;
|
|
17
|
+
descriptor: ScheduleDescriptor;
|
|
18
|
+
dispose: () => void;
|
|
19
|
+
}
|
|
20
|
+
export interface ScheduleContextExtensions {
|
|
21
|
+
addSchedule(descriptor: ScheduleDescriptor, callback: () => void | Promise<void>, id?: string): () => void;
|
|
22
|
+
}
|
|
23
|
+
declare module '../plugin.js' {
|
|
24
|
+
namespace Plugin {
|
|
25
|
+
interface Extensions extends ScheduleContextExtensions {
|
|
26
|
+
}
|
|
27
|
+
interface Contexts {
|
|
28
|
+
schedule: ScheduleFeature;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export declare class ScheduleFeature extends Feature<ScheduleHandle> {
|
|
33
|
+
readonly name: "schedule";
|
|
34
|
+
readonly icon = "Clock";
|
|
35
|
+
readonly desc = "\u65E5\u5386\u8C03\u5EA6";
|
|
36
|
+
readonly byName: Map<string, ScheduleHandle>;
|
|
37
|
+
add(handle: ScheduleHandle, pluginName: string): () => void;
|
|
38
|
+
remove(handle: ScheduleHandle): boolean;
|
|
39
|
+
get(id: string): ScheduleHandle | undefined;
|
|
40
|
+
stopAll(): void;
|
|
41
|
+
getStatus(): Array<{
|
|
42
|
+
id: string;
|
|
43
|
+
kind: string;
|
|
44
|
+
expression?: string;
|
|
45
|
+
running: boolean;
|
|
46
|
+
nextExecution: Date | null;
|
|
47
|
+
plugin: string;
|
|
48
|
+
}>;
|
|
49
|
+
dispose(): void;
|
|
50
|
+
toJSON(pluginName?: string): FeatureJSON;
|
|
51
|
+
get extensions(): {
|
|
52
|
+
addSchedule(descriptor: ScheduleDescriptor, callback: () => void | Promise<void>, id?: string): () => void;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScheduleFeature — 管理插件注册的内存定时任务
|
|
3
|
+
*/
|
|
4
|
+
import { Feature, ScheduleEngine, getScheduleEngine, setScheduleEngine } from '@zhin.js/kernel';
|
|
5
|
+
function ensureEngine() {
|
|
6
|
+
let engine = getScheduleEngine();
|
|
7
|
+
if (!engine) {
|
|
8
|
+
engine = new ScheduleEngine();
|
|
9
|
+
setScheduleEngine(engine);
|
|
10
|
+
}
|
|
11
|
+
return engine;
|
|
12
|
+
}
|
|
13
|
+
export class ScheduleFeature extends Feature {
|
|
14
|
+
name = 'schedule';
|
|
15
|
+
icon = 'Clock';
|
|
16
|
+
desc = '日历调度';
|
|
17
|
+
byName = new Map();
|
|
18
|
+
add(handle, pluginName) {
|
|
19
|
+
this.byName.set(handle.id, handle);
|
|
20
|
+
return super.add(handle, pluginName);
|
|
21
|
+
}
|
|
22
|
+
remove(handle) {
|
|
23
|
+
if (!this.byName.has(handle.id) && !this.items.includes(handle)) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
this.byName.delete(handle.id);
|
|
27
|
+
const removed = super.remove(handle);
|
|
28
|
+
if (removed) {
|
|
29
|
+
handle.dispose();
|
|
30
|
+
}
|
|
31
|
+
return removed;
|
|
32
|
+
}
|
|
33
|
+
get(id) {
|
|
34
|
+
return this.byName.get(id);
|
|
35
|
+
}
|
|
36
|
+
stopAll() {
|
|
37
|
+
for (const handle of this.items) {
|
|
38
|
+
handle.dispose();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
getStatus() {
|
|
42
|
+
const engine = getScheduleEngine();
|
|
43
|
+
const engineStatus = engine?.getStatus() ?? [];
|
|
44
|
+
const byId = new Map(engineStatus.map((s) => [s.id, s]));
|
|
45
|
+
return this.items.map((handle) => {
|
|
46
|
+
let pluginName = 'unknown';
|
|
47
|
+
for (const [name, items] of this.pluginItems) {
|
|
48
|
+
if (items.includes(handle)) {
|
|
49
|
+
pluginName = name;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const st = byId.get(handle.id);
|
|
54
|
+
return {
|
|
55
|
+
id: handle.id,
|
|
56
|
+
kind: handle.descriptor.kind,
|
|
57
|
+
expression: handle.descriptor.cron,
|
|
58
|
+
running: st?.running ?? true,
|
|
59
|
+
nextExecution: st?.nextExecution ?? null,
|
|
60
|
+
plugin: pluginName,
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
dispose() {
|
|
65
|
+
this.stopAll();
|
|
66
|
+
}
|
|
67
|
+
toJSON(pluginName) {
|
|
68
|
+
const list = pluginName ? this.getByPlugin(pluginName) : this.items;
|
|
69
|
+
return {
|
|
70
|
+
name: this.name,
|
|
71
|
+
icon: this.icon,
|
|
72
|
+
desc: this.desc,
|
|
73
|
+
count: list.length,
|
|
74
|
+
items: list.map((h) => ({
|
|
75
|
+
id: h.id,
|
|
76
|
+
kind: h.descriptor.kind,
|
|
77
|
+
cron: h.descriptor.cron,
|
|
78
|
+
})),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
get extensions() {
|
|
82
|
+
const feature = this;
|
|
83
|
+
return {
|
|
84
|
+
addSchedule(descriptor, callback, id) {
|
|
85
|
+
const plugin = this;
|
|
86
|
+
const jobId = id ?? `sched_${Math.random().toString(36).slice(2, 10)}`;
|
|
87
|
+
const engine = ensureEngine();
|
|
88
|
+
const disposeEngine = engine.register(jobId, descriptor.kind, async () => {
|
|
89
|
+
await callback();
|
|
90
|
+
}, {
|
|
91
|
+
cron: descriptor.cron,
|
|
92
|
+
everyMs: descriptor.everyMs,
|
|
93
|
+
atMs: descriptor.atMs,
|
|
94
|
+
scatterInput: descriptor.scatterInput,
|
|
95
|
+
holidayInput: descriptor.holidayInput,
|
|
96
|
+
tz: descriptor.tz,
|
|
97
|
+
});
|
|
98
|
+
const handle = {
|
|
99
|
+
id: jobId,
|
|
100
|
+
descriptor,
|
|
101
|
+
dispose: () => {
|
|
102
|
+
disposeEngine();
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
const dispose = feature.add(handle, plugin.name);
|
|
106
|
+
plugin.recordFeatureContribution(feature.name, jobId);
|
|
107
|
+
plugin.onDispose(dispose);
|
|
108
|
+
return dispose;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Schema } from '@zhin.js/schema';
|
|
2
|
+
import { Adapter } from '../adapter.js';
|
|
3
|
+
import type { EndpointConfigRecord, EndpointManager, ProvisionContext } from './endpoint-manager.js';
|
|
4
|
+
export declare class SchemaEndpointManager implements EndpointManager {
|
|
5
|
+
private readonly adapter;
|
|
6
|
+
private readonly schema;
|
|
7
|
+
constructor(adapter: Adapter, schema: Schema);
|
|
8
|
+
supportsProvision(): boolean;
|
|
9
|
+
listEndpoints(): EndpointConfigRecord[];
|
|
10
|
+
addEndpoint(ctx: ProvisionContext): Promise<EndpointConfigRecord>;
|
|
11
|
+
editEndpoint(name: string, ctx: ProvisionContext): Promise<EndpointConfigRecord>;
|
|
12
|
+
removeEndpoint(name: string): Promise<boolean>;
|
|
13
|
+
startEndpoint(name: string, ctx: ProvisionContext): Promise<void>;
|
|
14
|
+
stopEndpoint(name: string): Promise<boolean>;
|
|
15
|
+
}
|
|
16
|
+
export declare function resolveEndpointManager(adapter: Adapter): EndpointManager | null;
|
|
17
|
+
export declare function adapterSupportsProvision(adapter: Adapter): boolean;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { SchemaInteraction } from '../schema-interaction.js';
|
|
2
|
+
function readConfigEndpoints(root, context) {
|
|
3
|
+
const configService = root.inject('config');
|
|
4
|
+
const raw = configService?.getRaw(configService.primaryFile);
|
|
5
|
+
return (raw?.endpoints ?? []).filter((e) => e.context === context);
|
|
6
|
+
}
|
|
7
|
+
export class SchemaEndpointManager {
|
|
8
|
+
adapter;
|
|
9
|
+
schema;
|
|
10
|
+
constructor(adapter, schema) {
|
|
11
|
+
this.adapter = adapter;
|
|
12
|
+
this.schema = schema;
|
|
13
|
+
}
|
|
14
|
+
supportsProvision() {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
listEndpoints() {
|
|
18
|
+
return readConfigEndpoints(this.adapter.plugin.root, String(this.adapter.name));
|
|
19
|
+
}
|
|
20
|
+
async addEndpoint(ctx) {
|
|
21
|
+
const interaction = new SchemaInteraction(this.adapter.plugin, ctx.message);
|
|
22
|
+
await ctx.onStatusUpdate(`请按提示填写 ${String(this.adapter.name)} endpoint 配置:`);
|
|
23
|
+
const name = await interaction.text('Endpoint id(zhin.config endpoints[].id):');
|
|
24
|
+
const fields = await interaction.getValueWithSchema(this.schema);
|
|
25
|
+
return {
|
|
26
|
+
context: String(this.adapter.name),
|
|
27
|
+
id: name.trim(),
|
|
28
|
+
...fields,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async editEndpoint(name, ctx) {
|
|
32
|
+
const existing = this.listEndpoints().find((e) => e.id === name);
|
|
33
|
+
if (!existing) {
|
|
34
|
+
throw new Error(`配置中不存在 ${String(this.adapter.name)}/${name}`);
|
|
35
|
+
}
|
|
36
|
+
await ctx.onStatusUpdate(`编辑 ${String(this.adapter.name)}/${name},留空字段将保留原值。`);
|
|
37
|
+
const interaction = new SchemaInteraction(this.adapter.plugin, ctx.message);
|
|
38
|
+
const fields = await interaction.getValueWithSchema(this.schema);
|
|
39
|
+
return {
|
|
40
|
+
...existing,
|
|
41
|
+
...fields,
|
|
42
|
+
context: String(this.adapter.name),
|
|
43
|
+
id: name,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async removeEndpoint(name) {
|
|
47
|
+
return this.listEndpoints().some((e) => e.id === name);
|
|
48
|
+
}
|
|
49
|
+
async startEndpoint(name, ctx) {
|
|
50
|
+
const rec = this.listEndpoints().find((e) => e.id === name);
|
|
51
|
+
if (!rec)
|
|
52
|
+
throw new Error(`配置中不存在 ${String(this.adapter.name)}/${name}`);
|
|
53
|
+
await ctx.onStatusUpdate(`正在连接 ${String(this.adapter.name)}/${name}…`);
|
|
54
|
+
}
|
|
55
|
+
async stopEndpoint(name) {
|
|
56
|
+
return this.adapter.endpoints.has(name);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function resolveEndpointManager(adapter) {
|
|
60
|
+
const custom = adapter.getEndpointManager?.();
|
|
61
|
+
if (custom)
|
|
62
|
+
return custom;
|
|
63
|
+
const schema = adapter.getEndpointConfigSchema?.() ??
|
|
64
|
+
adapter.constructor.endpointConfigSchema;
|
|
65
|
+
if (schema) {
|
|
66
|
+
return new SchemaEndpointManager(adapter, schema);
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
export function adapterSupportsProvision(adapter) {
|
|
71
|
+
const manager = resolveEndpointManager(adapter);
|
|
72
|
+
return manager?.supportsProvision() ?? false;
|
|
73
|
+
}
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
* - Schema.toJSON() 传给前端驱动 PluginConfigForm
|
|
10
10
|
* - reloadable 标记决定保存后是否自动重载插件
|
|
11
11
|
*/
|
|
12
|
-
import { getPlugin } from '../plugin.js';
|
|
13
12
|
import { Feature } from '@zhin.js/kernel';
|
|
14
13
|
// ============================================================================
|
|
15
14
|
// SchemaFeature
|
|
@@ -91,7 +90,7 @@ export class SchemaFeature extends Feature {
|
|
|
91
90
|
const feature = this;
|
|
92
91
|
return {
|
|
93
92
|
declareConfig(key, schema, options) {
|
|
94
|
-
const plugin =
|
|
93
|
+
const plugin = this;
|
|
95
94
|
const reloadable = options?.reloadable ?? true;
|
|
96
95
|
// 从 Schema 提取默认值
|
|
97
96
|
const defaults = extractDefaults(schema);
|
|
@@ -129,4 +128,3 @@ function extractDefaults(schema) {
|
|
|
129
128
|
}
|
|
130
129
|
return result;
|
|
131
130
|
}
|
|
132
|
-
//# sourceMappingURL=schema-feature.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Segment } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 内建 canonical 类型始终走 schema 严格校验。Core 预留扩展和命名空间扩展
|
|
4
|
+
* 只承诺稳定顶层形状;裸未知类型会被拒绝,避免拼写错误绕过 canonical 校验。
|
|
5
|
+
*/
|
|
6
|
+
export declare function isCanonicalSegment(value: unknown): value is Segment;
|
|
7
|
+
export declare function assertCanonicalSegments(segments: unknown): asserts segments is Segment[];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { isStrictCanonicalSegment } from './validate.js';
|
|
2
|
+
const STRICT_CANONICAL_TYPES = new Set([
|
|
3
|
+
'text', 'mention', 'image', 'audio', 'video', 'file', 'reply', 'forward', 'face', 'dice', 'rps',
|
|
4
|
+
]);
|
|
5
|
+
// These are Core-owned wire extensions rather than canonical data types. Keep
|
|
6
|
+
// their gradual contracts isolated here; third-party extensions must be
|
|
7
|
+
// namespaced so a future canonical type cannot silently collide with them.
|
|
8
|
+
const CORE_EXTENSION_TYPES = new Set([
|
|
9
|
+
'action', 'html', 'keyboard', 'link', 'markdown', 'qrcode', 'record', 'tts', 'voice',
|
|
10
|
+
]);
|
|
11
|
+
const extensionTypePattern = /^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)+$/u;
|
|
12
|
+
function isPlainObject(value) {
|
|
13
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 内建 canonical 类型始终走 schema 严格校验。Core 预留扩展和命名空间扩展
|
|
17
|
+
* 只承诺稳定顶层形状;裸未知类型会被拒绝,避免拼写错误绕过 canonical 校验。
|
|
18
|
+
*/
|
|
19
|
+
export function isCanonicalSegment(value) {
|
|
20
|
+
if (!isPlainObject(value) || typeof value.type !== 'string')
|
|
21
|
+
return false;
|
|
22
|
+
if (!isPlainObject(value.data))
|
|
23
|
+
return false;
|
|
24
|
+
if (value.platform !== undefined && !isPlainObject(value.platform))
|
|
25
|
+
return false;
|
|
26
|
+
if (STRICT_CANONICAL_TYPES.has(value.type))
|
|
27
|
+
return isStrictCanonicalSegment(value);
|
|
28
|
+
return CORE_EXTENSION_TYPES.has(value.type) || extensionTypePattern.test(value.type);
|
|
29
|
+
}
|
|
30
|
+
export function assertCanonicalSegments(segments) {
|
|
31
|
+
if (!Array.isArray(segments)) {
|
|
32
|
+
throw new Error('segments must be an array');
|
|
33
|
+
}
|
|
34
|
+
for (let i = 0; i < segments.length; i++) {
|
|
35
|
+
if (!isCanonicalSegment(segments[i])) {
|
|
36
|
+
throw new Error(`segment[${i}] is not canonical`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { isCanonicalSegment } from './assert.js';
|
|
2
|
+
/** IM 可见段白名单(thinking / tool_call 等 AI-only 段过滤) */
|
|
3
|
+
const IM_VISIBLE_TYPES = new Set([
|
|
4
|
+
'text',
|
|
5
|
+
'mention',
|
|
6
|
+
'image',
|
|
7
|
+
'video',
|
|
8
|
+
'audio',
|
|
9
|
+
'voice',
|
|
10
|
+
'record',
|
|
11
|
+
'file',
|
|
12
|
+
'face',
|
|
13
|
+
'reply',
|
|
14
|
+
'forward',
|
|
15
|
+
'link',
|
|
16
|
+
'dice',
|
|
17
|
+
'rps',
|
|
18
|
+
'markdown',
|
|
19
|
+
'html',
|
|
20
|
+
'qrcode',
|
|
21
|
+
'tts',
|
|
22
|
+
'keyboard',
|
|
23
|
+
]);
|
|
24
|
+
const AI_ONLY_TYPES = new Set(['thinking', 'tool_call']);
|
|
25
|
+
/**
|
|
26
|
+
* 过滤 agent / AI 出站段,仅保留可经 IM 投递的 canonical 段。
|
|
27
|
+
*/
|
|
28
|
+
export function segmentsForImDelivery(segments) {
|
|
29
|
+
const out = [];
|
|
30
|
+
for (const item of segments) {
|
|
31
|
+
if (!isCanonicalSegment(item))
|
|
32
|
+
continue;
|
|
33
|
+
if (AI_ONLY_TYPES.has(item.type))
|
|
34
|
+
continue;
|
|
35
|
+
if (!IM_VISIBLE_TYPES.has(item.type))
|
|
36
|
+
continue;
|
|
37
|
+
out.push(item);
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { Segment, SegmentBase, MediaRef, TextSegment, MentionSegment, ImageSegment, AudioSegment, VideoSegment, FileSegment, ReplySegment, ForwardSegment, FaceSegment, DiceSegment, RpsSegment, } from './types.js';
|
|
2
|
+
export { mediaRefSchema, textSegmentSchema, mentionSegmentSchema, imageSegmentSchema, audioSegmentSchema, videoSegmentSchema, fileSegmentSchema, replySegmentSchema, forwardSegmentSchema, faceSegmentSchema, diceSegmentSchema, rpsSegmentSchema, canonicalSegmentSchema, segmentArraySchema, } from './validate.js';
|
|
3
|
+
export { assertCanonicalSegments, isCanonicalSegment } from './assert.js';
|
|
4
|
+
export { mediaRefJsonSchema, outboundSegmentJsonSchema, aiOutboundJsonSchema, STRICT_OUTBOUND_SEGMENT_TYPES, } from './json-schema.js';
|
|
5
|
+
export { segmentsForImDelivery } from './delivery.js';
|
|
6
|
+
export { isMediaRef, collectSegmentMedia, type SegmentMediaRef, } from './media.js';
|
|
7
|
+
export { createImageSegment } from './image.js';
|
|
8
|
+
export { formatSegmentPreview } from './preview.js';
|
|
9
|
+
export { segmentsToPlainText } from './text.js';
|
|
10
|
+
export { readMentionTarget, readMentionName, readMentionSegmentTarget } from './mention.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { mediaRefSchema, textSegmentSchema, mentionSegmentSchema, imageSegmentSchema, audioSegmentSchema, videoSegmentSchema, fileSegmentSchema, replySegmentSchema, forwardSegmentSchema, faceSegmentSchema, diceSegmentSchema, rpsSegmentSchema, canonicalSegmentSchema, segmentArraySchema, } from './validate.js';
|
|
2
|
+
export { assertCanonicalSegments, isCanonicalSegment } from './assert.js';
|
|
3
|
+
export { mediaRefJsonSchema, outboundSegmentJsonSchema, aiOutboundJsonSchema, STRICT_OUTBOUND_SEGMENT_TYPES, } from './json-schema.js';
|
|
4
|
+
export { segmentsForImDelivery } from './delivery.js';
|
|
5
|
+
export { isMediaRef, collectSegmentMedia, } from './media.js';
|
|
6
|
+
export { createImageSegment } from './image.js';
|
|
7
|
+
export { formatSegmentPreview } from './preview.js';
|
|
8
|
+
export { segmentsToPlainText } from './text.js';
|
|
9
|
+
export { readMentionTarget, readMentionName, readMentionSegmentTarget } from './mention.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical outbound segment 的 JSON Schema SSOT —— 供 AI structured output
|
|
3
|
+
* (AI SDK `Output.object({ schema })`)约束模型直接输出 zhin 消息段数组。
|
|
4
|
+
*
|
|
5
|
+
* 与 validate.ts(@zhin.js/schema 运行时校验)表达同一组约束的 JSON Schema 形态;
|
|
6
|
+
* 严格段类型集合必须与 assert.ts 的 STRICT_CANONICAL_TYPES 保持一致
|
|
7
|
+
* (tests/segment-contract/json-schema.test.ts 有交叉防漂移测试)。
|
|
8
|
+
*
|
|
9
|
+
* 注意:解析侧 parseOutboundSegment 对严格段要求 canonical 形态
|
|
10
|
+
* (如 image 必须携带 data.media: MediaRef),本 schema 与之对齐。
|
|
11
|
+
*/
|
|
12
|
+
type JsonSchemaObject = Record<string, unknown>;
|
|
13
|
+
/** MediaRef(canonical 媒体引用):types.ts 的 MediaRef 接口 */
|
|
14
|
+
export declare const mediaRefJsonSchema: JsonSchemaObject;
|
|
15
|
+
/** 严格段类型集合(SSOT:assert.ts STRICT_CANONICAL_TYPES) */
|
|
16
|
+
export declare const STRICT_OUTBOUND_SEGMENT_TYPES: readonly ["text", "mention", "image", "reply", "forward", "face", "dice", "rps"];
|
|
17
|
+
/**
|
|
18
|
+
* 单条 outbound 消息段的 JSON Schema。
|
|
19
|
+
* 严格段镜像 validate.ts 的 data 约束;宽松段走 generic 分支。
|
|
20
|
+
*/
|
|
21
|
+
export declare const outboundSegmentJsonSchema: JsonSchemaObject;
|
|
22
|
+
/**
|
|
23
|
+
* AI 结构化出站根对象(ADR 0025 JSON DSL 的 schema 形态)。
|
|
24
|
+
* 与 parseAiOutboundJson / ZhinAiOutboundPayload 对齐:text、mentions、segments
|
|
25
|
+
* 均为可选(provider strict 模式兼容性考虑),"至少一项"由 prompt 与下游校验兜底。
|
|
26
|
+
*/
|
|
27
|
+
export declare const aiOutboundJsonSchema: JsonSchemaObject;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical outbound segment 的 JSON Schema SSOT —— 供 AI structured output
|
|
3
|
+
* (AI SDK `Output.object({ schema })`)约束模型直接输出 zhin 消息段数组。
|
|
4
|
+
*
|
|
5
|
+
* 与 validate.ts(@zhin.js/schema 运行时校验)表达同一组约束的 JSON Schema 形态;
|
|
6
|
+
* 严格段类型集合必须与 assert.ts 的 STRICT_CANONICAL_TYPES 保持一致
|
|
7
|
+
* (tests/segment-contract/json-schema.test.ts 有交叉防漂移测试)。
|
|
8
|
+
*
|
|
9
|
+
* 注意:解析侧 parseOutboundSegment 对严格段要求 canonical 形态
|
|
10
|
+
* (如 image 必须携带 data.media: MediaRef),本 schema 与之对齐。
|
|
11
|
+
*/
|
|
12
|
+
const platformJsonSchema = {
|
|
13
|
+
type: 'object',
|
|
14
|
+
additionalProperties: true,
|
|
15
|
+
description: '平台专有字段(一般无需输出)',
|
|
16
|
+
};
|
|
17
|
+
/** MediaRef(canonical 媒体引用):types.ts 的 MediaRef 接口 */
|
|
18
|
+
export const mediaRefJsonSchema = {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
kind: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
enum: ['url', 'path', 'base64', 'file'],
|
|
24
|
+
description: 'url=http(s) 链接;path=本地文件路径;base64=内联 base64 数据;file=平台不透明文件引用(如 Telegram file_id)',
|
|
25
|
+
},
|
|
26
|
+
value: { type: 'string', description: '媒体内容:URL / 文件路径 / 纯 base64' },
|
|
27
|
+
mime_type: { type: 'string', description: '如 image/png、audio/mpeg' },
|
|
28
|
+
},
|
|
29
|
+
required: ['kind', 'value'],
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
};
|
|
32
|
+
function strictBranch(type, data) {
|
|
33
|
+
return {
|
|
34
|
+
type: 'object',
|
|
35
|
+
properties: {
|
|
36
|
+
type: { const: type },
|
|
37
|
+
data,
|
|
38
|
+
platform: platformJsonSchema,
|
|
39
|
+
},
|
|
40
|
+
required: ['type', 'data'],
|
|
41
|
+
additionalProperties: false,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function dataObject(properties, required) {
|
|
45
|
+
return { type: 'object', properties, required: [...required], additionalProperties: false };
|
|
46
|
+
}
|
|
47
|
+
/** 宽松分支:未纳入严格契约的段类型,仅约束顶层形状(与 isCanonicalSegment 宽松路径一致) */
|
|
48
|
+
const looseBranch = {
|
|
49
|
+
type: 'object',
|
|
50
|
+
properties: {
|
|
51
|
+
type: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
enum: ['video', 'audio', 'voice', 'record', 'file', 'link', 'markdown', 'html', 'keyboard', 'action'],
|
|
54
|
+
},
|
|
55
|
+
data: { type: 'object' },
|
|
56
|
+
platform: platformJsonSchema,
|
|
57
|
+
},
|
|
58
|
+
required: ['type', 'data'],
|
|
59
|
+
additionalProperties: false,
|
|
60
|
+
};
|
|
61
|
+
/** 严格段类型集合(SSOT:assert.ts STRICT_CANONICAL_TYPES) */
|
|
62
|
+
export const STRICT_OUTBOUND_SEGMENT_TYPES = [
|
|
63
|
+
'text', 'mention', 'image', 'reply', 'forward', 'face', 'dice', 'rps',
|
|
64
|
+
];
|
|
65
|
+
/**
|
|
66
|
+
* 单条 outbound 消息段的 JSON Schema。
|
|
67
|
+
* 严格段镜像 validate.ts 的 data 约束;宽松段走 generic 分支。
|
|
68
|
+
*/
|
|
69
|
+
export const outboundSegmentJsonSchema = {
|
|
70
|
+
description: 'zhin 消息段 {type, data, platform?}',
|
|
71
|
+
anyOf: [
|
|
72
|
+
strictBranch('text', dataObject({
|
|
73
|
+
text: { type: 'string', description: '文本内容' },
|
|
74
|
+
}, ['text'])),
|
|
75
|
+
strictBranch('mention', dataObject({
|
|
76
|
+
target: { type: 'string', description: '被 @ 用户的平台 id' },
|
|
77
|
+
name: { type: 'string' },
|
|
78
|
+
}, ['target'])),
|
|
79
|
+
strictBranch('image', dataObject({
|
|
80
|
+
media: mediaRefJsonSchema,
|
|
81
|
+
alt: { type: 'string' },
|
|
82
|
+
}, ['media'])),
|
|
83
|
+
strictBranch('reply', dataObject({
|
|
84
|
+
message_id: { type: 'string', description: '被引用消息的平台消息 id' },
|
|
85
|
+
}, ['message_id'])),
|
|
86
|
+
strictBranch('forward', dataObject({
|
|
87
|
+
forward_id: { type: 'string' },
|
|
88
|
+
title: { type: 'string' },
|
|
89
|
+
messages: { type: 'array', items: { type: 'array' } },
|
|
90
|
+
}, ['forward_id'])),
|
|
91
|
+
strictBranch('face', dataObject({
|
|
92
|
+
id: { anyOf: [{ type: 'string' }, { type: 'number' }], description: '平台表情 id' },
|
|
93
|
+
name: { type: 'string' },
|
|
94
|
+
}, ['id'])),
|
|
95
|
+
strictBranch('dice', dataObject({
|
|
96
|
+
result: { type: 'number' },
|
|
97
|
+
}, [])),
|
|
98
|
+
strictBranch('rps', dataObject({
|
|
99
|
+
result: { type: 'number' },
|
|
100
|
+
}, [])),
|
|
101
|
+
looseBranch,
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* AI 结构化出站根对象(ADR 0025 JSON DSL 的 schema 形态)。
|
|
106
|
+
* 与 parseAiOutboundJson / ZhinAiOutboundPayload 对齐:text、mentions、segments
|
|
107
|
+
* 均为可选(provider strict 模式兼容性考虑),"至少一项"由 prompt 与下游校验兜底。
|
|
108
|
+
*/
|
|
109
|
+
export const aiOutboundJsonSchema = {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
text: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: '纯文本回复正文;与 segments 至少输出一项。使用 mentions 时必填',
|
|
115
|
+
},
|
|
116
|
+
mentions: {
|
|
117
|
+
type: 'array',
|
|
118
|
+
items: { type: 'string' },
|
|
119
|
+
description: '要 @ 的会话成员引用(昵称或 id,由宿主解析为平台账号);需配合 text 使用',
|
|
120
|
+
},
|
|
121
|
+
segments: {
|
|
122
|
+
type: 'array',
|
|
123
|
+
items: outboundSegmentJsonSchema,
|
|
124
|
+
description: 'zhin 消息段数组,如 [{type:"image",data:{media:{kind:"url",value:"https://…"}}},{type:"text",data:{text:"…"}}]',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
additionalProperties: false,
|
|
128
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { MediaRef, Segment } from './types.js';
|
|
2
|
+
import { isMediaRef } from './validate.js';
|
|
3
|
+
export { isMediaRef };
|
|
4
|
+
export interface SegmentMediaRef {
|
|
5
|
+
readonly type: string;
|
|
6
|
+
readonly media: MediaRef;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 从入站 canonical 段收集媒体引用(image / audio / video / file)。
|
|
10
|
+
* 只认 canonical `data.media`;无媒体段时返回空数组(调用方无需特判 undefined)。
|
|
11
|
+
*/
|
|
12
|
+
export declare function collectSegmentMedia(segments: readonly Segment[] | undefined): SegmentMediaRef[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isMediaRef } from './validate.js';
|
|
2
|
+
export { isMediaRef };
|
|
3
|
+
/** 入站段携带媒体引用的段类型(纯文本视图无法承载的信息)。 */
|
|
4
|
+
const MEDIA_SEGMENT_TYPES = new Set(['image', 'audio', 'video', 'file']);
|
|
5
|
+
/**
|
|
6
|
+
* 从入站 canonical 段收集媒体引用(image / audio / video / file)。
|
|
7
|
+
* 只认 canonical `data.media`;无媒体段时返回空数组(调用方无需特判 undefined)。
|
|
8
|
+
*/
|
|
9
|
+
export function collectSegmentMedia(segments) {
|
|
10
|
+
if (!segments?.length)
|
|
11
|
+
return [];
|
|
12
|
+
const out = [];
|
|
13
|
+
for (const segment of segments) {
|
|
14
|
+
if (!segment || typeof segment.type !== 'string' || !MEDIA_SEGMENT_TYPES.has(segment.type)) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const media = segment.data?.media;
|
|
18
|
+
if (isMediaRef(media))
|
|
19
|
+
out.push({ type: segment.type, media });
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical mention field readers (SSOT).
|
|
3
|
+
*/
|
|
4
|
+
export declare function readMentionTarget(data: Record<string, unknown> | undefined): string;
|
|
5
|
+
export declare function readMentionName(data: Record<string, unknown> | undefined): string | undefined;
|
|
6
|
+
/** Resolve @ target from at / mention segment. */
|
|
7
|
+
export declare function readMentionSegmentTarget(seg: {
|
|
8
|
+
type: unknown;
|
|
9
|
+
data?: unknown;
|
|
10
|
+
}): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical mention field readers (SSOT).
|
|
3
|
+
*/
|
|
4
|
+
export function readMentionTarget(data) {
|
|
5
|
+
if (!data)
|
|
6
|
+
return '';
|
|
7
|
+
const raw = data.target ?? data.user_id ?? data.qq ?? data.id;
|
|
8
|
+
if (raw === 'all')
|
|
9
|
+
return 'all';
|
|
10
|
+
return raw != null ? String(raw) : '';
|
|
11
|
+
}
|
|
12
|
+
export function readMentionName(data) {
|
|
13
|
+
if (!data)
|
|
14
|
+
return undefined;
|
|
15
|
+
const name = data.name ?? data.nickname ?? data.username;
|
|
16
|
+
return typeof name === 'string' && name.trim() ? name.trim() : undefined;
|
|
17
|
+
}
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
/** Resolve @ target from at / mention segment. */
|
|
22
|
+
export function readMentionSegmentTarget(seg) {
|
|
23
|
+
if (seg.type !== 'at' && seg.type !== 'mention')
|
|
24
|
+
return '';
|
|
25
|
+
return readMentionTarget(isRecord(seg.data) ? seg.data : undefined);
|
|
26
|
+
}
|