@zhin.js/core 1.0.37 → 1.0.39
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/providers/anthropic.d.ts.map +1 -1
- package/lib/ai/providers/anthropic.js +2 -0
- package/lib/ai/providers/anthropic.js.map +1 -1
- package/lib/ai/providers/openai.d.ts.map +1 -1
- package/lib/ai/providers/openai.js +8 -0
- package/lib/ai/providers/openai.js.map +1 -1
- package/lib/ai/types.d.ts +5 -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/providers/anthropic.ts +1 -0
- package/src/ai/providers/openai.ts +5 -1
- package/src/ai/types.ts +6 -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 -702
- 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 -831
- 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
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ZhinAgent 工具收集 — 两级过滤 (Skill → Tool) + 技能支持工具注入
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { Logger } from '@zhin.js/logger';
|
|
6
|
-
import type { Tool, ToolContext } from '../../types.js';
|
|
7
|
-
import type { SkillFeature } from '../../built/skill.js';
|
|
8
|
-
import type { AgentTool } from '../types.js';
|
|
9
|
-
import { Agent } from '../agent.js';
|
|
10
|
-
import type { ZhinAgentConfig } from './config.js';
|
|
11
|
-
import { PERM_MAP } from './config.js';
|
|
12
|
-
|
|
13
|
-
const logger = new Logger(null, 'ZhinAgent:ToolCollector');
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Convert a Tool (with ToolContext) to an AgentTool, injecting context-provided parameters.
|
|
17
|
-
*/
|
|
18
|
-
export function toAgentTool(tool: Tool, context?: ToolContext): AgentTool {
|
|
19
|
-
const originalExecute = tool.execute;
|
|
20
|
-
|
|
21
|
-
const contextInjections: Array<{
|
|
22
|
-
paramName: string;
|
|
23
|
-
contextKey: string;
|
|
24
|
-
paramType: string;
|
|
25
|
-
}> = [];
|
|
26
|
-
let cleanParameters: any = tool.parameters;
|
|
27
|
-
|
|
28
|
-
if (context && tool.parameters?.properties) {
|
|
29
|
-
const props = tool.parameters.properties as Record<string, any>;
|
|
30
|
-
const filteredProps: Record<string, any> = {};
|
|
31
|
-
const filteredRequired: string[] = [];
|
|
32
|
-
|
|
33
|
-
for (const [key, schema] of Object.entries(props)) {
|
|
34
|
-
if (schema.contextKey && (context as any)[schema.contextKey] != null) {
|
|
35
|
-
contextInjections.push({
|
|
36
|
-
paramName: key,
|
|
37
|
-
contextKey: schema.contextKey,
|
|
38
|
-
paramType: schema.type || 'string',
|
|
39
|
-
});
|
|
40
|
-
} else {
|
|
41
|
-
filteredProps[key] = schema;
|
|
42
|
-
if (tool.parameters.required?.includes(key)) {
|
|
43
|
-
filteredRequired.push(key);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (contextInjections.length > 0) {
|
|
49
|
-
cleanParameters = {
|
|
50
|
-
...tool.parameters,
|
|
51
|
-
properties: filteredProps,
|
|
52
|
-
required: filteredRequired.length > 0 ? filteredRequired : undefined,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const at: AgentTool = {
|
|
58
|
-
name: tool.name,
|
|
59
|
-
description: tool.description,
|
|
60
|
-
parameters: cleanParameters as any,
|
|
61
|
-
execute: context
|
|
62
|
-
? (args: Record<string, any>) => {
|
|
63
|
-
const enrichedArgs = { ...args };
|
|
64
|
-
for (const { paramName, contextKey, paramType } of contextInjections) {
|
|
65
|
-
let value = (context as any)[contextKey];
|
|
66
|
-
if (paramType === 'number' && typeof value === 'string') {
|
|
67
|
-
value = Number(value);
|
|
68
|
-
} else if (paramType === 'string' && typeof value !== 'string') {
|
|
69
|
-
value = String(value);
|
|
70
|
-
}
|
|
71
|
-
enrichedArgs[paramName] = value;
|
|
72
|
-
}
|
|
73
|
-
return originalExecute(enrichedArgs, context);
|
|
74
|
-
}
|
|
75
|
-
: originalExecute,
|
|
76
|
-
};
|
|
77
|
-
if (tool.tags?.length) at.tags = tool.tags;
|
|
78
|
-
if (tool.keywords?.length) at.keywords = tool.keywords;
|
|
79
|
-
if (tool.permissionLevel) at.permissionLevel = PERM_MAP[tool.permissionLevel] ?? 0;
|
|
80
|
-
if (tool.preExecutable) at.preExecutable = true;
|
|
81
|
-
if ((tool as any).kind) at.kind = (tool as any).kind;
|
|
82
|
-
return at;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export interface CollectToolsContext {
|
|
86
|
-
config: Required<ZhinAgentConfig>;
|
|
87
|
-
skillRegistry: SkillFeature | null;
|
|
88
|
-
externalRegistered: Map<string, AgentTool>;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Two-level tool collection: Skill → Tool filtering, dedup, relevance ranking,
|
|
93
|
-
* skill-support injection, and config-level allow/deny.
|
|
94
|
-
*/
|
|
95
|
-
export function collectRelevantTools(
|
|
96
|
-
message: string,
|
|
97
|
-
context: ToolContext,
|
|
98
|
-
externalTools: Tool[],
|
|
99
|
-
ctx: CollectToolsContext,
|
|
100
|
-
): AgentTool[] {
|
|
101
|
-
const { config, skillRegistry, externalRegistered } = ctx;
|
|
102
|
-
|
|
103
|
-
const callerPerm = context.senderPermissionLevel
|
|
104
|
-
? (PERM_MAP[context.senderPermissionLevel] ?? 0)
|
|
105
|
-
: (context.isOwner ? 4 : context.isBotAdmin ? 3 : context.isGroupOwner ? 2 : context.isGroupAdmin ? 1 : 0);
|
|
106
|
-
|
|
107
|
-
const collected: AgentTool[] = [];
|
|
108
|
-
const collectedNames = new Set<string>();
|
|
109
|
-
|
|
110
|
-
// 0. Detect if user mentions a known skill name
|
|
111
|
-
let mentionedSkill: string | null = null;
|
|
112
|
-
if (skillRegistry && skillRegistry.size > 0) {
|
|
113
|
-
const msgLower = message.toLowerCase();
|
|
114
|
-
for (const skill of skillRegistry.getAll()) {
|
|
115
|
-
if (msgLower.includes(skill.name.toLowerCase())) {
|
|
116
|
-
mentionedSkill = skill.name;
|
|
117
|
-
logger.debug(`[技能检测] 用户提到技能: ${mentionedSkill}`);
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (mentionedSkill) {
|
|
124
|
-
const activateSkillTool = externalTools.find(t => t.name === 'activate_skill');
|
|
125
|
-
if (activateSkillTool) {
|
|
126
|
-
const toolPerm = activateSkillTool.permissionLevel ? (PERM_MAP[activateSkillTool.permissionLevel] ?? 0) : 0;
|
|
127
|
-
if (toolPerm <= callerPerm) {
|
|
128
|
-
collected.push(toAgentTool(activateSkillTool, context));
|
|
129
|
-
collectedNames.add('activate_skill');
|
|
130
|
-
logger.debug(`[技能激活] 已提前加入 activate_skill 工具(优先级最高)`);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// 1. SkillRegistry two-level filter
|
|
136
|
-
if (skillRegistry) {
|
|
137
|
-
const skills = skillRegistry.search(message, { maxResults: config.maxSkills });
|
|
138
|
-
const skillStr = skills.length > 0
|
|
139
|
-
? skills.map(s => `${s.name}(${s.tools?.length || 0}工具)`).join(', ')
|
|
140
|
-
: '(无匹配技能)';
|
|
141
|
-
logger.debug(`[Skill 匹配] ${skillStr}`);
|
|
142
|
-
|
|
143
|
-
for (const skill of skills) {
|
|
144
|
-
for (const tool of skill.tools) {
|
|
145
|
-
if (tool.platforms?.length && context.platform && !tool.platforms.includes(context.platform)) continue;
|
|
146
|
-
if (tool.scopes?.length && context.scope && !tool.scopes.includes(context.scope)) continue;
|
|
147
|
-
const toolPerm = tool.permissionLevel ? (PERM_MAP[tool.permissionLevel] ?? 0) : 0;
|
|
148
|
-
if (toolPerm > callerPerm) continue;
|
|
149
|
-
if (collectedNames.has(tool.name)) continue;
|
|
150
|
-
collected.push(toAgentTool(tool, context));
|
|
151
|
-
collectedNames.add(tool.name);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// 2. External tools
|
|
157
|
-
let deduped = 0;
|
|
158
|
-
for (const tool of externalTools) {
|
|
159
|
-
if (tool.name.startsWith('cmd_') || tool.name.startsWith('process_')) continue;
|
|
160
|
-
const toolPerm = tool.permissionLevel ? (PERM_MAP[tool.permissionLevel] ?? 0) : 0;
|
|
161
|
-
if (toolPerm > callerPerm) continue;
|
|
162
|
-
if (collectedNames.has(tool.name)) {
|
|
163
|
-
deduped++;
|
|
164
|
-
continue;
|
|
165
|
-
}
|
|
166
|
-
collected.push(toAgentTool(tool, context));
|
|
167
|
-
collectedNames.add(tool.name);
|
|
168
|
-
}
|
|
169
|
-
if (deduped > 0) {
|
|
170
|
-
logger.debug(`externalTools 去重: 跳过 ${deduped} 个已由 Skill 提供的工具`);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// 3. Externally registered tools
|
|
174
|
-
for (const tool of externalRegistered.values()) {
|
|
175
|
-
if (tool.permissionLevel != null && tool.permissionLevel > callerPerm) continue;
|
|
176
|
-
if (collectedNames.has(tool.name)) continue;
|
|
177
|
-
collected.push(tool);
|
|
178
|
-
collectedNames.add(tool.name);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// 4. Relevance filtering
|
|
182
|
-
const filtered = Agent.filterTools(message, collected, {
|
|
183
|
-
callerPermissionLevel: callerPerm,
|
|
184
|
-
maxTools: config.maxTools,
|
|
185
|
-
minScore: 0.3,
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// Prioritize activate_skill when a skill name was detected
|
|
189
|
-
if (mentionedSkill && filtered.length > 0) {
|
|
190
|
-
const activateSkillIdx = filtered.findIndex(t => t.name === 'activate_skill');
|
|
191
|
-
if (activateSkillIdx > 0) {
|
|
192
|
-
const activateSkillTool = filtered[activateSkillIdx];
|
|
193
|
-
filtered.splice(activateSkillIdx, 1);
|
|
194
|
-
filtered.unshift(activateSkillTool);
|
|
195
|
-
logger.debug(`[工具排序] activate_skill 提升至首位(因检测到技能: ${mentionedSkill})`);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Skill support tools injection
|
|
200
|
-
const SKILL_SUPPORT_TOOLS = ['bash', 'web_fetch', 'web_search', 'write_file', 'read_file'];
|
|
201
|
-
const hasSkillTool = filtered.some(t => t.name === 'activate_skill' || t.name === 'install_skill');
|
|
202
|
-
if (hasSkillTool) {
|
|
203
|
-
const filteredNames = new Set(filtered.map(t => t.name));
|
|
204
|
-
for (const supportName of SKILL_SUPPORT_TOOLS) {
|
|
205
|
-
if (filteredNames.has(supportName)) continue;
|
|
206
|
-
const supportTool = collected.find(t => t.name === supportName);
|
|
207
|
-
if (supportTool) {
|
|
208
|
-
filtered.push(supportTool);
|
|
209
|
-
filteredNames.add(supportName);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
logger.debug(`[技能支持] 已补充工具: ${SKILL_SUPPORT_TOOLS.filter(n => filteredNames.has(n)).join(', ')}`);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// 5. Config-level allow/deny
|
|
216
|
-
let final = filtered;
|
|
217
|
-
const allowed = config.allowedTools;
|
|
218
|
-
const disabled = config.disabledTools ?? [];
|
|
219
|
-
if (allowed && allowed.length > 0) {
|
|
220
|
-
const allowSet = new Set(allowed.map(n => n.toLowerCase()));
|
|
221
|
-
final = final.filter(t => allowSet.has(t.name.toLowerCase()));
|
|
222
|
-
if (final.length < filtered.length) {
|
|
223
|
-
logger.debug(`[工具开关] allowedTools 限制: ${filtered.length} -> ${final.length}`);
|
|
224
|
-
}
|
|
225
|
-
} else if (disabled.length > 0) {
|
|
226
|
-
const disabledSet = new Set(disabled.map(n => n.toLowerCase()));
|
|
227
|
-
final = final.filter(t => !disabledSet.has(t.name.toLowerCase()));
|
|
228
|
-
if (final.length < filtered.length) {
|
|
229
|
-
logger.debug(`[工具开关] disabledTools 过滤: ${filtered.length} -> ${final.length}`);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (final.length > 0) {
|
|
234
|
-
logger.debug(
|
|
235
|
-
`[工具收集] 收集了 ${collected.length} 个工具,过滤后 ${final.length} 个,` +
|
|
236
|
-
`用户消息相关性最高的: ${final.slice(0, 3).map(t => t.name).join(', ')}`
|
|
237
|
-
);
|
|
238
|
-
} else {
|
|
239
|
-
logger.debug(`[工具收集] 收集了 ${collected.length} 个工具,但过滤后 0 个(没有超过相关性阈值的)`);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return final;
|
|
243
|
-
}
|