foliko 2.0.21 → 2.0.23
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/.editorconfig +56 -56
- package/.lintstagedrc +7 -7
- package/.prettierignore +29 -29
- package/.prettierrc +11 -11
- package/Dockerfile +63 -63
- package/install.ps1 +129 -129
- package/install.sh +121 -121
- package/package.json +3 -5
- package/plugins/core/skill-manager/index.js +34 -23
- package/plugins/core/sub-agent/index.js +103 -14
- package/plugins/core/workflow/context.js +941 -941
- package/plugins/core/workflow/engine.js +66 -66
- package/plugins/core/workflow/js-runner.js +318 -318
- package/plugins/core/workflow/json-runner.js +323 -323
- package/plugins/core/workflow/stages/choice.js +74 -74
- package/plugins/core/workflow/stages/each.js +123 -123
- package/plugins/core/workflow/stages/parallel.js +69 -69
- package/plugins/executors/extension/extension-registry.js +72 -1
- package/plugins/executors/extension/index.js +68 -9
- package/plugins/io/file-system/index.js +377 -153
- package/skills/find-skills/SKILL.md +133 -133
- package/src/agent/chat.js +207 -222
- package/src/agent/sub.js +29 -26
- package/src/agent/tool-loop.js +648 -0
- package/src/llm/provider.js +12 -28
- package/src/plugin/base.js +17 -14
- package/src/plugin/manager.js +19 -0
- package/src/tool/router.js +2 -2
- package/src/utils/message-validator.js +186 -0
- package/tests/core/chat-tool.test.js +187 -0
- package/tests/core/disable-thinking.test.js +64 -0
- package/tests/core/edit-file.test.js +194 -0
- package/tests/core/ext-call-empty-args.test.js +136 -0
- package/tests/core/reasoning-content.test.js +129 -0
- package/tests/core/sanitize-for-llm.test.js +152 -0
- package/tests/core/search.test.js +212 -0
- package/tests/core/skill-input-schema.test.js +150 -0
- package/tests/core/strip-stale-tool-calls.test.js +154 -0
- package/tests/core/sub-agent-parse.test.js +247 -0
- package/tests/core/sub-agent-skills.test.js +197 -0
- package/tests/core/tool-loop.test.js +208 -0
- package/weixin_o9cq80zgZqKPA2-s59PN43GdDy1w@im.wechat.jsonl +0 -76
package/src/agent/sub.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
const { BaseAgent } = require('./base');
|
|
10
10
|
const { cleanResponse } = require('../utils');
|
|
11
|
-
const {
|
|
11
|
+
const { ToolLoop } = require('./tool-loop');
|
|
12
12
|
const { z } = require('zod');
|
|
13
13
|
const { logger } = require('../common/logger');
|
|
14
14
|
const { validateAll } = require('../utils/message-validator');
|
|
@@ -30,7 +30,7 @@ class SubAgent extends BaseAgent {
|
|
|
30
30
|
this.defaulTools = ['ext_skill', 'skill_load', 'ext_call', 'subagent_call'];
|
|
31
31
|
this.bindTools = {
|
|
32
32
|
read: 'read_file', write: 'write_file', edit: 'modify_file',
|
|
33
|
-
glob: 'read_directory', grep: '
|
|
33
|
+
glob: 'read_directory', grep: 'search', bash: 'shell_exec',
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
this._customSystemPrompt = config.systemPrompt || null;
|
|
@@ -61,36 +61,40 @@ class SubAgent extends BaseAgent {
|
|
|
61
61
|
addTool(toolDef) { this.tools[toolDef.name] = toolDef; return this; }
|
|
62
62
|
getTools() { return Object.values(this.tools); }
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
const {
|
|
66
|
-
// 优先从 framework 的 ai
|
|
64
|
+
_getOpenAIClient() {
|
|
65
|
+
const { LLMProvider } = require('../llm/provider');
|
|
66
|
+
// 优先从 framework 的 ai 插件拿最新配置
|
|
67
67
|
const aiPlugin = this.framework?.pluginManager?.get('ai');
|
|
68
68
|
const aiConfig = aiPlugin ? aiPlugin.getConfig() : {};
|
|
69
|
-
|
|
69
|
+
const provider = new LLMProvider({
|
|
70
70
|
provider: aiConfig.provider || this.provider,
|
|
71
71
|
model: aiConfig.model || this.model,
|
|
72
72
|
apiKey: aiConfig.apiKey || this.apiKey,
|
|
73
73
|
baseURL: aiConfig.baseURL || this.baseURL,
|
|
74
74
|
});
|
|
75
|
+
return provider.createModel();
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
let parentTools = [];
|
|
78
|
+
_buildToolMap() {
|
|
79
|
+
const map = {};
|
|
80
|
+
const allTools = this.framework?.getTools() || [];
|
|
81
81
|
if (Array.isArray(this.parentTools)) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
const parentToolNames = this.parentTools.map(key => this.bindTools[key.toLocaleLowerCase()] || key);
|
|
83
|
+
// 父工具 + 默认工具
|
|
84
|
+
const names = new Set([...parentToolNames, ...this.defaulTools]);
|
|
85
|
+
for (const tool of allTools) {
|
|
86
|
+
if (names.has(tool.name)) {
|
|
87
|
+
map[tool.name] = tool;
|
|
88
|
+
}
|
|
89
89
|
}
|
|
90
90
|
} else {
|
|
91
|
-
|
|
91
|
+
allTools.forEach(t => { map[t.name] = t; });
|
|
92
|
+
}
|
|
93
|
+
// 覆盖 / 合并插件自身的工具
|
|
94
|
+
for (const [name, toolDef] of Object.entries(this.tools)) {
|
|
95
|
+
map[name] = toolDef;
|
|
92
96
|
}
|
|
93
|
-
return
|
|
97
|
+
return map;
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
_buildSystemPrompt() {
|
|
@@ -130,26 +134,25 @@ class SubAgent extends BaseAgent {
|
|
|
130
134
|
const maxSteps = options?.maxSteps || 30;
|
|
131
135
|
const maxRetries = options?.maxRetries ?? this.maxRetries;
|
|
132
136
|
const retryDelay = options?.retryDelay ?? this.retryDelay;
|
|
133
|
-
const
|
|
137
|
+
const client = this._getOpenAIClient();
|
|
134
138
|
|
|
135
139
|
let messages = Array.isArray(taskOrMessages) ? [...taskOrMessages] : [{ role: 'user', content: taskOrMessages }];
|
|
136
140
|
|
|
137
141
|
let lastError;
|
|
138
142
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
139
143
|
try {
|
|
140
|
-
const tools = this.disableTools ? {} : this.
|
|
144
|
+
const tools = this.disableTools ? {} : this._buildToolMap();
|
|
141
145
|
const systemPrompt = this.disableTools ? this._customSystemPrompt : this._buildSystemPrompt();
|
|
142
146
|
const validated = this._validateMessagesPairing(messages);
|
|
143
147
|
if (validated.length !== messages.length) { messages.length = 0; messages.push(...validated); }
|
|
144
148
|
|
|
145
|
-
const
|
|
146
|
-
model: aiProvider(this.model),
|
|
147
|
-
instructions: systemPrompt,
|
|
149
|
+
const loop = new ToolLoop({
|
|
148
150
|
tools,
|
|
149
|
-
|
|
151
|
+
maxSteps,
|
|
152
|
+
prepareStep: this._prepareStep ? this._prepareStep.bind(this) : undefined,
|
|
150
153
|
});
|
|
151
154
|
|
|
152
|
-
const result = await
|
|
155
|
+
const result = await loop.generate({ messages, systemPrompt, model: this.model, client, ...this.providerOptions });
|
|
153
156
|
messages.push(...result.response.messages);
|
|
154
157
|
const full_text = cleanResponse(result.text);
|
|
155
158
|
this.emit('complete', { message: full_text, steps: result.steps?.length || 0 });
|