@zhin.js/ai 1.0.0 → 1.0.2

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.
Files changed (94) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +131 -497
  3. package/lib/agent.d.ts +54 -6
  4. package/lib/agent.d.ts.map +1 -1
  5. package/lib/agent.js +468 -116
  6. package/lib/agent.js.map +1 -1
  7. package/lib/compaction.d.ts +132 -0
  8. package/lib/compaction.d.ts.map +1 -0
  9. package/lib/compaction.js +370 -0
  10. package/lib/compaction.js.map +1 -0
  11. package/lib/context-manager.d.ts.map +1 -1
  12. package/lib/context-manager.js +10 -3
  13. package/lib/context-manager.js.map +1 -1
  14. package/lib/conversation-memory.d.ts +192 -0
  15. package/lib/conversation-memory.d.ts.map +1 -0
  16. package/lib/conversation-memory.js +619 -0
  17. package/lib/conversation-memory.js.map +1 -0
  18. package/lib/index.d.ts +25 -163
  19. package/lib/index.d.ts.map +1 -1
  20. package/lib/index.js +24 -1122
  21. package/lib/index.js.map +1 -1
  22. package/lib/output.d.ts +93 -0
  23. package/lib/output.d.ts.map +1 -0
  24. package/lib/output.js +176 -0
  25. package/lib/output.js.map +1 -0
  26. package/lib/providers/anthropic.d.ts +7 -0
  27. package/lib/providers/anthropic.d.ts.map +1 -1
  28. package/lib/providers/anthropic.js +5 -0
  29. package/lib/providers/anthropic.js.map +1 -1
  30. package/lib/providers/ollama.d.ts +10 -0
  31. package/lib/providers/ollama.d.ts.map +1 -1
  32. package/lib/providers/ollama.js +19 -4
  33. package/lib/providers/ollama.js.map +1 -1
  34. package/lib/providers/openai.d.ts +7 -0
  35. package/lib/providers/openai.d.ts.map +1 -1
  36. package/lib/providers/openai.js +11 -0
  37. package/lib/providers/openai.js.map +1 -1
  38. package/lib/rate-limiter.d.ts +38 -0
  39. package/lib/rate-limiter.d.ts.map +1 -0
  40. package/lib/rate-limiter.js +86 -0
  41. package/lib/rate-limiter.js.map +1 -0
  42. package/lib/session.d.ts +7 -0
  43. package/lib/session.d.ts.map +1 -1
  44. package/lib/session.js +47 -18
  45. package/lib/session.js.map +1 -1
  46. package/lib/storage.d.ts +68 -0
  47. package/lib/storage.d.ts.map +1 -0
  48. package/lib/storage.js +105 -0
  49. package/lib/storage.js.map +1 -0
  50. package/lib/tone-detector.d.ts +19 -0
  51. package/lib/tone-detector.d.ts.map +1 -0
  52. package/lib/tone-detector.js +72 -0
  53. package/lib/tone-detector.js.map +1 -0
  54. package/lib/types.d.ts +84 -8
  55. package/lib/types.d.ts.map +1 -1
  56. package/package.json +13 -42
  57. package/src/agent.ts +518 -135
  58. package/src/compaction.ts +529 -0
  59. package/src/context-manager.ts +10 -9
  60. package/src/conversation-memory.ts +816 -0
  61. package/src/index.ts +121 -1406
  62. package/src/output.ts +261 -0
  63. package/src/providers/anthropic.ts +4 -0
  64. package/src/providers/ollama.ts +23 -4
  65. package/src/providers/openai.ts +8 -1
  66. package/src/rate-limiter.ts +129 -0
  67. package/src/session.ts +47 -18
  68. package/src/storage.ts +135 -0
  69. package/src/tone-detector.ts +89 -0
  70. package/src/types.ts +95 -6
  71. package/tests/agent.test.ts +123 -70
  72. package/tests/compaction.test.ts +310 -0
  73. package/tests/context-manager.test.ts +73 -47
  74. package/tests/conversation-memory.test.ts +128 -0
  75. package/tests/output.test.ts +128 -0
  76. package/tests/providers.test.ts +574 -0
  77. package/tests/rate-limiter.test.ts +108 -0
  78. package/tests/session.test.ts +139 -48
  79. package/tests/setup.ts +82 -240
  80. package/tests/storage.test.ts +224 -0
  81. package/tests/tone-detector.test.ts +80 -0
  82. package/tsconfig.json +4 -5
  83. package/vitest.setup.ts +1 -0
  84. package/TOOLS.md +0 -294
  85. package/lib/tools.d.ts +0 -45
  86. package/lib/tools.d.ts.map +0 -1
  87. package/lib/tools.js +0 -194
  88. package/lib/tools.js.map +0 -1
  89. package/src/tools.ts +0 -205
  90. package/tests/ai-trigger.test.ts +0 -369
  91. package/tests/integration.test.ts +0 -596
  92. package/tests/providers.integration.test.ts +0 -227
  93. package/tests/tool.test.ts +0 -800
  94. package/tests/tools-builtin.test.ts +0 -346
