@zhin.js/core 1.0.25 → 1.0.26
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/CHANGELOG.md +10 -0
- package/README.md +84 -342
- package/lib/adapter.d.ts +17 -0
- package/lib/adapter.d.ts.map +1 -1
- package/lib/adapter.js +84 -2
- package/lib/adapter.js.map +1 -1
- package/lib/ai/agent.d.ts +126 -0
- package/lib/ai/agent.d.ts.map +1 -0
- package/lib/ai/agent.js +645 -0
- package/lib/ai/agent.js.map +1 -0
- package/lib/ai/context-manager.d.ts +213 -0
- package/lib/ai/context-manager.d.ts.map +1 -0
- package/lib/ai/context-manager.js +313 -0
- package/lib/ai/context-manager.js.map +1 -0
- package/lib/ai/conversation-memory.d.ts +181 -0
- package/lib/ai/conversation-memory.d.ts.map +1 -0
- package/lib/ai/conversation-memory.js +581 -0
- package/lib/ai/conversation-memory.js.map +1 -0
- package/lib/ai/follow-up.d.ts +131 -0
- package/lib/ai/follow-up.d.ts.map +1 -0
- package/lib/ai/follow-up.js +265 -0
- package/lib/ai/follow-up.js.map +1 -0
- package/lib/ai/index.d.ts +29 -0
- package/lib/ai/index.d.ts.map +1 -0
- package/lib/ai/index.js +34 -0
- package/lib/ai/index.js.map +1 -0
- package/lib/ai/init.d.ts +30 -0
- package/lib/ai/init.d.ts.map +1 -0
- package/lib/ai/init.js +424 -0
- package/lib/ai/init.js.map +1 -0
- package/lib/ai/output.d.ts +93 -0
- package/lib/ai/output.d.ts.map +1 -0
- package/lib/ai/output.js +176 -0
- package/lib/ai/output.js.map +1 -0
- package/lib/ai/providers/anthropic.d.ts +23 -0
- package/lib/ai/providers/anthropic.d.ts.map +1 -0
- package/lib/ai/providers/anthropic.js +322 -0
- package/lib/ai/providers/anthropic.js.map +1 -0
- package/lib/ai/providers/base.d.ts +43 -0
- package/lib/ai/providers/base.d.ts.map +1 -0
- package/lib/ai/providers/base.js +135 -0
- package/lib/ai/providers/base.js.map +1 -0
- package/lib/ai/providers/index.d.ts +12 -0
- package/lib/ai/providers/index.d.ts.map +1 -0
- package/lib/ai/providers/index.js +9 -0
- package/lib/ai/providers/index.js.map +1 -0
- package/lib/ai/providers/ollama.d.ts +25 -0
- package/lib/ai/providers/ollama.d.ts.map +1 -0
- package/lib/ai/providers/ollama.js +243 -0
- package/lib/ai/providers/ollama.js.map +1 -0
- package/lib/ai/providers/openai.d.ts +46 -0
- package/lib/ai/providers/openai.d.ts.map +1 -0
- package/lib/ai/providers/openai.js +132 -0
- package/lib/ai/providers/openai.js.map +1 -0
- package/lib/ai/rate-limiter.d.ts +38 -0
- package/lib/ai/rate-limiter.d.ts.map +1 -0
- package/lib/ai/rate-limiter.js +86 -0
- package/lib/ai/rate-limiter.js.map +1 -0
- package/lib/ai/service.d.ts +81 -0
- package/lib/ai/service.d.ts.map +1 -0
- package/lib/ai/service.js +274 -0
- package/lib/ai/service.js.map +1 -0
- package/lib/ai/session.d.ts +186 -0
- package/lib/ai/session.d.ts.map +1 -0
- package/lib/ai/session.js +443 -0
- package/lib/ai/session.js.map +1 -0
- package/lib/ai/tone-detector.d.ts +19 -0
- package/lib/ai/tone-detector.d.ts.map +1 -0
- package/lib/ai/tone-detector.js +72 -0
- package/lib/ai/tone-detector.js.map +1 -0
- package/lib/ai/tools.d.ts +45 -0
- package/lib/ai/tools.d.ts.map +1 -0
- package/lib/ai/tools.js +206 -0
- package/lib/ai/tools.js.map +1 -0
- package/lib/ai/types.d.ts +264 -0
- package/lib/ai/types.d.ts.map +1 -0
- package/lib/ai/types.js +6 -0
- package/lib/ai/types.js.map +1 -0
- package/lib/ai/user-profile.d.ts +56 -0
- package/lib/ai/user-profile.d.ts.map +1 -0
- package/lib/ai/user-profile.js +130 -0
- package/lib/ai/user-profile.js.map +1 -0
- package/lib/ai/zhin-agent.d.ts +165 -0
- package/lib/ai/zhin-agent.d.ts.map +1 -0
- package/lib/ai/zhin-agent.js +707 -0
- package/lib/ai/zhin-agent.js.map +1 -0
- package/lib/built/ai-trigger.d.ts.map +1 -1
- package/lib/built/ai-trigger.js +7 -3
- package/lib/built/ai-trigger.js.map +1 -1
- package/lib/built/command.d.ts +33 -17
- package/lib/built/command.d.ts.map +1 -1
- package/lib/built/command.js +71 -44
- package/lib/built/command.js.map +1 -1
- package/lib/built/component.d.ts +42 -15
- package/lib/built/component.d.ts.map +1 -1
- package/lib/built/component.js +84 -52
- package/lib/built/component.js.map +1 -1
- package/lib/built/config.d.ts +54 -5
- package/lib/built/config.d.ts.map +1 -1
- package/lib/built/config.js +76 -10
- package/lib/built/config.js.map +1 -1
- package/lib/built/cron.d.ts +41 -18
- package/lib/built/cron.d.ts.map +1 -1
- package/lib/built/cron.js +106 -63
- package/lib/built/cron.js.map +1 -1
- package/lib/built/database.d.ts +55 -6
- package/lib/built/database.d.ts.map +1 -1
- package/lib/built/database.js +93 -22
- package/lib/built/database.js.map +1 -1
- package/lib/built/dispatcher.d.ts +118 -0
- package/lib/built/dispatcher.d.ts.map +1 -0
- package/lib/built/dispatcher.js +196 -0
- package/lib/built/dispatcher.js.map +1 -0
- package/lib/built/permission.d.ts +45 -5
- package/lib/built/permission.d.ts.map +1 -1
- package/lib/built/permission.js +56 -11
- package/lib/built/permission.js.map +1 -1
- package/lib/built/skill.d.ts +117 -0
- package/lib/built/skill.d.ts.map +1 -0
- package/lib/built/skill.js +191 -0
- package/lib/built/skill.js.map +1 -0
- package/lib/built/tool.d.ts +71 -164
- package/lib/built/tool.d.ts.map +1 -1
- package/lib/built/tool.js +212 -297
- package/lib/built/tool.js.map +1 -1
- package/lib/feature.d.ts +75 -0
- package/lib/feature.d.ts.map +1 -0
- package/lib/feature.js +69 -0
- package/lib/feature.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -1
- package/lib/plugin.d.ts +25 -17
- package/lib/plugin.d.ts.map +1 -1
- package/lib/plugin.js +180 -20
- package/lib/plugin.js.map +1 -1
- package/lib/types.d.ts +4 -9
- package/lib/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/adapter.ts +101 -2
- package/src/ai/agent.ts +772 -0
- package/src/ai/context-manager.ts +440 -0
- package/src/ai/conversation-memory.ts +774 -0
- package/src/ai/follow-up.ts +357 -0
- package/src/ai/index.ts +128 -0
- package/src/ai/init.ts +502 -0
- package/src/ai/output.ts +261 -0
- package/src/ai/providers/anthropic.ts +375 -0
- package/src/ai/providers/base.ts +173 -0
- package/src/ai/providers/index.ts +13 -0
- package/src/ai/providers/ollama.ts +292 -0
- package/src/ai/providers/openai.ts +167 -0
- package/src/ai/rate-limiter.ts +129 -0
- package/src/ai/service.ts +319 -0
- package/src/ai/session.ts +544 -0
- package/src/ai/tone-detector.ts +89 -0
- package/src/ai/tools.ts +218 -0
- package/src/ai/types.ts +296 -0
- package/src/ai/user-profile.ts +181 -0
- package/src/ai/zhin-agent.ts +845 -0
- package/src/built/ai-trigger.ts +6 -3
- package/src/built/command.ts +75 -69
- package/src/built/component.ts +94 -76
- package/src/built/config.ts +238 -128
- package/src/built/cron.ts +117 -101
- package/src/built/database.ts +128 -33
- package/src/built/dispatcher.ts +332 -0
- package/src/built/permission.ts +146 -54
- package/src/built/skill.ts +280 -0
- package/src/built/tool.ts +245 -366
- package/src/feature.ts +113 -0
- package/src/index.ts +7 -0
- package/src/plugin.ts +198 -33
- package/src/types.ts +6 -10
- package/tests/adapter.test.ts +153 -1
- package/tests/ai/agent.test.ts +614 -0
- package/tests/ai/ai-trigger.test.ts +368 -0
- package/tests/ai/context-manager.test.ts +413 -0
- package/tests/ai/conversation-memory.test.ts +128 -0
- package/tests/ai/follow-up.test.ts +175 -0
- package/tests/ai/integration.test.ts +584 -0
- package/tests/ai/output.test.ts +128 -0
- package/tests/ai/providers.integration.test.ts +227 -0
- package/tests/ai/rate-limiter.test.ts +108 -0
- package/tests/ai/session.test.ts +375 -0
- package/tests/ai/setup.ts +308 -0
- package/tests/ai/tone-detector.test.ts +80 -0
- package/tests/ai/tool.test.ts +800 -0
- package/tests/ai/tools-builtin.test.ts +346 -0
- package/tests/ai/user-profile.test.ts +73 -0
- package/tests/ai/zhin-agent.test.ts +177 -0
- package/tests/config.test.ts +46 -0
- package/tests/cron.test.ts +94 -5
- package/tests/dispatcher.test.ts +146 -0
- package/tests/feature.test.ts +145 -0
- package/tests/features-builtin.test.ts +191 -0
- package/tests/plugin.test.ts +88 -14
- package/tests/skill-feature.test.ts +179 -0
- package/tests/tool-feature.test.ts +254 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,396 +1,138 @@
|
|
|
1
1
|
# @zhin.js/core
|
|
2
2
|
|
|
3
|
-
Zhin
|
|
3
|
+
Zhin.js 核心框架包,提供插件系统、Feature 架构、AI 智能体、消息路由等全部核心能力。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 核心概念
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- 🔌 **插件化架构**: 完整的插件生命周期管理
|
|
9
|
-
- 🤖 **多平台适配**: 支持多种聊天平台适配器
|
|
10
|
-
- 🎯 **命令系统**: 基于 segment-matcher 的智能消息匹配
|
|
11
|
-
- 🧩 **组件系统**: 支持模板渲染、属性绑定、插槽的组件化开发
|
|
12
|
-
- ⚡ **中间件链**: 灵活的消息处理中间件机制
|
|
13
|
-
- 🔧 **TypeScript**: 完整的类型支持
|
|
7
|
+
### Plugin(插件)
|
|
14
8
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
### App 类
|
|
18
|
-
|
|
19
|
-
应用核心类,继承自 `HMR<Plugin>`:
|
|
20
|
-
|
|
21
|
-
```typescript
|
|
22
|
-
import { App } from '@zhin.js/core'
|
|
23
|
-
|
|
24
|
-
// 直接使用 App 类创建实例
|
|
25
|
-
const app = new App('./zhin.config.ts')
|
|
26
|
-
|
|
27
|
-
// 启动应用
|
|
28
|
-
await app.start()
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
或者使用主包的便捷方法:
|
|
9
|
+
插件是 Zhin.js 的基本组织单位。每个插件拥有独立的生命周期和上下文,通过 `usePlugin()` Hook 访问框架能力。
|
|
32
10
|
|
|
33
11
|
```typescript
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
// 创建应用实例
|
|
37
|
-
const app = await createApp({
|
|
38
|
-
plugin_dirs: ['./plugins'],
|
|
39
|
-
plugins: ['my-plugin'],
|
|
40
|
-
bots: [{
|
|
41
|
-
context: 'process',
|
|
42
|
-
name: 'my-bot'
|
|
43
|
-
}],
|
|
44
|
-
debug: true
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
// 启动应用
|
|
48
|
-
await app.start()
|
|
49
|
-
```
|
|
12
|
+
import { usePlugin, MessageCommand } from '@zhin.js/core'
|
|
50
13
|
|
|
51
|
-
|
|
52
|
-
- 插件生命周期管理
|
|
53
|
-
- 配置文件加载和管理
|
|
54
|
-
- 适配器和机器人实例管理
|
|
55
|
-
- 消息路由和分发
|
|
56
|
-
- 热更新监听
|
|
14
|
+
const { addCommand, addTool, addCron, onMounted, onDispose } = usePlugin()
|
|
57
15
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
插件基类,继承自 `Dependency<Plugin>`:
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
import { usePlugin, addMiddleware, addCommand, addComponent } from '@zhin.js/core'
|
|
16
|
+
onMounted(() => console.log('插件已挂载'))
|
|
17
|
+
onDispose(() => console.log('插件已卸载'))
|
|
64
18
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
console.log(`[${plugin.name}] 收到消息:`, message.raw)
|
|
70
|
-
await next()
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
// 添加命令
|
|
74
|
-
addCommand(new MessageCommand('hello')
|
|
75
|
-
.action(async (message) => {
|
|
76
|
-
return '你好!'
|
|
77
|
-
})
|
|
19
|
+
addCommand(
|
|
20
|
+
new MessageCommand('hello <name:string>')
|
|
21
|
+
.desc('打招呼')
|
|
22
|
+
.action((_, result) => `Hello, ${result.params.name}!`)
|
|
78
23
|
)
|
|
79
24
|
```
|
|
80
25
|
|
|
81
|
-
|
|
82
|
-
- 中间件链管理
|
|
83
|
-
- 命令注册和处理
|
|
84
|
-
- 组件管理
|
|
85
|
-
- 事件监听和分发
|
|
86
|
-
- 消息发送前处理 (beforeSend)
|
|
87
|
-
|
|
88
|
-
### Adapter 类
|
|
26
|
+
### Feature(特性抽象)
|
|
89
27
|
|
|
90
|
-
|
|
28
|
+
Feature 是 Zhin.js 的核心扩展机制。所有内置功能均继承自 `Feature` 抽象基类,提供统一的注册/注销、插件归属追踪和 JSON 序列化能力。
|
|
91
29
|
|
|
92
|
-
```typescript
|
|
93
|
-
import { Adapter, Bot, Plugin } from '@zhin.js/core'
|
|
94
|
-
|
|
95
|
-
class MyBot implements Bot {
|
|
96
|
-
constructor(public plugin: Plugin, public config: BotConfig) {}
|
|
97
|
-
|
|
98
|
-
async connect() {
|
|
99
|
-
// 连接逻辑
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async disconnect() {
|
|
103
|
-
// 断开连接逻辑
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async sendMessage(options: SendOptions) {
|
|
107
|
-
// 发送消息逻辑
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// 注册适配器
|
|
112
|
-
const adapter = new Adapter('my-platform', MyBot)
|
|
113
30
|
```
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
.action(async (message, result) => {
|
|
124
|
-
const content = result.params.content
|
|
125
|
-
return `你说了:${content}`
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
addCommand(command)
|
|
31
|
+
Feature (抽象基类)
|
|
32
|
+
├── CommandFeature — 消息命令 addCommand()
|
|
33
|
+
├── ToolFeature — AI 可调用工具 addTool()
|
|
34
|
+
├── SkillFeature — 技能聚合 declareSkill()
|
|
35
|
+
├── CronFeature — 定时任务 addCron()
|
|
36
|
+
├── DatabaseFeature — 数据模型 defineModel()
|
|
37
|
+
├── ComponentFeature — 消息组件 addComponent()
|
|
38
|
+
├── ConfigFeature — 插件配置 addConfig()
|
|
39
|
+
└── PermissionFeature — 权限管理
|
|
129
40
|
```
|
|
130
41
|
|
|
131
|
-
|
|
42
|
+
每个 Feature 都会在 `Plugin.prototype` 上注入对应的扩展方法(如 `addCommand`、`addTool`),插件通过 `usePlugin()` 获取这些方法。
|
|
43
|
+
|
|
44
|
+
### Adapter(适配器)
|
|
132
45
|
|
|
133
|
-
|
|
46
|
+
适配器将不同聊天平台接入 Zhin.js,统一消息收发接口。
|
|
134
47
|
|
|
135
48
|
```typescript
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
// 定义组件
|
|
139
|
-
const MyComponent = defineComponent({
|
|
140
|
-
name: 'my-comp',
|
|
141
|
-
props: {
|
|
142
|
-
title: String,
|
|
143
|
-
count: { type: Number, default: 0 }
|
|
144
|
-
},
|
|
145
|
-
data(this: { title: string, count: number }) {
|
|
146
|
-
return {
|
|
147
|
-
message: `${this.title}: ${this.count}`
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
render(props, context) {
|
|
151
|
-
return `<text>${context.message}</text>`
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
// 注册组件
|
|
156
|
-
addComponent(MyComponent)
|
|
157
|
-
|
|
158
|
-
// 在消息中使用
|
|
159
|
-
// <my-comp title="计数器" :count="5"/>
|
|
49
|
+
// 适配器通过 Adapter.register 静态注册
|
|
50
|
+
Adapter.register('my-platform', MyAdapter)
|
|
160
51
|
```
|
|
161
52
|
|
|
162
|
-
|
|
53
|
+
每个适配器可以通过 `addTool()` 注册平台工具,通过 `declareSkill()` 将工具聚合为 AI 可理解的技能。
|
|
163
54
|
|
|
164
|
-
###
|
|
165
|
-
```typescript
|
|
166
|
-
// 获取应用实例
|
|
167
|
-
const app = useApp()
|
|
55
|
+
### MessageDispatcher(消息路由)
|
|
168
56
|
|
|
169
|
-
|
|
170
|
-
const plugin = usePlugin()
|
|
57
|
+
三阶段消息处理管线:
|
|
171
58
|
|
|
172
|
-
// 获取插件日志器
|
|
173
|
-
const logger = useLogger()
|
|
174
59
|
```
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// 监听所有消息
|
|
179
|
-
onMessage(async (message) => {
|
|
180
|
-
console.log('收到消息:', message.raw)
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
// 监听群聊消息
|
|
184
|
-
onGroupMessage(async (message) => {
|
|
185
|
-
if (message.raw.includes('帮助')) {
|
|
186
|
-
await message.reply('这里是帮助信息')
|
|
187
|
-
}
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
// 监听私聊消息
|
|
191
|
-
onPrivateMessage(async (message) => {
|
|
192
|
-
await message.reply('私聊回复')
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
// 自定义事件监听
|
|
196
|
-
onEvent('custom.event', (data) => {
|
|
197
|
-
console.log('自定义事件:', data)
|
|
198
|
-
})
|
|
60
|
+
消息到达 → Guardrail(守卫) → Route(路由) → Handle(处理)
|
|
61
|
+
│ │ │
|
|
62
|
+
权限/频率检查 命令 or AI? 执行命令 / AI Agent
|
|
199
63
|
```
|
|
200
64
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
onMounted(async (plugin) => {
|
|
205
|
-
console.log('插件已挂载:', plugin.name)
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
// 插件销毁时
|
|
209
|
-
onDispose(() => {
|
|
210
|
-
console.log('插件正在销毁')
|
|
211
|
-
})
|
|
212
|
-
```
|
|
65
|
+
- **Guardrail** — 鉴权、速率限制、黑名单等前置检查
|
|
66
|
+
- **Route** — 判断消息是命令还是 AI 对话
|
|
67
|
+
- **Handle** — CommandFeature 处理命令,ZhinAgent 处理 AI 对话
|
|
213
68
|
|
|
214
|
-
###
|
|
215
|
-
```typescript
|
|
216
|
-
// 注册上下文
|
|
217
|
-
register({
|
|
218
|
-
name: 'database',
|
|
219
|
-
async mounted(plugin) {
|
|
220
|
-
const db = new Database()
|
|
221
|
-
await db.connect()
|
|
222
|
-
return db
|
|
223
|
-
},
|
|
224
|
-
async dispose(db) {
|
|
225
|
-
await db.disconnect()
|
|
226
|
-
}
|
|
227
|
-
})
|
|
228
|
-
|
|
229
|
-
// 使用上下文依赖
|
|
230
|
-
useContext('database', async (db) => {
|
|
231
|
-
const users = await db.getUsers()
|
|
232
|
-
console.log('用户列表:', users)
|
|
233
|
-
})
|
|
234
|
-
```
|
|
69
|
+
### AI 模块(ZhinAgent)
|
|
235
70
|
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
import { registerAdapter } from '@zhin.js/core'
|
|
71
|
+
内置 AI 智能体,支持 OpenAI / Ollama 等大模型。
|
|
239
72
|
|
|
240
|
-
registerAdapter(new Adapter('my-platform', MyBot))
|
|
241
73
|
```
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
// 可以修改消息内容
|
|
249
|
-
return options
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
// 发送消息
|
|
253
|
-
await sendMessage({
|
|
254
|
-
type: 'group',
|
|
255
|
-
id: '123456',
|
|
256
|
-
context: 'onebot11',
|
|
257
|
-
bot: 'my-bot',
|
|
258
|
-
content: '你好世界!'
|
|
259
|
-
})
|
|
74
|
+
用户消息 → 速率限制 → 工具过滤 → 会话记忆 → LLM 调用 → 输出
|
|
75
|
+
│
|
|
76
|
+
三条路径选择:
|
|
77
|
+
闲聊(0工具)→ 1次 LLM
|
|
78
|
+
快速(无参数工具)→ 预执行 + 1次 LLM
|
|
79
|
+
Agent(有参数工具)→ 多轮 tool-calling
|
|
260
80
|
```
|
|
261
81
|
|
|
262
|
-
|
|
82
|
+
核心子模块:
|
|
263
83
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
raw: string
|
|
275
|
-
reply(content: SendContent, quote?: boolean | string): Promise<void>
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
interface MessageSegment {
|
|
279
|
-
type: string
|
|
280
|
-
data: Record<string, any>
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
type SendContent = string | MessageSegment | (string | MessageSegment)[]
|
|
284
|
-
```
|
|
84
|
+
| 模块 | 说明 |
|
|
85
|
+
|------|------|
|
|
86
|
+
| `SessionManager` | 会话管理(内存/数据库) |
|
|
87
|
+
| `ContextManager` | 上下文构建与滑动窗口 |
|
|
88
|
+
| `ConversationMemory` | 话题感知、链式摘要 |
|
|
89
|
+
| `UserProfileStore` | 用户画像 |
|
|
90
|
+
| `RateLimiter` | 频率限制 |
|
|
91
|
+
| `FollowUpManager` | 定时提醒(持久化) |
|
|
92
|
+
| `ToneDetector` | 情绪分析 |
|
|
93
|
+
| `OutputParser` | 多模态输出解析 |
|
|
285
94
|
|
|
286
|
-
|
|
287
|
-
```typescript
|
|
288
|
-
interface AppConfig {
|
|
289
|
-
bots?: BotConfig[]
|
|
290
|
-
plugin_dirs?: string[]
|
|
291
|
-
plugins?: string[]
|
|
292
|
-
disable_dependencies?: string[]
|
|
293
|
-
debug?: boolean
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
interface BotConfig {
|
|
297
|
-
name: string
|
|
298
|
-
context: string
|
|
299
|
-
[key: string]: any
|
|
300
|
-
}
|
|
301
|
-
```
|
|
95
|
+
## 主要导出
|
|
302
96
|
|
|
303
|
-
### 机器人接口
|
|
304
97
|
```typescript
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
connected?: boolean
|
|
308
|
-
connect(): Promise<void>
|
|
309
|
-
disconnect(): Promise<void>
|
|
310
|
-
sendMessage(options: SendOptions): Promise<void>
|
|
311
|
-
}
|
|
312
|
-
```
|
|
98
|
+
// 插件系统
|
|
99
|
+
export { Plugin, usePlugin, getPlugin } from './plugin.js'
|
|
313
100
|
|
|
314
|
-
|
|
101
|
+
// Feature 体系
|
|
102
|
+
export { Feature } from './feature.js'
|
|
103
|
+
export { CommandFeature } from './built/command.js'
|
|
104
|
+
export { ToolFeature, ZhinTool } from './built/tool.js'
|
|
105
|
+
export { SkillFeature } from './built/skill.js'
|
|
106
|
+
export { CronFeature } from './built/cron.js'
|
|
107
|
+
export { DatabaseFeature } from './built/database.js'
|
|
108
|
+
export { ComponentFeature } from './built/component.js'
|
|
109
|
+
export { ConfigFeature } from './built/config.js'
|
|
110
|
+
export { PermissionFeature } from './built/permission.js'
|
|
315
111
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
message: Message,
|
|
319
|
-
next: () => Promise<void>
|
|
320
|
-
) => Promise<void> | void
|
|
321
|
-
|
|
322
|
-
// 添加身份验证中间件
|
|
323
|
-
addMiddleware(async (message, next) => {
|
|
324
|
-
if (isAdmin(message.sender.id)) {
|
|
325
|
-
await next()
|
|
326
|
-
} else {
|
|
327
|
-
await message.reply('权限不足')
|
|
328
|
-
}
|
|
329
|
-
})
|
|
330
|
-
|
|
331
|
-
// 添加日志中间件
|
|
332
|
-
addMiddleware(async (message, next) => {
|
|
333
|
-
const start = Date.now()
|
|
334
|
-
await next()
|
|
335
|
-
const duration = Date.now() - start
|
|
336
|
-
console.log(`处理消息耗时: ${duration}ms`)
|
|
337
|
-
})
|
|
338
|
-
```
|
|
112
|
+
// 消息路由
|
|
113
|
+
export { createMessageDispatcher } from './built/dispatcher.js'
|
|
339
114
|
|
|
340
|
-
|
|
115
|
+
// AI
|
|
116
|
+
export { ZhinAgent } from './ai/index.js'
|
|
341
117
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
- `zhin.config.ts` - TypeScript 配置
|
|
345
|
-
- `zhin.config.json` - JSON 配置
|
|
346
|
-
- `zhin.config.yaml` - YAML 配置
|
|
347
|
-
- `zhin.config.toml` - TOML 配置
|
|
118
|
+
// 适配器
|
|
119
|
+
export { Adapter } from './adapter.js'
|
|
348
120
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
export
|
|
354
|
-
database: {
|
|
355
|
-
dialect: 'sqlite',
|
|
356
|
-
filename: './data/bot.db'
|
|
357
|
-
},
|
|
358
|
-
plugin_dirs: ['./src/plugins', 'node_modules', 'node_modules/@zhin.js'],
|
|
359
|
-
plugins: ['http', 'console', 'adapter-process'],
|
|
360
|
-
bots: [
|
|
361
|
-
{
|
|
362
|
-
context: 'process',
|
|
363
|
-
name: 'console-bot'
|
|
364
|
-
}
|
|
365
|
-
],
|
|
366
|
-
log_level: 1,
|
|
367
|
-
debug: process.env.NODE_ENV === 'development'
|
|
368
|
-
})
|
|
121
|
+
// 工具
|
|
122
|
+
export { MessageCommand } from './command.js'
|
|
123
|
+
export { Message } from './message.js'
|
|
124
|
+
export { Cron } from './cron.js'
|
|
125
|
+
export { Schema } from '@zhin.js/schema'
|
|
369
126
|
```
|
|
370
127
|
|
|
371
|
-
##
|
|
128
|
+
## 安装
|
|
372
129
|
|
|
373
|
-
### 类型生成
|
|
374
130
|
```bash
|
|
375
|
-
|
|
376
|
-
npx zhin dev # 开发时自动生成
|
|
131
|
+
pnpm add @zhin.js/core
|
|
377
132
|
```
|
|
378
133
|
|
|
379
|
-
|
|
380
|
-
```bash
|
|
381
|
-
# 开发模式启动,支持热更新
|
|
382
|
-
npx zhin dev
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
## 依赖项
|
|
386
|
-
|
|
387
|
-
- `@zhin.js/hmr` - 热模块替换系统
|
|
388
|
-
- `segment-matcher` - 消息片段匹配器
|
|
389
|
-
- `yaml` - YAML 配置文件支持
|
|
390
|
-
- `toml` - TOML 配置文件支持
|
|
391
|
-
- `dotenv` - 环境变量支持
|
|
134
|
+
> 通常不需要直接安装此包。使用 `zhin.js` 主入口包即可自动引入。
|
|
392
135
|
|
|
393
136
|
## 许可证
|
|
394
137
|
|
|
395
138
|
MIT License
|
|
396
|
-
MIT License
|
package/lib/adapter.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ export declare abstract class Adapter<R extends Bot = Bot> extends EventEmitter<
|
|
|
18
18
|
bots: Map<string, R>;
|
|
19
19
|
/** 适配器提供的工具 */
|
|
20
20
|
tools: Map<string, Tool>;
|
|
21
|
+
/** Skill 注销函数(declareSkill 时设置) */
|
|
22
|
+
private _skillDispose?;
|
|
21
23
|
/**
|
|
22
24
|
* 构造函数
|
|
23
25
|
* @param name 适配器名称(如 'process'、'qq' 等)
|
|
@@ -52,6 +54,21 @@ export declare abstract class Adapter<R extends Bot = Bot> extends EventEmitter<
|
|
|
52
54
|
* @returns 工具定义或 undefined
|
|
53
55
|
*/
|
|
54
56
|
getTool(name: string): Tool | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* 声明适配器的 Skill(将 this.tools 聚合为一个 Skill 注册到 SkillFeature)
|
|
59
|
+
*
|
|
60
|
+
* @param metadata Skill 元数据
|
|
61
|
+
* - description: 平台级能力描述
|
|
62
|
+
* - keywords: 额外的触发关键词(可选,会自动从工具中聚合)
|
|
63
|
+
* - tags: 额外的分类标签(可选,会自动从工具中聚合)
|
|
64
|
+
* - conventions: 平台调用约定(可选,拼接到 description 末尾)
|
|
65
|
+
*/
|
|
66
|
+
declareSkill(metadata: {
|
|
67
|
+
description: string;
|
|
68
|
+
keywords?: string[];
|
|
69
|
+
tags?: string[];
|
|
70
|
+
conventions?: string;
|
|
71
|
+
}): void;
|
|
55
72
|
/**
|
|
56
73
|
* 提供默认的适配器工具(子类可覆盖)
|
|
57
74
|
* 包含发送消息、撤回消息等基础能力
|
package/lib/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAqB,WAAW,EAAE,IAAI,EAAe,MAAM,YAAY,CAAC;AAE/E,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
package/lib/adapter.js
CHANGED
|
@@ -15,6 +15,8 @@ export class Adapter extends EventEmitter {
|
|
|
15
15
|
bots = new Map();
|
|
16
16
|
/** 适配器提供的工具 */
|
|
17
17
|
tools = new Map();
|
|
18
|
+
/** Skill 注销函数(declareSkill 时设置) */
|
|
19
|
+
_skillDispose;
|
|
18
20
|
/**
|
|
19
21
|
* 构造函数
|
|
20
22
|
* @param name 适配器名称(如 'process'、'qq' 等)
|
|
@@ -34,9 +36,20 @@ export class Adapter extends EventEmitter {
|
|
|
34
36
|
});
|
|
35
37
|
this.on('message.receive', (message) => {
|
|
36
38
|
this.logger.info(`${message.$bot} recv ${message.$channel.type}(${message.$channel.id}):${segment.raw(message.$content)}`);
|
|
37
|
-
// 使用 root 插件的中间件,这样所有子插件注册的中间件都能被执行
|
|
38
39
|
const rootPlugin = this.plugin?.root || this.plugin;
|
|
39
|
-
|
|
40
|
+
// 优先使用 MessageDispatcher(新架构),回退到旧中间件链(兼容)
|
|
41
|
+
const dispatcher = rootPlugin?.inject('dispatcher');
|
|
42
|
+
if (dispatcher && typeof dispatcher.dispatch === 'function') {
|
|
43
|
+
void dispatcher.dispatch(message).catch((err) => {
|
|
44
|
+
this.logger.error('dispatcher.dispatch(message) failed', err);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// 旧中间件链回退
|
|
49
|
+
void Promise.resolve(rootPlugin?.middleware(message, async () => { })).catch((err) => {
|
|
50
|
+
this.logger.error('rootPlugin.middleware(message, next) failed', err);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
40
53
|
});
|
|
41
54
|
}
|
|
42
55
|
get logger() {
|
|
@@ -94,6 +107,9 @@ export class Adapter extends EventEmitter {
|
|
|
94
107
|
}
|
|
95
108
|
// 清理 bots Map
|
|
96
109
|
this.bots.clear();
|
|
110
|
+
// 清理 Skill
|
|
111
|
+
this._skillDispose?.();
|
|
112
|
+
this._skillDispose = undefined;
|
|
97
113
|
// 从 adapters 数组中移除
|
|
98
114
|
const idx = this.plugin.root.adapters.indexOf(this.name);
|
|
99
115
|
if (idx !== -1) {
|
|
@@ -123,8 +139,18 @@ export class Adapter extends EventEmitter {
|
|
|
123
139
|
tags: [...(tool.tags || []), 'adapter', this.name],
|
|
124
140
|
};
|
|
125
141
|
this.tools.set(tool.name, toolWithSource);
|
|
142
|
+
// 同步到全局 ToolFeature(如果可用),使适配器工具出现在插件 features 统计中
|
|
143
|
+
let globalDispose;
|
|
144
|
+
const toolFeature = this.plugin?.root?.inject('tool');
|
|
145
|
+
if (toolFeature && typeof toolFeature.addTool === 'function') {
|
|
146
|
+
const adapterPluginName = this.plugin?.name || `adapter:${this.name}`;
|
|
147
|
+
globalDispose = toolFeature.addTool(toolWithSource, adapterPluginName, false);
|
|
148
|
+
// 记录到宿主插件的 feature 贡献
|
|
149
|
+
this.plugin?.recordFeatureContribution('tool', tool.name);
|
|
150
|
+
}
|
|
126
151
|
return () => {
|
|
127
152
|
this.tools.delete(tool.name);
|
|
153
|
+
globalDispose?.();
|
|
128
154
|
};
|
|
129
155
|
}
|
|
130
156
|
/**
|
|
@@ -142,6 +168,62 @@ export class Adapter extends EventEmitter {
|
|
|
142
168
|
getTool(name) {
|
|
143
169
|
return this.tools.get(name);
|
|
144
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* 声明适配器的 Skill(将 this.tools 聚合为一个 Skill 注册到 SkillFeature)
|
|
173
|
+
*
|
|
174
|
+
* @param metadata Skill 元数据
|
|
175
|
+
* - description: 平台级能力描述
|
|
176
|
+
* - keywords: 额外的触发关键词(可选,会自动从工具中聚合)
|
|
177
|
+
* - tags: 额外的分类标签(可选,会自动从工具中聚合)
|
|
178
|
+
* - conventions: 平台调用约定(可选,拼接到 description 末尾)
|
|
179
|
+
*/
|
|
180
|
+
declareSkill(metadata) {
|
|
181
|
+
const skillFeature = this.plugin?.root?.inject('skill');
|
|
182
|
+
if (!skillFeature) {
|
|
183
|
+
this.logger.debug(`declareSkill: SkillFeature 不可用,跳过 Skill 注册`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// 收集适配器所有工具
|
|
187
|
+
const tools = this.getTools();
|
|
188
|
+
// 聚合关键词:metadata 声明 + 工具自带
|
|
189
|
+
const allKeywords = new Set(metadata.keywords || []);
|
|
190
|
+
for (const tool of tools) {
|
|
191
|
+
if (tool.keywords) {
|
|
192
|
+
for (const kw of tool.keywords) {
|
|
193
|
+
allKeywords.add(kw);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// 聚合标签:metadata 声明 + 工具自带
|
|
198
|
+
const allTags = new Set(metadata.tags || []);
|
|
199
|
+
for (const tool of tools) {
|
|
200
|
+
if (tool.tags) {
|
|
201
|
+
for (const tag of tool.tags) {
|
|
202
|
+
allTags.add(tag);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// 拼接描述:基础描述 + 调用约定
|
|
207
|
+
let description = metadata.description;
|
|
208
|
+
if (metadata.conventions) {
|
|
209
|
+
description += `\n\n调用约定:${metadata.conventions}`;
|
|
210
|
+
}
|
|
211
|
+
const pluginName = this.plugin?.name || `adapter:${this.name}`;
|
|
212
|
+
const skill = {
|
|
213
|
+
name: `adapter:${this.name}`,
|
|
214
|
+
description,
|
|
215
|
+
tools,
|
|
216
|
+
keywords: Array.from(allKeywords),
|
|
217
|
+
tags: Array.from(allTags),
|
|
218
|
+
pluginName,
|
|
219
|
+
};
|
|
220
|
+
// 清理旧的 Skill(如果有)
|
|
221
|
+
this._skillDispose?.();
|
|
222
|
+
// 注册到 SkillFeature
|
|
223
|
+
this._skillDispose = skillFeature.add(skill, pluginName);
|
|
224
|
+
this.plugin?.recordFeatureContribution('skill', `adapter:${this.name}`);
|
|
225
|
+
this.logger.debug(`declareSkill: 已注册 Skill "${skill.name}",包含 ${tools.length} 个工具`);
|
|
226
|
+
}
|
|
145
227
|
/**
|
|
146
228
|
* 提供默认的适配器工具(子类可覆盖)
|
|
147
229
|
* 包含发送消息、撤回消息等基础能力
|