@zhin.js/core 1.0.36 → 1.0.38
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 +18 -0
- package/README.md +57 -3
- package/lib/adapter.d.ts +11 -0
- package/lib/adapter.d.ts.map +1 -1
- package/lib/adapter.js +61 -0
- package/lib/adapter.js.map +1 -1
- package/lib/ai/index.d.ts +3 -39
- package/lib/ai/index.d.ts.map +1 -1
- package/lib/ai/index.js +2 -44
- package/lib/ai/index.js.map +1 -1
- package/lib/ai/types.d.ts +4 -3
- package/lib/ai/types.d.ts.map +1 -1
- package/lib/built/ai-trigger.js.map +1 -1
- package/lib/built/common-adapter-tools.d.ts +55 -0
- package/lib/built/common-adapter-tools.d.ts.map +1 -0
- package/lib/built/common-adapter-tools.js +158 -0
- package/lib/built/common-adapter-tools.js.map +1 -0
- package/lib/built/dispatcher.d.ts.map +1 -1
- package/lib/built/dispatcher.js +50 -46
- package/lib/built/dispatcher.js.map +1 -1
- package/lib/built/skill.d.ts.map +1 -1
- package/lib/built/skill.js +0 -1
- package/lib/built/skill.js.map +1 -1
- package/lib/built/tool.d.ts +3 -3
- package/lib/built/tool.d.ts.map +1 -1
- package/lib/built/tool.js.map +1 -1
- package/lib/feature.d.ts +16 -1
- package/lib/feature.d.ts.map +1 -1
- package/lib/feature.js +41 -2
- package/lib/feature.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/plugin.d.ts +38 -1
- package/lib/plugin.d.ts.map +1 -1
- package/lib/plugin.js +73 -22
- package/lib/plugin.js.map +1 -1
- package/lib/scheduler/scheduler.js +1 -1
- package/lib/scheduler/scheduler.js.map +1 -1
- package/lib/types.d.ts +43 -28
- package/lib/types.d.ts.map +1 -1
- package/lib/utils.d.ts +12 -3
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +64 -54
- package/lib/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/adapter.ts +85 -5
- package/src/ai/index.ts +8 -186
- package/src/ai/types.ts +5 -4
- package/src/built/ai-trigger.ts +2 -2
- package/src/built/common-adapter-tools.ts +207 -0
- package/src/built/dispatcher.ts +51 -52
- package/src/built/skill.ts +3 -4
- package/src/built/tool.ts +3 -3
- package/src/feature.ts +45 -2
- package/src/index.ts +2 -0
- package/src/plugin.ts +92 -31
- package/src/scheduler/scheduler.ts +1 -1
- package/src/types.ts +39 -28
- package/src/utils.ts +63 -52
- package/tests/ai/setup.ts +2 -2
- package/tests/utils.test.ts +1 -3
- package/lib/ai/agent.d.ts +0 -130
- package/lib/ai/agent.d.ts.map +0 -1
- package/lib/ai/agent.js +0 -684
- package/lib/ai/agent.js.map +0 -1
- package/lib/ai/bootstrap.d.ts +0 -91
- package/lib/ai/bootstrap.d.ts.map +0 -1
- package/lib/ai/bootstrap.js +0 -243
- package/lib/ai/bootstrap.js.map +0 -1
- package/lib/ai/builtin-tools.d.ts +0 -59
- package/lib/ai/builtin-tools.d.ts.map +0 -1
- package/lib/ai/builtin-tools.js +0 -777
- package/lib/ai/builtin-tools.js.map +0 -1
- package/lib/ai/compaction.d.ts +0 -132
- package/lib/ai/compaction.d.ts.map +0 -1
- package/lib/ai/compaction.js +0 -370
- package/lib/ai/compaction.js.map +0 -1
- package/lib/ai/context-manager.d.ts +0 -213
- package/lib/ai/context-manager.d.ts.map +0 -1
- package/lib/ai/context-manager.js +0 -313
- package/lib/ai/context-manager.js.map +0 -1
- package/lib/ai/conversation-memory.d.ts +0 -181
- package/lib/ai/conversation-memory.d.ts.map +0 -1
- package/lib/ai/conversation-memory.js +0 -581
- package/lib/ai/conversation-memory.js.map +0 -1
- package/lib/ai/cron-engine.d.ts +0 -92
- package/lib/ai/cron-engine.d.ts.map +0 -1
- package/lib/ai/cron-engine.js +0 -278
- package/lib/ai/cron-engine.js.map +0 -1
- package/lib/ai/follow-up.d.ts +0 -131
- package/lib/ai/follow-up.d.ts.map +0 -1
- package/lib/ai/follow-up.js +0 -265
- package/lib/ai/follow-up.js.map +0 -1
- package/lib/ai/hooks.d.ts +0 -143
- package/lib/ai/hooks.d.ts.map +0 -1
- package/lib/ai/hooks.js +0 -108
- package/lib/ai/hooks.js.map +0 -1
- package/lib/ai/init.d.ts +0 -30
- package/lib/ai/init.d.ts.map +0 -1
- package/lib/ai/init.js +0 -686
- package/lib/ai/init.js.map +0 -1
- package/lib/ai/output.d.ts +0 -93
- package/lib/ai/output.d.ts.map +0 -1
- package/lib/ai/output.js +0 -176
- package/lib/ai/output.js.map +0 -1
- package/lib/ai/rate-limiter.d.ts +0 -38
- package/lib/ai/rate-limiter.d.ts.map +0 -1
- package/lib/ai/rate-limiter.js +0 -86
- package/lib/ai/rate-limiter.js.map +0 -1
- package/lib/ai/service.d.ts +0 -88
- package/lib/ai/service.d.ts.map +0 -1
- package/lib/ai/service.js +0 -285
- package/lib/ai/service.js.map +0 -1
- package/lib/ai/session.d.ts +0 -186
- package/lib/ai/session.d.ts.map +0 -1
- package/lib/ai/session.js +0 -443
- package/lib/ai/session.js.map +0 -1
- package/lib/ai/subagent.d.ts +0 -50
- package/lib/ai/subagent.d.ts.map +0 -1
- package/lib/ai/subagent.js +0 -144
- package/lib/ai/subagent.js.map +0 -1
- package/lib/ai/tone-detector.d.ts +0 -19
- package/lib/ai/tone-detector.d.ts.map +0 -1
- package/lib/ai/tone-detector.js +0 -72
- package/lib/ai/tone-detector.js.map +0 -1
- package/lib/ai/tools.d.ts +0 -45
- package/lib/ai/tools.d.ts.map +0 -1
- package/lib/ai/tools.js +0 -206
- package/lib/ai/tools.js.map +0 -1
- package/lib/ai/user-profile.d.ts +0 -56
- package/lib/ai/user-profile.d.ts.map +0 -1
- package/lib/ai/user-profile.js +0 -130
- package/lib/ai/user-profile.js.map +0 -1
- package/lib/ai/zhin-agent/builtin-tools.d.ts +0 -17
- package/lib/ai/zhin-agent/builtin-tools.d.ts.map +0 -1
- package/lib/ai/zhin-agent/builtin-tools.js +0 -220
- package/lib/ai/zhin-agent/builtin-tools.js.map +0 -1
- package/lib/ai/zhin-agent/config.d.ts +0 -54
- package/lib/ai/zhin-agent/config.d.ts.map +0 -1
- package/lib/ai/zhin-agent/config.js +0 -76
- package/lib/ai/zhin-agent/config.js.map +0 -1
- package/lib/ai/zhin-agent/exec-policy.d.ts +0 -20
- package/lib/ai/zhin-agent/exec-policy.d.ts.map +0 -1
- package/lib/ai/zhin-agent/exec-policy.js +0 -71
- package/lib/ai/zhin-agent/exec-policy.js.map +0 -1
- package/lib/ai/zhin-agent/index.d.ts +0 -70
- package/lib/ai/zhin-agent/index.d.ts.map +0 -1
- package/lib/ai/zhin-agent/index.js +0 -404
- package/lib/ai/zhin-agent/index.js.map +0 -1
- package/lib/ai/zhin-agent/prompt.d.ts +0 -21
- package/lib/ai/zhin-agent/prompt.d.ts.map +0 -1
- package/lib/ai/zhin-agent/prompt.js +0 -111
- package/lib/ai/zhin-agent/prompt.js.map +0 -1
- package/lib/ai/zhin-agent/tool-collector.d.ts +0 -22
- package/lib/ai/zhin-agent/tool-collector.d.ts.map +0 -1
- package/lib/ai/zhin-agent/tool-collector.js +0 -218
- package/lib/ai/zhin-agent/tool-collector.js.map +0 -1
- package/src/ai/agent.ts +0 -812
- package/src/ai/bootstrap.ts +0 -309
- package/src/ai/builtin-tools.ts +0 -849
- package/src/ai/compaction.ts +0 -529
- package/src/ai/context-manager.ts +0 -440
- package/src/ai/conversation-memory.ts +0 -774
- package/src/ai/cron-engine.ts +0 -337
- package/src/ai/follow-up.ts +0 -357
- package/src/ai/hooks.ts +0 -223
- package/src/ai/init.ts +0 -762
- package/src/ai/output.ts +0 -261
- package/src/ai/rate-limiter.ts +0 -129
- package/src/ai/service.ts +0 -331
- package/src/ai/session.ts +0 -544
- package/src/ai/subagent.ts +0 -209
- package/src/ai/tone-detector.ts +0 -89
- package/src/ai/tools.ts +0 -218
- package/src/ai/user-profile.ts +0 -181
- package/src/ai/zhin-agent/builtin-tools.ts +0 -247
- package/src/ai/zhin-agent/config.ts +0 -113
- package/src/ai/zhin-agent/exec-policy.ts +0 -78
- package/src/ai/zhin-agent/index.ts +0 -512
- package/src/ai/zhin-agent/prompt.ts +0 -131
- package/src/ai/zhin-agent/tool-collector.ts +0 -243
- package/tests/ai/agent.test.ts +0 -614
- package/tests/ai/context-manager.test.ts +0 -413
- package/tests/ai/conversation-memory.test.ts +0 -128
- package/tests/ai/follow-up.test.ts +0 -175
- package/tests/ai/integration.test.ts +0 -584
- package/tests/ai/output.test.ts +0 -128
- package/tests/ai/rate-limiter.test.ts +0 -108
- package/tests/ai/session.test.ts +0 -375
- package/tests/ai/subagent.test.ts +0 -270
- package/tests/ai/tone-detector.test.ts +0 -80
- package/tests/ai/tools-builtin.test.ts +0 -346
- package/tests/ai/user-profile.test.ts +0 -73
- package/tests/ai/zhin-agent.test.ts +0 -177
package/src/adapter.ts
CHANGED
|
@@ -2,15 +2,29 @@ import { Bot } from "./bot.js";
|
|
|
2
2
|
import { Plugin } from "./plugin.js";
|
|
3
3
|
import { EventEmitter } from "events";
|
|
4
4
|
import { Message } from "./message.js";
|
|
5
|
-
import { BeforeSendHandler, SendOptions, Tool, ToolContext } from "./types.js";
|
|
5
|
+
import { BeforeSendHandler, SendOptions, Tool, ToolContext, ToolScope } from "./types.js";
|
|
6
6
|
import { segment } from "./utils.js";
|
|
7
7
|
import { ZhinTool, isZhinTool, type ToolInput } from "./built/tool.js";
|
|
8
8
|
import type { Skill, SkillFeature } from "./built/skill.js";
|
|
9
|
+
import {
|
|
10
|
+
type IGroupManagement,
|
|
11
|
+
GROUP_METHOD_SPECS,
|
|
12
|
+
GROUP_MANAGEMENT_SKILL_DESCRIPTION,
|
|
13
|
+
GROUP_MANAGEMENT_SKILL_TAGS,
|
|
14
|
+
GROUP_MANAGEMENT_SKILL_KEYWORDS,
|
|
15
|
+
buildMethodArgs,
|
|
16
|
+
} from "./built/common-adapter-tools.js";
|
|
9
17
|
/**
|
|
10
18
|
* Adapter类:适配器抽象,管理多平台Bot实例。
|
|
11
19
|
* 负责根据配置启动/关闭各平台机器人,统一异常处理。
|
|
12
|
-
*
|
|
20
|
+
*
|
|
13
21
|
* 适配器可以提供 AI 工具,供 AI 服务调用。
|
|
22
|
+
*
|
|
23
|
+
* 群管理能力:
|
|
24
|
+
* Adapter 基类声明了 IGroupManagement 中的可选方法规范,
|
|
25
|
+
* 具体适配器(ICQQ/Discord/Telegram 等)选择性覆写。
|
|
26
|
+
* 调用 registerGroupManagementSkill() 后,基类自动检测
|
|
27
|
+
* 哪些方法已被实现,生成对应的 Tool 并注册为 "群聊管理" Skill。
|
|
14
28
|
*/
|
|
15
29
|
export abstract class Adapter<R extends Bot = Bot> extends EventEmitter<Adapter.Lifecycle> {
|
|
16
30
|
/** 当前适配器下所有Bot实例,key为bot名称 */
|
|
@@ -40,7 +54,7 @@ export abstract class Adapter<R extends Bot = Bot> extends EventEmitter<Adapter.
|
|
|
40
54
|
this.logger.info(`${message.$bot} recv ${message.$channel.type}(${message.$channel.id}):${segment.raw(message.$content)}`);
|
|
41
55
|
const rootPlugin = this.plugin?.root || this.plugin;
|
|
42
56
|
// 优先使用 MessageDispatcher(新架构),回退到旧中间件链(兼容)
|
|
43
|
-
const dispatcher = rootPlugin?.inject('dispatcher' as
|
|
57
|
+
const dispatcher = rootPlugin?.inject('dispatcher') as { dispatch?: (msg: Message) => Promise<void> } | undefined;
|
|
44
58
|
if (dispatcher && typeof dispatcher.dispatch === 'function') {
|
|
45
59
|
void dispatcher.dispatch(message).catch((err: unknown) => {
|
|
46
60
|
this.logger.error('dispatcher.dispatch(message) failed', err);
|
|
@@ -87,6 +101,8 @@ export abstract class Adapter<R extends Bot = Bot> extends EventEmitter<Adapter.
|
|
|
87
101
|
this.bots.set(bot.$id, bot);
|
|
88
102
|
}
|
|
89
103
|
this.logger.debug(`adapter ${this.name} started`);
|
|
104
|
+
|
|
105
|
+
this._autoDetectGroupManagement();
|
|
90
106
|
}
|
|
91
107
|
/**
|
|
92
108
|
* 停止适配器,断开并移除所有Bot实例
|
|
@@ -145,7 +161,7 @@ export abstract class Adapter<R extends Bot = Bot> extends EventEmitter<Adapter.
|
|
|
145
161
|
|
|
146
162
|
// 同步到全局 ToolFeature(如果可用),使适配器工具出现在插件 features 统计中
|
|
147
163
|
let globalDispose: (() => void) | undefined;
|
|
148
|
-
const toolFeature = this.plugin?.root?.inject('tool' as
|
|
164
|
+
const toolFeature = this.plugin?.root?.inject('tool') as { addTool?: (tool: Tool, name: string, gen: boolean) => () => void } | undefined;
|
|
149
165
|
if (toolFeature && typeof toolFeature.addTool === 'function') {
|
|
150
166
|
const adapterPluginName = this.plugin?.name || `adapter:${this.name}`;
|
|
151
167
|
globalDispose = toolFeature.addTool(toolWithSource, adapterPluginName, false);
|
|
@@ -191,7 +207,7 @@ export abstract class Adapter<R extends Bot = Bot> extends EventEmitter<Adapter.
|
|
|
191
207
|
tags?: string[];
|
|
192
208
|
conventions?: string;
|
|
193
209
|
}): void {
|
|
194
|
-
const skillFeature = this.plugin?.root?.inject('skill'
|
|
210
|
+
const skillFeature = this.plugin?.root?.inject('skill') as SkillFeature | undefined;
|
|
195
211
|
if (!skillFeature) {
|
|
196
212
|
this.logger.debug(`declareSkill: SkillFeature 不可用,跳过 Skill 注册`);
|
|
197
213
|
return;
|
|
@@ -305,6 +321,70 @@ export abstract class Adapter<R extends Bot = Bot> extends EventEmitter<Adapter.
|
|
|
305
321
|
},
|
|
306
322
|
});
|
|
307
323
|
}
|
|
324
|
+
|
|
325
|
+
// ==========================================================================
|
|
326
|
+
// 群管理自动检测 — start() 结束时自动执行
|
|
327
|
+
// ==========================================================================
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* 遍历 GROUP_METHOD_SPECS,检测子类是否覆写了对应方法。
|
|
331
|
+
* 对每个已实现的方法生成 Tool 并注册,最后聚合为 "群聊管理" Skill。
|
|
332
|
+
*/
|
|
333
|
+
private _autoDetectGroupManagement(): void {
|
|
334
|
+
const self = this as unknown as IGroupManagement;
|
|
335
|
+
const prefix = this.name as string;
|
|
336
|
+
const generatedTools: Tool[] = [];
|
|
337
|
+
|
|
338
|
+
for (const spec of GROUP_METHOD_SPECS) {
|
|
339
|
+
const fn = self[spec.method];
|
|
340
|
+
if (typeof fn !== 'function') continue;
|
|
341
|
+
|
|
342
|
+
const boundFn: (...args: any[]) => Promise<any> = fn.bind(self);
|
|
343
|
+
|
|
344
|
+
const properties: Record<string, any> = {
|
|
345
|
+
bot_id: { type: 'string', description: 'Bot ID', contextKey: 'botId' },
|
|
346
|
+
scene_id: { type: 'string', description: '群/服务器 ID', contextKey: 'sceneId' },
|
|
347
|
+
};
|
|
348
|
+
const required: string[] = ['bot_id', 'scene_id'];
|
|
349
|
+
|
|
350
|
+
for (const [name, schema] of Object.entries(spec.extraParams)) {
|
|
351
|
+
properties[name] = schema;
|
|
352
|
+
}
|
|
353
|
+
if (spec.extraRequired) {
|
|
354
|
+
required.push(...spec.extraRequired);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const tool: Tool = {
|
|
358
|
+
name: `${prefix}_${spec.toolSuffix}`,
|
|
359
|
+
description: `${spec.description} (${prefix})`,
|
|
360
|
+
parameters: { type: 'object' as const, properties, required },
|
|
361
|
+
execute: async (args: Record<string, any>) => {
|
|
362
|
+
const { bot_id, scene_id, ...rest } = args;
|
|
363
|
+
return boundFn(...buildMethodArgs(spec.method, bot_id, scene_id, rest));
|
|
364
|
+
},
|
|
365
|
+
tags: ['group', 'management', prefix],
|
|
366
|
+
keywords: spec.keywords,
|
|
367
|
+
permissionLevel: spec.permissionLevel,
|
|
368
|
+
scopes: ['group', 'channel'] as ToolScope[],
|
|
369
|
+
preExecutable: spec.preExecutable,
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
this.addTool(tool);
|
|
373
|
+
generatedTools.push(tool);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (generatedTools.length === 0) return;
|
|
377
|
+
|
|
378
|
+
this.declareSkill({
|
|
379
|
+
description: GROUP_MANAGEMENT_SKILL_DESCRIPTION,
|
|
380
|
+
keywords: GROUP_MANAGEMENT_SKILL_KEYWORDS,
|
|
381
|
+
tags: GROUP_MANAGEMENT_SKILL_TAGS,
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
this.logger.debug(
|
|
385
|
+
`自动检测到 ${generatedTools.length} 个群管理方法 → 已注册 Skill`,
|
|
386
|
+
);
|
|
387
|
+
}
|
|
308
388
|
}
|
|
309
389
|
export interface Adapters {}
|
|
310
390
|
export namespace Adapter {
|
package/src/ai/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @zhin.js/core — AI
|
|
2
|
+
* @zhin.js/core — AI 模块(仅基础类型与 Provider)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Agent 循环、会话、ZhinAgent 等已迁至 @zhin.js/agent。
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
// ── 类型定义 ──
|
|
@@ -21,131 +21,14 @@ export type {
|
|
|
21
21
|
AgentTool,
|
|
22
22
|
AgentConfig,
|
|
23
23
|
AgentResult,
|
|
24
|
+
Usage,
|
|
25
|
+
ToolFilterOptions,
|
|
26
|
+
SessionConfig,
|
|
27
|
+
Session,
|
|
28
|
+
ToolDefinition as ChatToolDefinition,
|
|
29
|
+
JsonSchema,
|
|
24
30
|
} from './types.js';
|
|
25
31
|
|
|
26
|
-
// ── AI Service ──
|
|
27
|
-
export { AIService } from './service.js';
|
|
28
|
-
|
|
29
|
-
// ── Agent ──
|
|
30
|
-
export { Agent, createAgent, formatToolTitle } from './agent.js';
|
|
31
|
-
|
|
32
|
-
// ── Session ──
|
|
33
|
-
export {
|
|
34
|
-
SessionManager,
|
|
35
|
-
createMemorySessionManager,
|
|
36
|
-
createDatabaseSessionManager,
|
|
37
|
-
AI_SESSION_MODEL,
|
|
38
|
-
} from './session.js';
|
|
39
|
-
|
|
40
|
-
// ── Context Manager ──
|
|
41
|
-
export {
|
|
42
|
-
createContextManager,
|
|
43
|
-
CHAT_MESSAGE_MODEL,
|
|
44
|
-
CONTEXT_SUMMARY_MODEL,
|
|
45
|
-
} from './context-manager.js';
|
|
46
|
-
export type {
|
|
47
|
-
ContextManager,
|
|
48
|
-
ContextConfig,
|
|
49
|
-
MessageRecord,
|
|
50
|
-
} from './context-manager.js';
|
|
51
|
-
|
|
52
|
-
// ── ZhinAgent ──
|
|
53
|
-
export { ZhinAgent } from './zhin-agent/index.js';
|
|
54
|
-
export type { ZhinAgentConfig, OnChunkCallback } from './zhin-agent/index.js';
|
|
55
|
-
|
|
56
|
-
// ── ZhinAgent sub-modules (for advanced consumers) ──
|
|
57
|
-
export { PERM_MAP, DEFAULT_CONFIG as ZHIN_AGENT_DEFAULT_CONFIG, SECTION_SEP } from './zhin-agent/config.js';
|
|
58
|
-
export { checkExecPolicy, applyExecPolicyToTools, resolveExecAllowlist, EXEC_PRESETS } from './zhin-agent/exec-policy.js';
|
|
59
|
-
export { collectRelevantTools, toAgentTool } from './zhin-agent/tool-collector.js';
|
|
60
|
-
export { buildRichSystemPrompt, buildContextHint, buildEnhancedPersona, buildUserMessageWithHistory, contentToText } from './zhin-agent/prompt.js';
|
|
61
|
-
export type { RichSystemPromptContext } from './zhin-agent/prompt.js';
|
|
62
|
-
export { createChatHistoryTool, createUserProfileTool, createScheduleFollowUpTool, createSpawnTaskTool } from './zhin-agent/builtin-tools.js';
|
|
63
|
-
|
|
64
|
-
// ── Conversation Memory ──
|
|
65
|
-
export {
|
|
66
|
-
ConversationMemory,
|
|
67
|
-
AI_MESSAGE_MODEL,
|
|
68
|
-
AI_SUMMARY_MODEL,
|
|
69
|
-
} from './conversation-memory.js';
|
|
70
|
-
export type { ConversationMemoryConfig } from './conversation-memory.js';
|
|
71
|
-
|
|
72
|
-
// ── User Profile ──
|
|
73
|
-
export {
|
|
74
|
-
UserProfileStore,
|
|
75
|
-
AI_USER_PROFILE_MODEL,
|
|
76
|
-
} from './user-profile.js';
|
|
77
|
-
|
|
78
|
-
// ── Rate Limiter ──
|
|
79
|
-
export { RateLimiter } from './rate-limiter.js';
|
|
80
|
-
export type { RateLimitConfig, RateLimitResult } from './rate-limiter.js';
|
|
81
|
-
|
|
82
|
-
// ── Follow-Up ──
|
|
83
|
-
export { FollowUpManager, AI_FOLLOWUP_MODEL } from './follow-up.js';
|
|
84
|
-
export type { FollowUpRecord, FollowUpSender } from './follow-up.js';
|
|
85
|
-
|
|
86
|
-
// ── Subagent ──
|
|
87
|
-
export { SubagentManager } from './subagent.js';
|
|
88
|
-
export type {
|
|
89
|
-
SubagentOrigin,
|
|
90
|
-
SubagentResultSender,
|
|
91
|
-
SpawnOptions,
|
|
92
|
-
SubagentManagerOptions,
|
|
93
|
-
} from './subagent.js';
|
|
94
|
-
|
|
95
|
-
// ── 持久化定时任务引擎 ──
|
|
96
|
-
export {
|
|
97
|
-
PersistentCronEngine,
|
|
98
|
-
readCronJobsFile,
|
|
99
|
-
writeCronJobsFile,
|
|
100
|
-
getCronJobsFilePath,
|
|
101
|
-
generateCronJobId,
|
|
102
|
-
createCronTools,
|
|
103
|
-
setCronManager,
|
|
104
|
-
getCronManager,
|
|
105
|
-
CRON_JOBS_FILENAME,
|
|
106
|
-
} from './cron-engine.js';
|
|
107
|
-
export type {
|
|
108
|
-
CronJobRecord,
|
|
109
|
-
CronRunner,
|
|
110
|
-
AddCronFn,
|
|
111
|
-
PersistentCronEngineOptions,
|
|
112
|
-
CronManager,
|
|
113
|
-
} from './cron-engine.js';
|
|
114
|
-
|
|
115
|
-
// ── Tone Detector ──
|
|
116
|
-
export { detectTone } from './tone-detector.js';
|
|
117
|
-
export type { Tone } from './tone-detector.js';
|
|
118
|
-
|
|
119
|
-
// ── 多模态输出 ──
|
|
120
|
-
export {
|
|
121
|
-
parseOutput,
|
|
122
|
-
renderToPlainText,
|
|
123
|
-
renderToSatori,
|
|
124
|
-
} from './output.js';
|
|
125
|
-
export type {
|
|
126
|
-
OutputElement,
|
|
127
|
-
TextElement,
|
|
128
|
-
ImageElement,
|
|
129
|
-
AudioElement,
|
|
130
|
-
VideoElement,
|
|
131
|
-
CardElement,
|
|
132
|
-
FileElement,
|
|
133
|
-
CardField,
|
|
134
|
-
CardButton,
|
|
135
|
-
} from './output.js';
|
|
136
|
-
|
|
137
|
-
// ── 内置工具 ──
|
|
138
|
-
export {
|
|
139
|
-
calculatorTool,
|
|
140
|
-
timeTool,
|
|
141
|
-
searchTool,
|
|
142
|
-
codeRunnerTool,
|
|
143
|
-
httpTool,
|
|
144
|
-
memoryTool,
|
|
145
|
-
getBuiltinTools,
|
|
146
|
-
getAllBuiltinTools,
|
|
147
|
-
} from './tools.js';
|
|
148
|
-
|
|
149
32
|
// ── Providers ──
|
|
150
33
|
export {
|
|
151
34
|
BaseProvider,
|
|
@@ -161,64 +44,3 @@ export type {
|
|
|
161
44
|
AnthropicConfig,
|
|
162
45
|
OllamaConfig,
|
|
163
46
|
} from './providers/index.js';
|
|
164
|
-
|
|
165
|
-
// ── 初始化 ──
|
|
166
|
-
export { initAIModule } from './init.js';
|
|
167
|
-
|
|
168
|
-
// ── Hook 系统 (借鉴 OpenClaw) ──
|
|
169
|
-
export {
|
|
170
|
-
registerAIHook,
|
|
171
|
-
unregisterAIHook,
|
|
172
|
-
triggerAIHook,
|
|
173
|
-
createAIHookEvent,
|
|
174
|
-
clearAIHooks,
|
|
175
|
-
getRegisteredAIHookKeys,
|
|
176
|
-
} from './hooks.js';
|
|
177
|
-
export type {
|
|
178
|
-
AIHookEvent,
|
|
179
|
-
AIHookEventType,
|
|
180
|
-
AIHookHandler,
|
|
181
|
-
MessageReceivedEvent,
|
|
182
|
-
MessageSentEvent,
|
|
183
|
-
SessionCompactEvent,
|
|
184
|
-
SessionNewEvent,
|
|
185
|
-
AgentBootstrapEvent,
|
|
186
|
-
ToolCallEvent,
|
|
187
|
-
} from './hooks.js';
|
|
188
|
-
|
|
189
|
-
// ── 会话压缩 (借鉴 OpenClaw) ──
|
|
190
|
-
export {
|
|
191
|
-
estimateTokens,
|
|
192
|
-
estimateMessagesTokens,
|
|
193
|
-
splitMessagesByTokenShare,
|
|
194
|
-
chunkMessagesByMaxTokens,
|
|
195
|
-
computeAdaptiveChunkRatio,
|
|
196
|
-
resolveContextWindowTokens,
|
|
197
|
-
evaluateContextWindowGuard,
|
|
198
|
-
summarizeWithFallback,
|
|
199
|
-
summarizeInStages,
|
|
200
|
-
pruneHistoryForContext,
|
|
201
|
-
compactSession,
|
|
202
|
-
DEFAULT_CONTEXT_TOKENS,
|
|
203
|
-
} from './compaction.js';
|
|
204
|
-
export type {
|
|
205
|
-
ContextWindowSource,
|
|
206
|
-
ContextWindowInfo,
|
|
207
|
-
ContextWindowGuardResult,
|
|
208
|
-
PruneResult,
|
|
209
|
-
} from './compaction.js';
|
|
210
|
-
|
|
211
|
-
// ── 引导文件管理 (借鉴 OpenClaw) ──
|
|
212
|
-
export {
|
|
213
|
-
loadBootstrapFiles,
|
|
214
|
-
buildContextFiles,
|
|
215
|
-
buildBootstrapContextSection,
|
|
216
|
-
loadSoulPersona,
|
|
217
|
-
loadToolsGuide,
|
|
218
|
-
loadAgentsMemory,
|
|
219
|
-
clearBootstrapCache,
|
|
220
|
-
} from './bootstrap.js';
|
|
221
|
-
export type {
|
|
222
|
-
BootstrapFile,
|
|
223
|
-
ContextFile,
|
|
224
|
-
} from './bootstrap.js';
|
package/src/ai/types.ts
CHANGED
|
@@ -51,10 +51,11 @@ export interface JsonSchema {
|
|
|
51
51
|
properties?: Record<string, JsonSchema>;
|
|
52
52
|
required?: string[];
|
|
53
53
|
items?: JsonSchema;
|
|
54
|
-
enum?:
|
|
54
|
+
enum?: unknown[];
|
|
55
55
|
description?: string;
|
|
56
|
-
default?:
|
|
57
|
-
|
|
56
|
+
default?: unknown;
|
|
57
|
+
/** JSON Schema allows arbitrary extension properties */
|
|
58
|
+
[key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any -- JSON Schema spec requires open index
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
// ============================================================================
|
|
@@ -183,7 +184,7 @@ export interface AgentTool {
|
|
|
183
184
|
name: string;
|
|
184
185
|
description: string;
|
|
185
186
|
parameters: JsonSchema;
|
|
186
|
-
execute: (args: Record<string, any>) => Promise<
|
|
187
|
+
execute: (args: Record<string, any>) => Promise<unknown>;
|
|
187
188
|
/** 工具标签,用于分类和快速匹配 */
|
|
188
189
|
tags?: string[];
|
|
189
190
|
/** 触发关键词,用户消息包含这些词时优先选择此工具 */
|
package/src/built/ai-trigger.ts
CHANGED
|
@@ -171,12 +171,12 @@ export function inferSenderPermissions<T extends object>(
|
|
|
171
171
|
|
|
172
172
|
const isGroupOwner = senderPermissions.includes('owner') ||
|
|
173
173
|
senderPermissions.includes('group_owner') ||
|
|
174
|
-
|
|
174
|
+
message.$sender?.role === 'owner';
|
|
175
175
|
|
|
176
176
|
const isGroupAdmin = isGroupOwner ||
|
|
177
177
|
senderPermissions.includes('admin') ||
|
|
178
178
|
senderPermissions.includes('group_admin') ||
|
|
179
|
-
|
|
179
|
+
message.$sender?.role === 'admin';
|
|
180
180
|
|
|
181
181
|
let permissionLevel: ToolPermissionLevel = 'user';
|
|
182
182
|
if (isOwner) permissionLevel = 'owner';
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group Management Skill — 方法规范与元数据
|
|
3
|
+
*
|
|
4
|
+
* 设计理念:
|
|
5
|
+
* 群管理是 IM 系统的一种"技能"(Skill),而非一组零散的工具。
|
|
6
|
+
* Adapter 基类声明群管理操作的方法规范(可选),
|
|
7
|
+
* 具体适配器(ICQQ/Discord/Telegram 等)选择性覆写。
|
|
8
|
+
* Adapter.start() 自动检测哪些方法已被子类实现,
|
|
9
|
+
* 生成对应的 Tool 并注册为 "群聊管理" Skill。
|
|
10
|
+
*
|
|
11
|
+
* 子类无需任何额外调用:
|
|
12
|
+
*
|
|
13
|
+
* class IcqqAdapter extends Adapter<IcqqBot> {
|
|
14
|
+
* async kickMember(botId, sceneId, userId) { ... }
|
|
15
|
+
* async muteMember(botId, sceneId, userId, duration) { ... }
|
|
16
|
+
* // start() 中自动检测 → 自动注册 Skill,零样板代码
|
|
17
|
+
* }
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { ToolPermissionLevel } from '../types.js';
|
|
21
|
+
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Adapter 群管理方法规范
|
|
24
|
+
// ============================================================================
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 群管理能力接口。
|
|
28
|
+
* Adapter 基类通过此接口声明方法签名,子类选择性覆写。
|
|
29
|
+
*/
|
|
30
|
+
export interface IGroupManagement {
|
|
31
|
+
kickMember?(botId: string, sceneId: string, userId: string): Promise<any>;
|
|
32
|
+
muteMember?(botId: string, sceneId: string, userId: string, duration?: number): Promise<any>;
|
|
33
|
+
setMemberNickname?(botId: string, sceneId: string, userId: string, nickname: string): Promise<any>;
|
|
34
|
+
setAdmin?(botId: string, sceneId: string, userId: string, enable?: boolean): Promise<any>;
|
|
35
|
+
listMembers?(botId: string, sceneId: string): Promise<any>;
|
|
36
|
+
banMember?(botId: string, sceneId: string, userId: string, reason?: string): Promise<any>;
|
|
37
|
+
unbanMember?(botId: string, sceneId: string, userId: string): Promise<any>;
|
|
38
|
+
setGroupName?(botId: string, sceneId: string, name: string): Promise<any>;
|
|
39
|
+
muteAll?(botId: string, sceneId: string, enable?: boolean): Promise<any>;
|
|
40
|
+
getGroupInfo?(botId: string, sceneId: string): Promise<any>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// 方法 → Tool 元数据映射
|
|
45
|
+
// ============================================================================
|
|
46
|
+
|
|
47
|
+
export interface GroupMethodSpec {
|
|
48
|
+
method: keyof IGroupManagement;
|
|
49
|
+
toolSuffix: string;
|
|
50
|
+
description: string;
|
|
51
|
+
keywords: string[];
|
|
52
|
+
permissionLevel: ToolPermissionLevel;
|
|
53
|
+
extraParams: Record<string, { type: string; description: string; default?: any }>;
|
|
54
|
+
extraRequired?: string[];
|
|
55
|
+
preExecutable?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const GROUP_METHOD_SPECS: GroupMethodSpec[] = [
|
|
59
|
+
{
|
|
60
|
+
method: 'kickMember',
|
|
61
|
+
toolSuffix: 'kick_member',
|
|
62
|
+
description: '将成员踢出群/服务器',
|
|
63
|
+
keywords: ['踢', 'kick', '移除', '踢出'],
|
|
64
|
+
permissionLevel: 'group_admin',
|
|
65
|
+
extraParams: {
|
|
66
|
+
user_id: { type: 'string', description: '目标用户 ID' },
|
|
67
|
+
},
|
|
68
|
+
extraRequired: ['user_id'],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
method: 'muteMember',
|
|
72
|
+
toolSuffix: 'mute_member',
|
|
73
|
+
description: '禁言群成员(duration=0 解除)',
|
|
74
|
+
keywords: ['禁言', 'mute', '静音', '解除禁言'],
|
|
75
|
+
permissionLevel: 'group_admin',
|
|
76
|
+
extraParams: {
|
|
77
|
+
user_id: { type: 'string', description: '目标用户 ID' },
|
|
78
|
+
duration: { type: 'number', description: '禁言时长(秒),0=解除', default: 600 },
|
|
79
|
+
},
|
|
80
|
+
extraRequired: ['user_id'],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
method: 'setMemberNickname',
|
|
84
|
+
toolSuffix: 'set_nickname',
|
|
85
|
+
description: '设置群成员昵称/名片',
|
|
86
|
+
keywords: ['昵称', '名片', 'nickname', 'card'],
|
|
87
|
+
permissionLevel: 'group_admin',
|
|
88
|
+
extraParams: {
|
|
89
|
+
user_id: { type: 'string', description: '目标用户 ID' },
|
|
90
|
+
nickname: { type: 'string', description: '新昵称' },
|
|
91
|
+
},
|
|
92
|
+
extraRequired: ['user_id', 'nickname'],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
method: 'setAdmin',
|
|
96
|
+
toolSuffix: 'set_admin',
|
|
97
|
+
description: '设置/取消群管理员',
|
|
98
|
+
keywords: ['管理员', 'admin', '设置管理'],
|
|
99
|
+
permissionLevel: 'group_owner',
|
|
100
|
+
extraParams: {
|
|
101
|
+
user_id: { type: 'string', description: '目标用户 ID' },
|
|
102
|
+
enable: { type: 'boolean', description: '设置(true)/取消(false)', default: true },
|
|
103
|
+
},
|
|
104
|
+
extraRequired: ['user_id'],
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
method: 'listMembers',
|
|
108
|
+
toolSuffix: 'list_members',
|
|
109
|
+
description: '获取群/服务器成员列表',
|
|
110
|
+
keywords: ['成员', '列表', 'members', 'list'],
|
|
111
|
+
permissionLevel: 'user',
|
|
112
|
+
extraParams: {},
|
|
113
|
+
preExecutable: true,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
method: 'banMember',
|
|
117
|
+
toolSuffix: 'ban_member',
|
|
118
|
+
description: '封禁成员',
|
|
119
|
+
keywords: ['封禁', 'ban', '拉黑'],
|
|
120
|
+
permissionLevel: 'group_admin',
|
|
121
|
+
extraParams: {
|
|
122
|
+
user_id: { type: 'string', description: '目标用户 ID' },
|
|
123
|
+
reason: { type: 'string', description: '封禁原因' },
|
|
124
|
+
},
|
|
125
|
+
extraRequired: ['user_id'],
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
method: 'unbanMember',
|
|
129
|
+
toolSuffix: 'unban_member',
|
|
130
|
+
description: '解除封禁',
|
|
131
|
+
keywords: ['解封', 'unban', '解除封禁'],
|
|
132
|
+
permissionLevel: 'group_admin',
|
|
133
|
+
extraParams: {
|
|
134
|
+
user_id: { type: 'string', description: '目标用户 ID' },
|
|
135
|
+
},
|
|
136
|
+
extraRequired: ['user_id'],
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
method: 'setGroupName',
|
|
140
|
+
toolSuffix: 'set_group_name',
|
|
141
|
+
description: '修改群名称',
|
|
142
|
+
keywords: ['群名', '改名', 'group name'],
|
|
143
|
+
permissionLevel: 'group_admin',
|
|
144
|
+
extraParams: {
|
|
145
|
+
name: { type: 'string', description: '新群名' },
|
|
146
|
+
},
|
|
147
|
+
extraRequired: ['name'],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
method: 'muteAll',
|
|
151
|
+
toolSuffix: 'mute_all',
|
|
152
|
+
description: '全员禁言/解除全员禁言',
|
|
153
|
+
keywords: ['全员禁言', 'mute all', '全体禁言'],
|
|
154
|
+
permissionLevel: 'group_admin',
|
|
155
|
+
extraParams: {
|
|
156
|
+
enable: { type: 'boolean', description: '开启(true)/解除(false)', default: true },
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
method: 'getGroupInfo',
|
|
161
|
+
toolSuffix: 'get_group_info',
|
|
162
|
+
description: '获取群/服务器基本信息',
|
|
163
|
+
keywords: ['群信息', 'group info', '群资料'],
|
|
164
|
+
permissionLevel: 'user',
|
|
165
|
+
extraParams: {},
|
|
166
|
+
preExecutable: true,
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
|
|
170
|
+
// ============================================================================
|
|
171
|
+
// Skill 常量
|
|
172
|
+
// ============================================================================
|
|
173
|
+
|
|
174
|
+
export const GROUP_MANAGEMENT_SKILL_DESCRIPTION =
|
|
175
|
+
'群聊管理能力:在 IM 系统中对群/服务器进行管理,包括踢人、禁言、封禁、' +
|
|
176
|
+
'设置管理员、修改群名、查看成员列表等操作。具体可用的操作取决于平台和 Bot 权限。';
|
|
177
|
+
|
|
178
|
+
export const GROUP_MANAGEMENT_SKILL_TAGS = ['group', 'management', 'im', 'admin'];
|
|
179
|
+
export const GROUP_MANAGEMENT_SKILL_KEYWORDS = [
|
|
180
|
+
'群管理', '踢人', '禁言', '封禁', '管理员', '群名',
|
|
181
|
+
'成员', 'kick', 'mute', 'ban', 'admin', 'members',
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
// ============================================================================
|
|
185
|
+
// 参数映射(method → 有序参数列表)
|
|
186
|
+
// ============================================================================
|
|
187
|
+
|
|
188
|
+
export function buildMethodArgs(
|
|
189
|
+
method: keyof IGroupManagement,
|
|
190
|
+
botId: string,
|
|
191
|
+
sceneId: string,
|
|
192
|
+
rest: Record<string, any>,
|
|
193
|
+
): any[] {
|
|
194
|
+
switch (method) {
|
|
195
|
+
case 'kickMember': return [botId, sceneId, rest.user_id];
|
|
196
|
+
case 'muteMember': return [botId, sceneId, rest.user_id, rest.duration ?? 600];
|
|
197
|
+
case 'setMemberNickname': return [botId, sceneId, rest.user_id, rest.nickname];
|
|
198
|
+
case 'setAdmin': return [botId, sceneId, rest.user_id, rest.enable ?? true];
|
|
199
|
+
case 'listMembers': return [botId, sceneId];
|
|
200
|
+
case 'banMember': return [botId, sceneId, rest.user_id, rest.reason];
|
|
201
|
+
case 'unbanMember': return [botId, sceneId, rest.user_id];
|
|
202
|
+
case 'setGroupName': return [botId, sceneId, rest.name];
|
|
203
|
+
case 'muteAll': return [botId, sceneId, rest.enable ?? true];
|
|
204
|
+
case 'getGroupInfo': return [botId, sceneId];
|
|
205
|
+
default: return [botId, sceneId, ...Object.values(rest)];
|
|
206
|
+
}
|
|
207
|
+
}
|