package/README.md CHANGED
@@ -1,564 +1,198 @@
1
1
  # @zhin.js/ai
2
2
 
3
- 🤖 Zhin.js AI 服务插件 - 多模型 LLM 集成与 Agent 能力
4
-
5
- ## ✨ 特性
6
-
7
- - 🔌 **多模型支持**:OpenAI、Claude、DeepSeek、Moonshot、智谱、Ollama
8
- - 🔄 **流式输出**:实时响应,提升用户体验
9
- - 🛠️ **工具调用**:Function Calling / Tool Use 支持
10
- - 🤖 **Agent 能力**:自动规划、工具调用、多轮推理
11
- - 💬 **会话管理**:上下文记忆、自动过期、持久化
12
- - 📝 **内置工具**:计算器、时间、HTTP 请求等
13
- - 💾 **数据库持久化**:自动使用 Zhin 数据库存储会话,支持更长记忆
14
- - 📊 **消息记录**:自动记录所有平台消息,构建智能上下文
15
- - 🧠 **智能总结**:自动总结历史对话,保持上下文简洁
16
- - 🎯 **AI 触发中间件**:支持 @机器人、前缀触发、私聊直接对话
17
- - 🔧 **统一工具服务**:Tool ↔ Command 双向转换,AI 可调用现有命令
18
- - 🎨 **富媒体支持**:AI 可输出图片、音频、视频、@用户等富媒体内容
19
- - 🔒 **权限控制**:基于平台、场景、用户权限的工具过滤
20
-
21
- ## 📦 安装
3
+ 框架无关的 AI 引擎,提供 LLM Provider 抽象、Agent 循环、会话管理、记忆与压缩等能力。
22
4
 
23
- ```bash
24
- pnpm add @zhin.js/ai
25
- ```
26
-
27
- ## 🚀 快速开始
28
-
29
- ### 1. 配置
30
-
31
- 在 `zhin.config.yml` 中添加配置:
32
-
33
- ```yaml
34
- ai:
35
- enabled: true
36
- defaultProvider: openai
37
- providers:
38
- openai:
39
- apiKey: sk-xxx
40
- # baseUrl: https://api.openai.com/v1 # 可选,自定义 API 地址
41
- anthropic:
42
- apiKey: sk-ant-xxx
43
- deepseek:
44
- apiKey: sk-xxx
45
- moonshot:
46
- apiKey: sk-xxx # 月之暗面 API Key
47
- zhipu:
48
- apiKey: sk-xxx # 智谱 AI API Key
49
- ollama:
50
- baseUrl: http://localhost:11434 # 本地 Ollama 服务
51
- sessions:
52
- maxHistory: 200 # 最大历史消息数(数据库模式默认200)
53
- expireMs: 604800000 # 会话过期时间(7天)
54
- useDatabase: true # 使用数据库持久化(默认开启)
55
- context:
56
- enabled: true # 启用消息记录和智能上下文
57
- maxRecentMessages: 100 # 读取最近消息数量
58
- summaryThreshold: 50 # 触发自动总结的消息数量
59
- keepAfterSummary: 10 # 总结后保留的最近消息数
60
- maxContextTokens: 4000 # 上下文最大 token 估算
61
- ```
62
-
63
- ### 2. 启用插件
64
-
65
- ```yaml
66
- plugins:
67
- - ai
68
- ```
5
+ 不依赖任何 IM/Bot 概念,可独立用于 Web 后端、CLI 工具、自动化脚本等任意 Node.js 应用。
69
6
 
70
- ## 📊 消息记录与智能上下文
7
+ ## 核心模块
71
8
 
72
- AI 插件会自动记录所有平台的聊天消息,并在对话时智能构建上下文。
9
+ ### Provider(LLM 提供者)
73
10
 
74
- ### 消息记录格式
11
+ 统一的 LLM 提供者接口,内置多种主流模型支持:
75
12
 
76
- 所有消息自动保存到 `chat_messages` 表:
77
-
78
- | 字段 | 类型 | 说明 |
79
- |------|------|------|
80
- | platform | text | 平台标识:icqq, kook, discord 等 |
81
- | scene_id | text | 场景ID:群号/频道ID/用户ID |
82
- | scene_type | text | 场景类型:group, private, channel |
83
- | scene_name | text | 场景名称 |
84
- | sender_id | text | 发送者ID |
85
- | sender_name | text | 发送者名称 |
86
- | message | text | 消息内容 |
87
- | time | integer | 时间戳(毫秒) |
88
-
89
- ### 智能上下文
90
-
91
- 当使用 `/chat` 命令时:
92
-
93
- 1. **自动读取历史**:读取当前场景最近 100 条消息
94
- 2. **包含历史总结**:如果有之前的总结,会作为背景信息
95
- 3. **理解多人对话**:AI 能区分不同用户的发言
96
- 4. **自动总结**:当消息过多时自动总结,保持上下文简洁
13
+ ```typescript
14
+ import { OpenAIProvider, OllamaProvider, AnthropicProvider } from '@zhin.js/ai'
97
15
 
98
- ### 配置选项
16
+ const provider = new OpenAIProvider({
17
+ apiKey: 'sk-...',
18
+ baseUrl: 'https://api.openai.com/v1',
19
+ model: 'gpt-4o',
20
+ contextWindow: 128000,
21
+ models: ['gpt-4o', 'gpt-4o-mini'],
22
+ capabilities: { vision: true, streaming: true, toolCalling: true },
23
+ })
99
24
 
100
- ```yaml
101
- ai:
102
- context:
103
- enabled: true # 启用消息记录(默认开启)
104
- maxRecentMessages: 100 # 读取最近消息数量
105
- summaryThreshold: 50 # 超过此数量触发自动总结
106
- keepAfterSummary: 10 # 总结后保留最近几条消息
107
- maxContextTokens: 4000 # 上下文最大 token(估算)
25
+ const response = await provider.chat({
26
+ model: 'gpt-4o',
27
+ messages: [{ role: 'user', content: '你好' }],
28
+ })
108
29
  ```
109
30
 
110
- ## 💾 会话持久化
111
-
112
- AI 插件默认使用 Zhin 的数据库服务进行会话持久化存储,提供以下优势:
113
-
114
- ### 优势
115
-
116
- - **更长的记忆能力**:数据库模式默认保存 200 条消息历史(内存模式 100 条)
117
- - **持久化存储**:机器人重启后会话不丢失
118
- - **更长的过期时间**:数据库模式默认 7 天过期(内存模式 24 小时)
119
- - **自动切换**:数据库就绪时自动从内存切换到数据库存储
120
-
121
- ### 配置选项
122
-
123
- ```yaml
124
- ai:
125
- sessions:
126
- # 最大历史消息数
127
- # 数据库模式默认 200,内存模式默认 100
128
- maxHistory: 200
129
-
130
- # 会话过期时间(毫秒)
131
- # 数据库模式默认 7 天,内存模式默认 24 小时
132
- expireMs: 604800000
133
-
134
- # 是否使用数据库持久化
135
- # 默认 true,设为 false 使用内存存储
136
- useDatabase: true
137
- ```
31
+ 内置 Provider:
138
32
 
139
- ### 数据库模型
140
-
141
- 会话数据存储在 `ai_sessions` 表中:
142
-
143
- | 字段 | 类型 | 说明 |
144
- |------|------|------|
145
- | `session_id` | text | 会话 ID(平台:用户ID 或 平台:频道ID:用户ID) |
146
- | `messages` | json | 消息历史 |
147
- | `config` | json | 会话配置 |
148
- | `created_at` | integer | 创建时间戳 |
149
- | `updated_at` | integer | 更新时间戳 |
150
-
151
- ## 🎯 AI 触发方式
152
-
153
- AI 插件提供独立的触发中间件,支持多种触发方式:
154
-
155
- ### 触发配置
156
-
157
- ```yaml
158
- ai:
159
- trigger:
160
- enabled: true
161
- prefixes: # 前缀触发
162
- - '#'
163
- - 'AI:'
164
- - 'ai:'
165
- respondToAt: true # @机器人触发
166
- respondToPrivate: true # 私聊直接对话
167
- ignorePrefixes: # 忽略的前缀(避免与命令冲突)
168
- - '/'
169
- - '!'
170
- timeout: 60000 # 超时时间
171
- # thinkingMessage: '🤔 思考中...' # 可选提示
172
- ```
33
+ | Provider | 说明 |
34
+ |----------|------|
35
+ | `OpenAIProvider` | OpenAI 及兼容 API |
36
+ | `DeepSeekProvider` | DeepSeek(继承 OpenAI) |
37
+ | `MoonshotProvider` | Moonshot / Kimi(继承 OpenAI) |
38
+ | `ZhipuProvider` | 智谱 GLM(继承 OpenAI) |
39
+ | `AnthropicProvider` | Anthropic Claude |
40
+ | `OllamaProvider` | Ollama 本地模型 |
173
41
 
174
- ### 使用示例
42
+ ### Agent(Agent 引擎)
175
43
 
176
- ```
177
- # 使用 # 前缀触发
178
- # 今天天气怎么样?
44
+ 无状态的多轮 tool-calling 循环引擎:
179
45
 
180
- # @机器人触发(群聊)
181
- @机器人 帮我计算 2+3*4
46
+ ```typescript
47
+ import { Agent, createAgent } from '@zhin.js/ai'
182
48
 
183
- # 私聊直接对话
184
- 北京今天适合出门吗?
185
- ```
49
+ const agent = createAgent(provider, logger, {
50
+ maxIterations: 5,
51
+ timeout: 60000,
52
+ })
186
53
 
187
- ## 💬 使用命令
54
+ const result = await agent.run({
55
+ messages: [
56
+ { role: 'system', content: '你是一个助手' },
57
+ { role: 'user', content: '今天天气怎么样?' },
58
+ ],
59
+ tools: [weatherTool],
60
+ })
61
+ ```
188
62
 
189
- 插件提供以下命令:
63
+ ### SessionManager(会话管理)
190
64
 
191
- | 命令 | 描述 | 示例 |
192
- |------|------|------|
193
- | `/ai.models` | 列出可用模型 | `/ai.models` |
194
- | `/ai.clear` | 清除对话历史 | `/ai.clear` |
195
- | `/ai.stats` | 查看场景消息统计 | `/ai.stats` |
196
- | `/ai.tools` | 列出所有可用工具 | `/ai.tools` |
197
- | `/ai.summary` | 生成对话总结 | `/ai.summary` |
198
- | `/ai.health` | 检查 AI 服务健康状态 | `/ai.health` |
65
+ 管理对话会话的创建、检索和过期:
199
66
 
200
- ### /chat 命令详解
67
+ ```typescript
68
+ import { createMemorySessionManager, createDatabaseSessionManager } from '@zhin.js/ai'
201
69
 
202
- `/chat` 命令会自动读取当前场景(群聊/私聊)的最近 100 条消息作为上下文:
70
+ // 内存模式
71
+ const sessionManager = createMemorySessionManager({
72
+ maxHistory: 50,
73
+ expireMs: 3600000,
74
+ })
203
75
 
76
+ // 数据库持久化模式
77
+ const dbSessionManager = createDatabaseSessionManager(databaseModel, {
78
+ maxHistory: 50,
79
+ expireMs: 3600000,
80
+ })
204
81
  ```
205
- # 基本对话(AI 能看到之前的群聊记录)
206
- /chat 刚才大家在讨论什么?
207
82
 
208
- # 开始新对话(清除上下文)
209
- /chat -n 你好,我们重新开始
83
+ ### ContextManager(上下文管理)
210
84
 
211
- # 手动总结历史(生成摘要)
212
- /chat -s
213
- ```
85
+ 管理消息记录和上下文摘要:
214
86
 
215
- ### 指定模型和提供商
87
+ ```typescript
88
+ import { createContextManager } from '@zhin.js/ai'
216
89
 
217
- ```
218
- /ask -m gpt-4o -p openai 解释相对论
219
- /ask -m claude-opus-4-20250514 -p anthropic 写一首诗
90
+ const contextManager = createContextManager(logger, {
91
+ enabled: true,
92
+ maxMessagesBeforeSummary: 100,
93
+ summaryRetentionDays: 30,
94
+ })
220
95
  ```
221
96
 
222
- ## 🔧 编程接口
97
+ ### ConversationMemory(对话记忆)
223
98
 
224
- ### 基础使用
99
+ 双层记忆系统:短期滑动窗口 + 长期链式摘要。
225
100
 
226
101
  ```typescript
227
- import { usePlugin } from 'zhin.js';
228
-
229
- const plugin = usePlugin();
230
-
231
- // 获取 AI 服务
232
- plugin.useContext('ai', async (ai) => {
233
- // 简单问答
234
- const answer = await ai.ask('什么是 TypeScript?');
235
- console.log(answer);
236
-
237
- // 指定模型
238
- const answer2 = await ai.ask('写一首诗', {
239
- provider: 'anthropic',
240
- model: 'claude-opus-4-20250514',
241
- temperature: 0.9,
242
- });
243
- });
244
- ```
102
+ import { ConversationMemory } from '@zhin.js/ai'
245
103
 
246
- ### 会话聊天
247
-
248
- ```typescript
249
- plugin.useContext('ai', async (ai) => {
250
- const sessionId = 'user-123';
251
-
252
- // 多轮对话
253
- await ai.chatWithSession(sessionId, '我叫小明');
254
- const response = await ai.chatWithSession(sessionId, '我叫什么?');
255
- // response: "你叫小明"
256
-
257
- // 流式响应
258
- const stream = await ai.chatWithSession(sessionId, '讲个故事', { stream: true });
259
- for await (const chunk of stream) {
260
- process.stdout.write(chunk);
261
- }
262
- });
104
+ const memory = new ConversationMemory(provider, logger, {
105
+ shortTermWindow: 5,
106
+ minTopicRounds: 3,
107
+ topicChangeThreshold: 0.5,
108
+ })
263
109
  ```
264
110
 
265
- ### 使用 Agent
266
-
267
- ```typescript
268
- plugin.useContext('ai', async (ai) => {
269
- // 使用内置工具
270
- const result = await ai.runAgent('计算 sin(45°) 的值');
271
- console.log(result.content);
272
- console.log('使用的工具:', result.toolCalls);
273
-
274
- // 自定义工具
275
- const agent = ai.createAgent({
276
- model: 'gpt-4o',
277
- tools: [{
278
- name: 'search_database',
279
- description: '搜索数据库',
280
- parameters: {
281
- type: 'object',
282
- properties: {
283
- query: { type: 'string', description: '搜索关键词' }
284
- },
285
- required: ['query']
286
- },
287
- async execute(args) {
288
- // 实现搜索逻辑
289
- return { results: ['结果1', '结果2'] };
290
- }
291
- }]
292
- });
293
-
294
- const result2 = await agent.run('搜索用户张三的信息');
295
- });
296
- ```
111
+ ### Compaction(上下文压缩)
297
112
 
298
- ### 流式 Agent
113
+ 管理上下文窗口,防止 token 超限:
299
114
 
300
115
  ```typescript
301
- plugin.useContext('ai', async (ai) => {
302
- const agent = ai.createAgent({ model: 'gpt-4o' });
303
-
304
- for await (const event of agent.runStream('查询当前时间并计算距离新年还有多少天')) {
305
- switch (event.type) {
306
- case 'content':
307
- process.stdout.write(event.data);
308
- break;
309
- case 'tool_call':
310
- console.log(`\n调用工具: ${event.data.name}`);
311
- break;
312
- case 'tool_result':
313
- console.log(`工具结果: ${event.data.result}`);
314
- break;
315
- case 'done':
316
- console.log('\n完成:', event.data.usage);
317
- break;
318
- }
319
- }
320
- });
321
- ```
116
+ import {
117
+ estimateTokens,
118
+ evaluateContextWindowGuard,
119
+ pruneHistoryForContext,
120
+ compactSession,
121
+ } from '@zhin.js/ai'
322
122
 
323
- ## 🛠️ 内置工具
324
-
325
- | 工具 | 描述 |
326
- |------|------|
327
- | `calculator` | 数学计算(支持三角函数、对数等) |
328
- | `get_time` | 获取当前时间 |
329
- | `get_weather` | 获取天气(模拟数据) |
330
- | `web_search` | 网页搜索(需要配置 API) |
331
- | `http_request` | HTTP 请求 |
332
- | `run_code` | 执行 JavaScript 代码 |
333
-
334
- ### 添加自定义工具
335
-
336
- ```typescript
337
- import { createCalculatorTool, createTimeTool } from '@zhin.js/ai';
338
-
339
- const myTool = {
340
- name: 'my_tool',
341
- description: '我的自定义工具',
342
- parameters: {
343
- type: 'object',
344
- properties: {
345
- input: { type: 'string' }
346
- }
347
- },
348
- async execute(args) {
349
- return `处理结果: ${args.input}`;
350
- }
351
- };
352
-
353
- const agent = ai.createAgent({
354
- tools: [myTool],
355
- useBuiltinTools: true, // 同时使用内置工具
356
- });
123
+ const guard = evaluateContextWindowGuard({
124
+ messages: history,
125
+ maxContextTokens: 128000,
126
+ maxHistoryShare: 0.5,
127
+ })
128
+ // guard.status: 'ok' | 'warning' | 'critical'
357
129
  ```
358
130
 
359
- ## 🔧 统一工具服务
360
-
361
- AI 插件提供统一的工具服务,支持 Tool ↔ Command 双向转换:
131
+ ### Output(输出解析)
362
132
 
363
- ### 使用 ZhinTool 类(推荐)
133
+ AI 文本回复解析为结构化元素:
364
134
 
365
135
  ```typescript
366
- import { usePlugin, ZhinTool } from 'zhin.js';
367
-
368
- const plugin = usePlugin();
369
-
370
- // 使用链式调用定义工具
371
- const weatherTool = new ZhinTool('weather')
372
- .desc('查询天气信息')
373
- .param('city', { type: 'string', description: '城市名称' }, true)
374
- .param('days', { type: 'number', description: '预报天数' })
375
- .platform('qq', 'telegram') // 限定平台
376
- .scope('group', 'private') // 限定场景
377
- .permission('user') // 权限级别
378
- // AI 调用时执行
379
- .execute(async (args, ctx) => {
380
- return `${args.city} 的天气是晴天`;
381
- })
382
- // 可选:生成命令(与 MessageCommand.action 一致)
383
- .action(async (message, result) => {
384
- return `天气查询: ${result.params.city}`;
385
- });
386
-
387
- plugin.addTool(weatherTool);
388
- ```
389
-
390
- ### 使用 defineTool 辅助函数
136
+ import { parseOutput, renderToPlainText } from '@zhin.js/ai'
391
137
 
392
- ```typescript
393
- import { usePlugin, defineTool } from 'zhin.js';
394
-
395
- const plugin = usePlugin();
396
-
397
- const calculatorTool = defineTool<{ expression: string }>({
398
- name: 'calculator',
399
- description: '计算数学表达式',
400
- parameters: {
401
- type: 'object',
402
- properties: {
403
- expression: {
404
- type: 'string',
405
- description: '数学表达式',
406
- },
407
- },
408
- required: ['expression'],
409
- },
410
- // 可选:命令配置
411
- command: {
412
- pattern: 'calc <expression:rest>',
413
- alias: ['计算'],
414
- usage: ['计算数学表达式'],
415
- },
416
- execute: async (args) => {
417
- // args.expression 有完整类型提示
418
- const result = eval(args.expression);
419
- return `结果: ${result}`;
420
- },
421
- });
422
-
423
- plugin.addTool(calculatorTool);
138
+ const elements = parseOutput(aiResponse)
139
+ const text = renderToPlainText(elements)
424
140
  ```
425
141
 
426
- ### 权限控制
142
+ 支持的元素类型:`TextElement`、`ImageElement`、`AudioElement`、`VideoElement`、`CardElement`、`FileElement`。
427
143
 
428
- 工具可以声明权限要求:
144
+ ### RateLimiter(速率限制)
429
145
 
430
146
  ```typescript
431
- const adminTool = new ZhinTool('admin_action')
432
- .desc('管理员操作')
433
- .permission('bot_admin') // 需要机器人管理员权限
434
- .scope('group') // 仅在群聊可用
435
- .execute(async (args) => {
436
- return '操作成功';
437
- });
438
- ```
147
+ import { RateLimiter } from '@zhin.js/ai'
439
148
 
440
- 权限级别(从低到高):
441
- - `user` - 普通用户
442
- - `group_admin` - 群管理员
443
- - `group_owner` - 群主
444
- - `bot_admin` - 机器人管理员
445
- - `owner` - Zhin 拥有者
149
+ const limiter = new RateLimiter({
150
+ maxRequests: 10,
151
+ windowMs: 60000,
152
+ })
446
153
 
447
- ## 🎨 富媒体输出
448
-
449
- AI 可以输出富媒体内容,使用 XML-like 标签格式:
450
-
451
- ```
452
- # AI 可以在回复中使用:
453
-
454
- <image url="https://example.com/cat.jpg"/> # 图片
455
- <video url="https://example.com/video.mp4"/> # 视频
456
- <audio url="https://example.com/song.mp3"/> # 音频
457
- <at user_id="123456"/> # @用户
458
- <face id="178"/> # 表情
459
-
460
- # 混合使用
461
- 今天天气不错!<image url="https://weather.com/sunny.jpg"/>
154
+ const result = limiter.check('user-123')
155
+ if (!result.allowed) {
156
+ console.log(`请等待 ${result.retryAfterMs}ms`)
157
+ }
462
158
  ```
463
159
 
464
- 系统会自动将这些标签解析为平台对应的消息元素
465
-
466
- ## 🔌 支持的模型
467
-
468
- ### OpenAI
469
- - gpt-4o, gpt-4o-mini
470
- - gpt-4-turbo, gpt-4
471
- - gpt-3.5-turbo
472
- - o1, o1-mini, o1-preview, o3-mini
160
+ ### Storage(存储抽象)
473
161
 
474
- ### Anthropic (Claude)
475
- - claude-opus-4-20250514
476
- - claude-sonnet-4-20250514
477
- - claude-3-7-sonnet-20250219
478
- - claude-3-5-sonnet-20241022
479
- - claude-3-5-haiku-20241022
480
-
481
- ### DeepSeek
482
- - deepseek-chat
483
- - deepseek-coder
484
- - deepseek-reasoner
485
-
486
- ### Moonshot (月之暗面)
487
- - moonshot-v1-8k
488
- - moonshot-v1-32k
489
- - moonshot-v1-128k
490
-
491
- ### 智谱 AI
492
- - glm-4-plus, glm-4
493
- - glm-4-air, glm-4-flash
494
- - glm-4v-plus
495
-
496
- ### Ollama (本地)
497
- - llama3.3, llama3.2, llama3.1
498
- - qwen2.5, qwen2.5-coder
499
- - deepseek-r1, deepseek-v3
500
- - mistral, mixtral
501
- - phi4, gemma2
502
-
503
- ## 📚 类型扩展
162
+ 统一存储后端,支持内存和数据库模式,可在运行时热切换:
504
163
 
505
164
  ```typescript
506
- declare module 'zhin.js' {
507
- namespace Plugin {
508
- interface Contexts {
509
- ai: import('@zhin.js/ai').AIService;
510
- }
511
- }
512
- }
513
- ```
514
-
515
- ## 🔗 与 MCP 集成
165
+ import { MemoryStorageBackend, createSwappableBackend } from '@zhin.js/ai'
516
166
 
517
- AI 服务可以与 MCP (Model Context Protocol) 无缝集成:
167
+ const backend = createSwappableBackend(new MemoryStorageBackend())
518
168
 
519
- ```typescript
520
- // MCP 工具可以调用 AI 服务
521
- server.registerTool('ai_chat', {
522
- description: '与 AI 对话',
523
- inputSchema: z.object({
524
- message: z.string(),
525
- }),
526
- }, async (args) => {
527
- const ai = plugin.inject('ai');
528
- const response = await ai.ask(args.message);
529
- return { content: [{ type: 'text', text: response }] };
530
- });
169
+ // 运行时切换到数据库
170
+ backend.swap(new DatabaseStorageBackend(model))
531
171
  ```
532
172
 
533
- ## ⚙️ 高级配置
173
+ ## 主要导出
534
174
 
535
- ### 使用代理
175
+ | 导出 | 说明 |
176
+ |------|------|
177
+ | `OpenAIProvider` / `AnthropicProvider` / `OllamaProvider` | LLM 提供者 |
178
+ | `Agent` / `createAgent` | Agent 引擎 |
179
+ | `SessionManager` | 会话管理 |
180
+ | `ContextManager` | 上下文管理 |
181
+ | `ConversationMemory` | 对话记忆 |
182
+ | `compactSession` / `pruneHistoryForContext` | 上下文压缩 |
183
+ | `parseOutput` / `renderToPlainText` | 输出解析 |
184
+ | `RateLimiter` | 速率限制 |
185
+ | `detectTone` | 情绪检测 |
186
+ | `MemoryStorageBackend` / `createSwappableBackend` | 存储抽象 |
187
+
188
+ ## 安装
536
189
 
537
- ```yaml
538
- ai:
539
- providers:
540
- openai:
541
- apiKey: sk-xxx
542
- baseUrl: https://your-proxy.com/v1
190
+ ```bash
191
+ pnpm add @zhin.js/ai
543
192
  ```
544
193
 
545
- ### 自定义 Provider
546
-
547
- ```typescript
548
- import { OpenAIProvider } from '@zhin.js/ai';
549
-
550
- // 创建自定义 provider
551
- const customProvider = new OpenAIProvider({
552
- apiKey: 'xxx',
553
- baseUrl: 'https://api.custom.com/v1',
554
- headers: {
555
- 'X-Custom-Header': 'value'
556
- }
557
- });
558
-
559
- ai.registerProvider(customProvider);
560
- ```
194
+ > 也可通过 `zhin.js` 或 `@zhin.js/agent` 间接引入。
561
195
 
562
- ## 📄 License
196
+ ## 许可证
563
197
 
564
- MIT
198
+ MIT License