sdkwork-browser-agent 1.0.0
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/README.md +228 -0
- package/README.zh.md +228 -0
- package/dist/agent-Bpxmkz8W.d.ts +197 -0
- package/dist/agent-kexkkI13.d.cts +197 -0
- package/dist/browser/agent-Bpxmkz8W.d.ts +197 -0
- package/dist/browser/chunk-7W2JJCSS.js +276 -0
- package/dist/browser/chunk-7W2JJCSS.js.map +1 -0
- package/dist/browser/chunk-BHRFRGR7.js +144 -0
- package/dist/browser/chunk-BHRFRGR7.js.map +1 -0
- package/dist/browser/chunk-CLP6UNSV.js +285 -0
- package/dist/browser/chunk-CLP6UNSV.js.map +1 -0
- package/dist/browser/chunk-HXLRBB7S.js +1569 -0
- package/dist/browser/chunk-HXLRBB7S.js.map +1 -0
- package/dist/browser/chunk-VJEFLRZT.js +1720 -0
- package/dist/browser/chunk-VJEFLRZT.js.map +1 -0
- package/dist/browser/index.d.ts +842 -0
- package/dist/browser/index.js +3293 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/llm/index.d.ts +235 -0
- package/dist/browser/llm/index.js +29 -0
- package/dist/browser/llm/index.js.map +1 -0
- package/dist/browser/mcp/index.d.ts +63 -0
- package/dist/browser/mcp/index.js +9 -0
- package/dist/browser/mcp/index.js.map +1 -0
- package/dist/browser/provider-Dna36xA-.d.ts +105 -0
- package/dist/browser/skills/index.d.ts +401 -0
- package/dist/browser/skills/index.js +31 -0
- package/dist/browser/skills/index.js.map +1 -0
- package/dist/browser/storage/index.d.ts +64 -0
- package/dist/browser/storage/index.js +15 -0
- package/dist/browser/storage/index.js.map +1 -0
- package/dist/browser/tools/index.d.ts +45 -0
- package/dist/browser/tools/index.js +15 -0
- package/dist/browser/tools/index.js.map +1 -0
- package/dist/browser/types-CG5I-byI.d.ts +30 -0
- package/dist/chunk-56J3IBXZ.js +144 -0
- package/dist/chunk-56J3IBXZ.js.map +1 -0
- package/dist/chunk-5XTVS5MB.js +1720 -0
- package/dist/chunk-5XTVS5MB.js.map +1 -0
- package/dist/chunk-6AYIRBGI.js +166 -0
- package/dist/chunk-6AYIRBGI.js.map +1 -0
- package/dist/chunk-C2EYJHXW.cjs +276 -0
- package/dist/chunk-C2EYJHXW.cjs.map +1 -0
- package/dist/chunk-HOZQ445W.cjs +166 -0
- package/dist/chunk-HOZQ445W.cjs.map +1 -0
- package/dist/chunk-KZNZ6CGD.cjs +144 -0
- package/dist/chunk-KZNZ6CGD.cjs.map +1 -0
- package/dist/chunk-XFMT5ZA4.js +276 -0
- package/dist/chunk-XFMT5ZA4.js.map +1 -0
- package/dist/chunk-XPGICLEJ.cjs +1720 -0
- package/dist/chunk-XPGICLEJ.cjs.map +1 -0
- package/dist/index.cjs +1311 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +395 -0
- package/dist/index.d.ts +395 -0
- package/dist/index.js +1311 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/index.cjs +29 -0
- package/dist/llm/index.cjs.map +1 -0
- package/dist/llm/index.d.cts +235 -0
- package/dist/llm/index.d.ts +235 -0
- package/dist/llm/index.js +29 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/mcp/index.cjs +9 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +63 -0
- package/dist/mcp/index.d.ts +63 -0
- package/dist/mcp/index.js +9 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/node/agent-Bpxmkz8W.d.ts +197 -0
- package/dist/node/agent-kexkkI13.d.cts +197 -0
- package/dist/node/chunk-7W2JJCSS.js +276 -0
- package/dist/node/chunk-7W2JJCSS.js.map +1 -0
- package/dist/node/chunk-BHRFRGR7.js +144 -0
- package/dist/node/chunk-BHRFRGR7.js.map +1 -0
- package/dist/node/chunk-CLP6UNSV.js +285 -0
- package/dist/node/chunk-CLP6UNSV.js.map +1 -0
- package/dist/node/chunk-HXLRBB7S.js +1569 -0
- package/dist/node/chunk-HXLRBB7S.js.map +1 -0
- package/dist/node/chunk-IYG37UN3.cjs +144 -0
- package/dist/node/chunk-IYG37UN3.cjs.map +1 -0
- package/dist/node/chunk-JF33ZOMB.cjs +285 -0
- package/dist/node/chunk-JF33ZOMB.cjs.map +1 -0
- package/dist/node/chunk-KXXS33G3.cjs +276 -0
- package/dist/node/chunk-KXXS33G3.cjs.map +1 -0
- package/dist/node/chunk-MTFOABGC.cjs +1720 -0
- package/dist/node/chunk-MTFOABGC.cjs.map +1 -0
- package/dist/node/chunk-VJEFLRZT.js +1720 -0
- package/dist/node/chunk-VJEFLRZT.js.map +1 -0
- package/dist/node/chunk-YDHQCPSN.cjs +1569 -0
- package/dist/node/chunk-YDHQCPSN.cjs.map +1 -0
- package/dist/node/index.cjs +3293 -0
- package/dist/node/index.cjs.map +1 -0
- package/dist/node/index.d.cts +842 -0
- package/dist/node/index.d.ts +842 -0
- package/dist/node/index.js +3293 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/llm/index.cjs +29 -0
- package/dist/node/llm/index.cjs.map +1 -0
- package/dist/node/llm/index.d.cts +235 -0
- package/dist/node/llm/index.d.ts +235 -0
- package/dist/node/llm/index.js +29 -0
- package/dist/node/llm/index.js.map +1 -0
- package/dist/node/mcp/index.cjs +9 -0
- package/dist/node/mcp/index.cjs.map +1 -0
- package/dist/node/mcp/index.d.cts +63 -0
- package/dist/node/mcp/index.d.ts +63 -0
- package/dist/node/mcp/index.js +9 -0
- package/dist/node/mcp/index.js.map +1 -0
- package/dist/node/provider-Dna36xA-.d.cts +105 -0
- package/dist/node/provider-Dna36xA-.d.ts +105 -0
- package/dist/node/skills/index.cjs +31 -0
- package/dist/node/skills/index.cjs.map +1 -0
- package/dist/node/skills/index.d.cts +401 -0
- package/dist/node/skills/index.d.ts +401 -0
- package/dist/node/skills/index.js +31 -0
- package/dist/node/skills/index.js.map +1 -0
- package/dist/node/storage/index.cjs +15 -0
- package/dist/node/storage/index.cjs.map +1 -0
- package/dist/node/storage/index.d.cts +64 -0
- package/dist/node/storage/index.d.ts +64 -0
- package/dist/node/storage/index.js +15 -0
- package/dist/node/storage/index.js.map +1 -0
- package/dist/node/tools/index.cjs +15 -0
- package/dist/node/tools/index.cjs.map +1 -0
- package/dist/node/tools/index.d.cts +45 -0
- package/dist/node/tools/index.d.ts +45 -0
- package/dist/node/tools/index.js +15 -0
- package/dist/node/tools/index.js.map +1 -0
- package/dist/node/types-CG5I-byI.d.cts +30 -0
- package/dist/node/types-CG5I-byI.d.ts +30 -0
- package/dist/provider-Dna36xA-.d.cts +105 -0
- package/dist/provider-Dna36xA-.d.ts +105 -0
- package/dist/skills/index.cjs +15 -0
- package/dist/skills/index.cjs.map +1 -0
- package/dist/skills/index.d.cts +43 -0
- package/dist/skills/index.d.ts +43 -0
- package/dist/skills/index.js +15 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/tools/index.cjs +15 -0
- package/dist/tools/index.cjs.map +1 -0
- package/dist/tools/index.d.cts +45 -0
- package/dist/tools/index.d.ts +45 -0
- package/dist/tools/index.js +15 -0
- package/dist/tools/index.js.map +1 -0
- package/package.json +150 -0
|
@@ -0,0 +1,3293 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14;
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
var _chunkMTFOABGCcjs = require('./chunk-MTFOABGC.cjs');
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
var _chunkYDHQCPSNcjs = require('./chunk-YDHQCPSN.cjs');
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
var _chunkKXXS33G3cjs = require('./chunk-KXXS33G3.cjs');
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
var _chunkIYG37UN3cjs = require('./chunk-IYG37UN3.cjs');
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
var _chunkJF33ZOMBcjs = require('./chunk-JF33ZOMB.cjs');
|
|
48
|
+
|
|
49
|
+
// src/core/agent.ts
|
|
50
|
+
var Agent = (_class = class {
|
|
51
|
+
constructor(config) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);
|
|
52
|
+
this.config = config;
|
|
53
|
+
this.name = config.name;
|
|
54
|
+
this.description = config.description;
|
|
55
|
+
this.version = config.version;
|
|
56
|
+
this.llmProvider = config.llmProvider;
|
|
57
|
+
this.systemPrompt = config.systemPrompt;
|
|
58
|
+
this.maxIterations = config.maxIterations || 10;
|
|
59
|
+
this.hooks = config.hooks;
|
|
60
|
+
this._middlewares = config.middlewares || [];
|
|
61
|
+
}
|
|
62
|
+
__init() {this._skills = /* @__PURE__ */ new Map()}
|
|
63
|
+
__init2() {this._tools = /* @__PURE__ */ new Map()}
|
|
64
|
+
__init3() {this._plugins = /* @__PURE__ */ new Map()}
|
|
65
|
+
__init4() {this._mcpResources = /* @__PURE__ */ new Map()}
|
|
66
|
+
__init5() {this._mcpTools = /* @__PURE__ */ new Map()}
|
|
67
|
+
__init6() {this._middlewares = []}
|
|
68
|
+
__init7() {this._initialized = false}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
async initialize() {
|
|
77
|
+
if (this._initialized) return;
|
|
78
|
+
_optionalChain([this, 'access', _2 => _2.config, 'access', _3 => _3.skills, 'optionalAccess', _4 => _4.forEach, 'call', _5 => _5((skill) => this.registerSkill(skill))]);
|
|
79
|
+
_optionalChain([this, 'access', _6 => _6.config, 'access', _7 => _7.tools, 'optionalAccess', _8 => _8.forEach, 'call', _9 => _9((tool) => this.registerTool(tool))]);
|
|
80
|
+
_optionalChain([this, 'access', _10 => _10.config, 'access', _11 => _11.mcpResources, 'optionalAccess', _12 => _12.forEach, 'call', _13 => _13((resource) => this.registerMCPResource(resource))]);
|
|
81
|
+
_optionalChain([this, 'access', _14 => _14.config, 'access', _15 => _15.mcpTools, 'optionalAccess', _16 => _16.forEach, 'call', _17 => _17((tool) => this.registerMCPTool(tool))]);
|
|
82
|
+
const pluginContext = {
|
|
83
|
+
agent: this,
|
|
84
|
+
registerSkill: (skill) => this.registerSkill(skill),
|
|
85
|
+
registerTool: (tool) => this.registerTool(tool),
|
|
86
|
+
registerMCPResource: (resource) => this.registerMCPResource(resource),
|
|
87
|
+
registerMCPTool: (tool) => this.registerMCPTool(tool),
|
|
88
|
+
getLLMProvider: () => this.llmProvider,
|
|
89
|
+
config: {}
|
|
90
|
+
};
|
|
91
|
+
for (const plugin of this.config.plugins || []) {
|
|
92
|
+
await plugin.initialize(pluginContext);
|
|
93
|
+
this._plugins.set(plugin.name, plugin);
|
|
94
|
+
}
|
|
95
|
+
this._initialized = true;
|
|
96
|
+
}
|
|
97
|
+
// ============================================
|
|
98
|
+
// Registration Methods
|
|
99
|
+
// ============================================
|
|
100
|
+
registerSkill(skill) {
|
|
101
|
+
if (this._skills.has(skill.name)) {
|
|
102
|
+
console.warn(`Skill '${skill.name}' is already registered. Overwriting.`);
|
|
103
|
+
}
|
|
104
|
+
this._skills.set(skill.name, skill);
|
|
105
|
+
}
|
|
106
|
+
registerTool(tool) {
|
|
107
|
+
if (this._tools.has(tool.name)) {
|
|
108
|
+
console.warn(`Tool '${tool.name}' is already registered. Overwriting.`);
|
|
109
|
+
}
|
|
110
|
+
this._tools.set(tool.name, tool);
|
|
111
|
+
}
|
|
112
|
+
registerMCPResource(resource) {
|
|
113
|
+
if (this._mcpResources.has(resource.uri)) {
|
|
114
|
+
console.warn(`MCP Resource '${resource.uri}' is already registered. Overwriting.`);
|
|
115
|
+
}
|
|
116
|
+
this._mcpResources.set(resource.uri, resource);
|
|
117
|
+
}
|
|
118
|
+
registerMCPTool(tool) {
|
|
119
|
+
if (this._mcpTools.has(tool.name)) {
|
|
120
|
+
console.warn(`MCP Tool '${tool.name}' is already registered. Overwriting.`);
|
|
121
|
+
}
|
|
122
|
+
this._mcpTools.set(tool.name, tool);
|
|
123
|
+
}
|
|
124
|
+
use(middleware) {
|
|
125
|
+
this._middlewares.push(middleware);
|
|
126
|
+
}
|
|
127
|
+
// ============================================
|
|
128
|
+
// Execution Methods
|
|
129
|
+
// ============================================
|
|
130
|
+
async executeSkill(name, params = {}) {
|
|
131
|
+
const skill = this._skills.get(name);
|
|
132
|
+
if (!skill) {
|
|
133
|
+
return { success: false, error: `Skill '${name}' not found` };
|
|
134
|
+
}
|
|
135
|
+
const context = {
|
|
136
|
+
agent: this,
|
|
137
|
+
skillName: name,
|
|
138
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
139
|
+
};
|
|
140
|
+
await _optionalChain([this, 'access', _18 => _18.hooks, 'optionalAccess', _19 => _19.beforeSkillExecution, 'optionalCall', _20 => _20(name, params)]);
|
|
141
|
+
const execute = async () => {
|
|
142
|
+
try {
|
|
143
|
+
const result = await skill.handler(params, context);
|
|
144
|
+
await _optionalChain([this, 'access', _21 => _21.hooks, 'optionalAccess', _22 => _22.afterSkillExecution, 'optionalCall', _23 => _23(name, result)]);
|
|
145
|
+
return result;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
148
|
+
await _optionalChain([this, 'access', _24 => _24.hooks, 'optionalAccess', _25 => _25.onError, 'optionalCall', _26 => _26(err, context)]);
|
|
149
|
+
return { success: false, error: err.message };
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const chain = this._middlewares.reduceRight(
|
|
153
|
+
(next, middleware) => () => middleware(context, next),
|
|
154
|
+
execute
|
|
155
|
+
);
|
|
156
|
+
return chain();
|
|
157
|
+
}
|
|
158
|
+
async executeTool(name, input) {
|
|
159
|
+
const tool = this._tools.get(name);
|
|
160
|
+
if (!tool) {
|
|
161
|
+
return {
|
|
162
|
+
content: [{ type: "error", text: `Tool '${name}' not found` }],
|
|
163
|
+
isError: true
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const context = {
|
|
167
|
+
agent: this,
|
|
168
|
+
skillName: name,
|
|
169
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
170
|
+
};
|
|
171
|
+
try {
|
|
172
|
+
await _optionalChain([this, 'access', _27 => _27.hooks, 'optionalAccess', _28 => _28.onToolCall, 'optionalCall', _29 => _29(name, input)]);
|
|
173
|
+
return await tool.execute(input, context);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
176
|
+
return {
|
|
177
|
+
content: [{ type: "error", text: message }],
|
|
178
|
+
isError: true
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async readMCPResource(uri) {
|
|
183
|
+
const resource = this._mcpResources.get(uri);
|
|
184
|
+
if (!resource) return null;
|
|
185
|
+
return resource.read();
|
|
186
|
+
}
|
|
187
|
+
async executeMCPTool(name, args) {
|
|
188
|
+
const tool = this._mcpTools.get(name);
|
|
189
|
+
if (!tool) {
|
|
190
|
+
return {
|
|
191
|
+
content: [{ type: "error", text: `MCP Tool '${name}' not found` }],
|
|
192
|
+
isError: true
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
const context = {
|
|
196
|
+
agent: this,
|
|
197
|
+
skillName: name,
|
|
198
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
199
|
+
};
|
|
200
|
+
try {
|
|
201
|
+
return await tool.execute(args, context);
|
|
202
|
+
} catch (error) {
|
|
203
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
204
|
+
return {
|
|
205
|
+
content: [{ type: "error", text: message }],
|
|
206
|
+
isError: true
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// ============================================
|
|
211
|
+
// LLM Integration
|
|
212
|
+
// ============================================
|
|
213
|
+
async chat(messages, options) {
|
|
214
|
+
if (!this.llmProvider) {
|
|
215
|
+
throw new Error("No LLM provider configured");
|
|
216
|
+
}
|
|
217
|
+
const request = {
|
|
218
|
+
messages: this.systemPrompt ? [{ role: "system", content: this.systemPrompt }, ...messages] : messages,
|
|
219
|
+
...options
|
|
220
|
+
};
|
|
221
|
+
return this.llmProvider.complete(request);
|
|
222
|
+
}
|
|
223
|
+
async *streamChat(messages, options) {
|
|
224
|
+
if (!this.llmProvider) {
|
|
225
|
+
throw new Error("No LLM provider configured");
|
|
226
|
+
}
|
|
227
|
+
const request = {
|
|
228
|
+
messages: this.systemPrompt ? [{ role: "system", content: this.systemPrompt }, ...messages] : messages,
|
|
229
|
+
stream: true,
|
|
230
|
+
...options
|
|
231
|
+
};
|
|
232
|
+
yield* this.llmProvider.stream(request);
|
|
233
|
+
}
|
|
234
|
+
async executeWithTools(messages, tools) {
|
|
235
|
+
if (!this.llmProvider) {
|
|
236
|
+
throw new Error("No LLM provider configured");
|
|
237
|
+
}
|
|
238
|
+
const request = {
|
|
239
|
+
messages: this.systemPrompt ? [{ role: "system", content: this.systemPrompt }, ...messages] : messages,
|
|
240
|
+
tools,
|
|
241
|
+
tool_choice: "auto"
|
|
242
|
+
};
|
|
243
|
+
return this.llmProvider.complete(request);
|
|
244
|
+
}
|
|
245
|
+
// ============================================
|
|
246
|
+
// Query Methods
|
|
247
|
+
// ============================================
|
|
248
|
+
getSkill(name) {
|
|
249
|
+
return this._skills.get(name);
|
|
250
|
+
}
|
|
251
|
+
getTool(name) {
|
|
252
|
+
return this._tools.get(name);
|
|
253
|
+
}
|
|
254
|
+
getMCPResource(uri) {
|
|
255
|
+
return this._mcpResources.get(uri);
|
|
256
|
+
}
|
|
257
|
+
getMCPTool(name) {
|
|
258
|
+
return this._mcpTools.get(name);
|
|
259
|
+
}
|
|
260
|
+
getPlugin(name) {
|
|
261
|
+
return this._plugins.get(name);
|
|
262
|
+
}
|
|
263
|
+
getSkillNames() {
|
|
264
|
+
return Array.from(this._skills.keys());
|
|
265
|
+
}
|
|
266
|
+
getToolNames() {
|
|
267
|
+
return Array.from(this._tools.keys());
|
|
268
|
+
}
|
|
269
|
+
getMCPResourceURIs() {
|
|
270
|
+
return Array.from(this._mcpResources.keys());
|
|
271
|
+
}
|
|
272
|
+
getMCPToolNames() {
|
|
273
|
+
return Array.from(this._mcpTools.keys());
|
|
274
|
+
}
|
|
275
|
+
getPluginNames() {
|
|
276
|
+
return Array.from(this._plugins.keys());
|
|
277
|
+
}
|
|
278
|
+
getAllSkills() {
|
|
279
|
+
return Array.from(this._skills.values());
|
|
280
|
+
}
|
|
281
|
+
getAllTools() {
|
|
282
|
+
return Array.from(this._tools.values());
|
|
283
|
+
}
|
|
284
|
+
// ============================================
|
|
285
|
+
// Lifecycle Methods
|
|
286
|
+
// ============================================
|
|
287
|
+
async destroy() {
|
|
288
|
+
for (const plugin of this._plugins.values()) {
|
|
289
|
+
await _optionalChain([plugin, 'access', _30 => _30.destroy, 'optionalCall', _31 => _31()]);
|
|
290
|
+
}
|
|
291
|
+
this._skills.clear();
|
|
292
|
+
this._tools.clear();
|
|
293
|
+
this._plugins.clear();
|
|
294
|
+
this._mcpResources.clear();
|
|
295
|
+
this._mcpTools.clear();
|
|
296
|
+
this._middlewares = [];
|
|
297
|
+
this._initialized = false;
|
|
298
|
+
}
|
|
299
|
+
}, _class);
|
|
300
|
+
|
|
301
|
+
// src/core/decision-engine.ts
|
|
302
|
+
var SimpleEmbeddingProvider = (_class2 = class {constructor() { _class2.prototype.__init8.call(this);_class2.prototype.__init9.call(this);_class2.prototype.__init10.call(this); }
|
|
303
|
+
__init8() {this.vocabulary = /* @__PURE__ */ new Map()}
|
|
304
|
+
__init9() {this.vocabSize = 0}
|
|
305
|
+
__init10() {this.maxVocabSize = 1e3}
|
|
306
|
+
async embed(text) {
|
|
307
|
+
const tokens = this.tokenize(text);
|
|
308
|
+
const embedding = new Array(this.maxVocabSize).fill(0);
|
|
309
|
+
for (const token of tokens) {
|
|
310
|
+
if (!this.vocabulary.has(token)) {
|
|
311
|
+
if (this.vocabSize < this.maxVocabSize) {
|
|
312
|
+
this.vocabulary.set(token, this.vocabSize++);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const idx = this.vocabulary.get(token);
|
|
316
|
+
if (idx !== void 0) {
|
|
317
|
+
embedding[idx] += 1;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
const magnitude = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
|
|
321
|
+
if (magnitude > 0) {
|
|
322
|
+
return embedding.map((val) => val / magnitude);
|
|
323
|
+
}
|
|
324
|
+
return embedding;
|
|
325
|
+
}
|
|
326
|
+
similarity(a, b) {
|
|
327
|
+
let dotProduct = 0;
|
|
328
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) {
|
|
329
|
+
dotProduct += a[i] * b[i];
|
|
330
|
+
}
|
|
331
|
+
return dotProduct;
|
|
332
|
+
}
|
|
333
|
+
tokenize(text) {
|
|
334
|
+
return text.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((t) => t.length > 2);
|
|
335
|
+
}
|
|
336
|
+
}, _class2);
|
|
337
|
+
var DecisionEngine = (_class3 = class {
|
|
338
|
+
__init11() {this.skillEmbeddings = /* @__PURE__ */ new Map()}
|
|
339
|
+
|
|
340
|
+
__init12() {this.decisionCache = /* @__PURE__ */ new Map()}
|
|
341
|
+
|
|
342
|
+
constructor(config = {}, embeddingProvider) {;_class3.prototype.__init11.call(this);_class3.prototype.__init12.call(this);
|
|
343
|
+
this.config = {
|
|
344
|
+
threshold: _nullishCoalesce(config.threshold, () => ( 0.6)),
|
|
345
|
+
maxSkills: _nullishCoalesce(config.maxSkills, () => ( 3)),
|
|
346
|
+
enableEmbeddings: _nullishCoalesce(config.enableEmbeddings, () => ( true)),
|
|
347
|
+
enableCaching: _nullishCoalesce(config.enableCaching, () => ( true)),
|
|
348
|
+
similarityThreshold: _nullishCoalesce(config.similarityThreshold, () => ( 0.5))
|
|
349
|
+
};
|
|
350
|
+
this.embeddingProvider = _nullishCoalesce(embeddingProvider, () => ( new SimpleEmbeddingProvider()));
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Index skills for fast retrieval
|
|
354
|
+
*/
|
|
355
|
+
async indexSkill(skill) {
|
|
356
|
+
if (!this.config.enableEmbeddings) return;
|
|
357
|
+
const text = `${skill.name} ${skill.description} ${this.extractKeywords(skill)}`;
|
|
358
|
+
const embedding = await this.embeddingProvider.embed(text);
|
|
359
|
+
this.skillEmbeddings.set(skill.name, embedding);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Make decision based on input
|
|
363
|
+
*/
|
|
364
|
+
async decide(context) {
|
|
365
|
+
const cacheKey = this.generateCacheKey(context);
|
|
366
|
+
if (this.config.enableCaching) {
|
|
367
|
+
const cached = this.decisionCache.get(cacheKey);
|
|
368
|
+
if (cached) return cached;
|
|
369
|
+
}
|
|
370
|
+
const relevantSkills = await this.findRelevantSkills(context);
|
|
371
|
+
const relevantTools = this.findRelevantTools(context);
|
|
372
|
+
let decision;
|
|
373
|
+
if (relevantSkills.length === 0 && relevantTools.length === 0) {
|
|
374
|
+
decision = {
|
|
375
|
+
type: "llm",
|
|
376
|
+
confidence: 1,
|
|
377
|
+
reasoning: "No relevant skills found, using LLM directly"
|
|
378
|
+
};
|
|
379
|
+
} else if (relevantSkills.length === 1 && relevantTools.length === 0) {
|
|
380
|
+
decision = {
|
|
381
|
+
type: "skill",
|
|
382
|
+
skills: [relevantSkills[0].name],
|
|
383
|
+
confidence: relevantSkills[0].confidence,
|
|
384
|
+
reasoning: `Single skill match: ${relevantSkills[0].name}`
|
|
385
|
+
};
|
|
386
|
+
} else if (relevantTools.length === 1 && relevantSkills.length === 0) {
|
|
387
|
+
decision = {
|
|
388
|
+
type: "tool",
|
|
389
|
+
tools: [relevantTools[0].name],
|
|
390
|
+
confidence: relevantTools[0].confidence,
|
|
391
|
+
reasoning: `Single tool match: ${relevantTools[0].name}`
|
|
392
|
+
};
|
|
393
|
+
} else {
|
|
394
|
+
const topSkills = relevantSkills.slice(0, this.config.maxSkills);
|
|
395
|
+
const topTools = relevantTools.slice(0, 2);
|
|
396
|
+
decision = {
|
|
397
|
+
type: "multi",
|
|
398
|
+
skills: topSkills.map((s) => s.name),
|
|
399
|
+
tools: topTools.map((t) => t.name),
|
|
400
|
+
confidence: Math.max(_nullishCoalesce(_optionalChain([topSkills, 'access', _32 => _32[0], 'optionalAccess', _33 => _33.confidence]), () => ( 0)), _nullishCoalesce(_optionalChain([topTools, 'access', _34 => _34[0], 'optionalAccess', _35 => _35.confidence]), () => ( 0))),
|
|
401
|
+
reasoning: `Multiple matches: ${topSkills.map((s) => s.name).join(", ")}`,
|
|
402
|
+
fallback: "llm"
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
if (this.config.enableCaching) {
|
|
406
|
+
this.decisionCache.set(cacheKey, decision);
|
|
407
|
+
if (this.decisionCache.size > 1e3) {
|
|
408
|
+
const firstKey = this.decisionCache.keys().next().value;
|
|
409
|
+
if (firstKey !== void 0) {
|
|
410
|
+
this.decisionCache.delete(firstKey);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return decision;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Find relevant skills using similarity matching
|
|
418
|
+
*/
|
|
419
|
+
async findRelevantSkills(context) {
|
|
420
|
+
if (!this.config.enableEmbeddings || this.skillEmbeddings.size === 0) {
|
|
421
|
+
return this.fallbackSkillMatching(context);
|
|
422
|
+
}
|
|
423
|
+
const inputEmbedding = await this.embeddingProvider.embed(context.input);
|
|
424
|
+
const results = [];
|
|
425
|
+
for (const [skillName, skillEmbedding] of this.skillEmbeddings) {
|
|
426
|
+
const similarity = this.embeddingProvider.similarity(inputEmbedding, skillEmbedding);
|
|
427
|
+
if (similarity >= this.config.similarityThreshold) {
|
|
428
|
+
results.push({ name: skillName, confidence: similarity });
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
results.sort((a, b) => b.confidence - a.confidence);
|
|
432
|
+
return results;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Fallback matching using keyword extraction
|
|
436
|
+
*/
|
|
437
|
+
fallbackSkillMatching(context) {
|
|
438
|
+
const inputKeywords = this.extractKeywordsFromText(context.input);
|
|
439
|
+
const results = [];
|
|
440
|
+
for (const skillName of context.availableSkills) {
|
|
441
|
+
const skillKeywords = skillName.toLowerCase().split(/[_-]/);
|
|
442
|
+
const matches = inputKeywords.filter(
|
|
443
|
+
(kw) => skillKeywords.some((sk) => sk.includes(kw) || kw.includes(sk))
|
|
444
|
+
);
|
|
445
|
+
if (matches.length > 0) {
|
|
446
|
+
const confidence = matches.length / Math.max(inputKeywords.length, skillKeywords.length);
|
|
447
|
+
if (confidence >= this.config.threshold) {
|
|
448
|
+
results.push({ name: skillName, confidence });
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
results.sort((a, b) => b.confidence - a.confidence);
|
|
453
|
+
return results;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Find relevant tools
|
|
457
|
+
*/
|
|
458
|
+
findRelevantTools(context) {
|
|
459
|
+
const inputKeywords = this.extractKeywordsFromText(context.input);
|
|
460
|
+
const results = [];
|
|
461
|
+
for (const toolName of context.availableTools) {
|
|
462
|
+
const toolKeywords = toolName.toLowerCase().split(/[_-]/);
|
|
463
|
+
const matches = inputKeywords.filter(
|
|
464
|
+
(kw) => toolKeywords.some((tk) => tk.includes(kw) || kw.includes(tk))
|
|
465
|
+
);
|
|
466
|
+
if (matches.length > 0) {
|
|
467
|
+
const confidence = matches.length / Math.max(inputKeywords.length, toolKeywords.length);
|
|
468
|
+
if (confidence >= this.config.threshold) {
|
|
469
|
+
results.push({ name: toolName, confidence });
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
results.sort((a, b) => b.confidence - a.confidence);
|
|
474
|
+
return results;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Extract keywords from skill
|
|
478
|
+
*/
|
|
479
|
+
extractKeywords(skill) {
|
|
480
|
+
const keywords = [
|
|
481
|
+
skill.name,
|
|
482
|
+
skill.description,
|
|
483
|
+
..._nullishCoalesce(_optionalChain([skill, 'access', _36 => _36.metadata, 'optionalAccess', _37 => _37.tags]), () => ( [])),
|
|
484
|
+
_nullishCoalesce(_optionalChain([skill, 'access', _38 => _38.metadata, 'optionalAccess', _39 => _39.category]), () => ( ""))
|
|
485
|
+
];
|
|
486
|
+
for (const [key, prop] of Object.entries(skill.parameters.properties)) {
|
|
487
|
+
keywords.push(key, prop.description);
|
|
488
|
+
}
|
|
489
|
+
return keywords.join(" ");
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Extract keywords from text
|
|
493
|
+
*/
|
|
494
|
+
extractKeywordsFromText(text) {
|
|
495
|
+
return text.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((t) => t.length > 2);
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Generate cache key
|
|
499
|
+
*/
|
|
500
|
+
generateCacheKey(context) {
|
|
501
|
+
return `${context.input}:${context.availableSkills.join(",")}:${context.availableTools.join(",")}`;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Clear cache
|
|
505
|
+
*/
|
|
506
|
+
clearCache() {
|
|
507
|
+
this.decisionCache.clear();
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Get cache stats
|
|
511
|
+
*/
|
|
512
|
+
getCacheStats() {
|
|
513
|
+
return { size: this.decisionCache.size };
|
|
514
|
+
}
|
|
515
|
+
}, _class3);
|
|
516
|
+
|
|
517
|
+
// src/core/skill-loader.ts
|
|
518
|
+
var DynamicSkillLoader = (_class4 = class {
|
|
519
|
+
__init13() {this.loadedSkills = /* @__PURE__ */ new Map()}
|
|
520
|
+
__init14() {this.skillCache = /* @__PURE__ */ new Map()}
|
|
521
|
+
__init15() {this.skillSources = /* @__PURE__ */ new Map()}
|
|
522
|
+
|
|
523
|
+
constructor(config = {}) {;_class4.prototype.__init13.call(this);_class4.prototype.__init14.call(this);_class4.prototype.__init15.call(this);
|
|
524
|
+
this.config = {
|
|
525
|
+
skillDirectory: _nullishCoalesce(config.skillDirectory, () => ( "./skills")),
|
|
526
|
+
enableLazyLoading: _nullishCoalesce(config.enableLazyLoading, () => ( true)),
|
|
527
|
+
enableCaching: _nullishCoalesce(config.enableCaching, () => ( true)),
|
|
528
|
+
cacheSize: _nullishCoalesce(config.cacheSize, () => ( 100)),
|
|
529
|
+
hotReload: _nullishCoalesce(config.hotReload, () => ( false))
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Register a skill source for lazy loading
|
|
534
|
+
*/
|
|
535
|
+
registerSource(source) {
|
|
536
|
+
this.skillSources.set(source.name, source);
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Load a skill dynamically
|
|
540
|
+
*/
|
|
541
|
+
async load(name) {
|
|
542
|
+
if (this.config.enableCaching) {
|
|
543
|
+
const cached = this.skillCache.get(name);
|
|
544
|
+
if (cached) return cached;
|
|
545
|
+
}
|
|
546
|
+
const loaded = this.loadedSkills.get(name);
|
|
547
|
+
if (loaded) {
|
|
548
|
+
return loaded;
|
|
549
|
+
}
|
|
550
|
+
const source = this.skillSources.get(name);
|
|
551
|
+
if (!source) {
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
let skill = null;
|
|
555
|
+
switch (source.type) {
|
|
556
|
+
case "builtin":
|
|
557
|
+
skill = await this.loadBuiltin(source);
|
|
558
|
+
break;
|
|
559
|
+
case "file":
|
|
560
|
+
skill = await this.loadFromFile(source);
|
|
561
|
+
break;
|
|
562
|
+
case "url":
|
|
563
|
+
skill = await this.loadFromUrl(source);
|
|
564
|
+
break;
|
|
565
|
+
case "module":
|
|
566
|
+
skill = await this.loadFromModule(source);
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
if (skill) {
|
|
570
|
+
if (this.config.enableCaching) {
|
|
571
|
+
this.skillCache.set(name, skill);
|
|
572
|
+
this.enforceCacheLimit();
|
|
573
|
+
}
|
|
574
|
+
const loadedSkill = {
|
|
575
|
+
...skill,
|
|
576
|
+
loadedAt: /* @__PURE__ */ new Date(),
|
|
577
|
+
source,
|
|
578
|
+
size: JSON.stringify(skill).length
|
|
579
|
+
};
|
|
580
|
+
this.loadedSkills.set(name, loadedSkill);
|
|
581
|
+
}
|
|
582
|
+
return skill;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Load multiple skills
|
|
586
|
+
*/
|
|
587
|
+
async loadMultiple(names) {
|
|
588
|
+
const results = /* @__PURE__ */ new Map();
|
|
589
|
+
await Promise.all(
|
|
590
|
+
names.map(async (name) => {
|
|
591
|
+
const skill = await this.load(name);
|
|
592
|
+
if (skill) {
|
|
593
|
+
results.set(name, skill);
|
|
594
|
+
}
|
|
595
|
+
})
|
|
596
|
+
);
|
|
597
|
+
return results;
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Unload a skill
|
|
601
|
+
*/
|
|
602
|
+
unload(name) {
|
|
603
|
+
this.skillCache.delete(name);
|
|
604
|
+
return this.loadedSkills.delete(name);
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Check if skill is loaded
|
|
608
|
+
*/
|
|
609
|
+
isLoaded(name) {
|
|
610
|
+
return this.loadedSkills.has(name) || this.skillCache.has(name);
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Get loaded skill info
|
|
614
|
+
*/
|
|
615
|
+
getLoadedSkill(name) {
|
|
616
|
+
return this.loadedSkills.get(name);
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* List all loaded skills
|
|
620
|
+
*/
|
|
621
|
+
listLoaded() {
|
|
622
|
+
return Array.from(this.loadedSkills.values());
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* List available skill sources
|
|
626
|
+
*/
|
|
627
|
+
listSources() {
|
|
628
|
+
return Array.from(this.skillSources.values());
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Preload skills (eager loading)
|
|
632
|
+
*/
|
|
633
|
+
async preload(names) {
|
|
634
|
+
await this.loadMultiple(names);
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Get memory usage stats
|
|
638
|
+
*/
|
|
639
|
+
getStats() {
|
|
640
|
+
const loaded = this.listLoaded();
|
|
641
|
+
return {
|
|
642
|
+
loaded: loaded.length,
|
|
643
|
+
cached: this.skillCache.size,
|
|
644
|
+
sources: this.skillSources.size,
|
|
645
|
+
totalSize: loaded.reduce((sum, s) => sum + (_nullishCoalesce(s.size, () => ( 0))), 0)
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Clear cache
|
|
650
|
+
*/
|
|
651
|
+
clearCache() {
|
|
652
|
+
this.skillCache.clear();
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Clear all loaded skills
|
|
656
|
+
*/
|
|
657
|
+
clear() {
|
|
658
|
+
this.loadedSkills.clear();
|
|
659
|
+
this.skillCache.clear();
|
|
660
|
+
}
|
|
661
|
+
// Private loading methods
|
|
662
|
+
async loadBuiltin(_source) {
|
|
663
|
+
return null;
|
|
664
|
+
}
|
|
665
|
+
async loadFromFile(source) {
|
|
666
|
+
if (typeof window !== "undefined") {
|
|
667
|
+
console.warn("File loading not supported in browser");
|
|
668
|
+
return null;
|
|
669
|
+
}
|
|
670
|
+
try {
|
|
671
|
+
const fs = await Promise.resolve().then(() => _interopRequireWildcard(require("fs/promises")));
|
|
672
|
+
const content = await fs.readFile(source.source, "utf-8");
|
|
673
|
+
const module = JSON.parse(content);
|
|
674
|
+
return this.validateSkill(module);
|
|
675
|
+
} catch (error) {
|
|
676
|
+
console.error(`Failed to load skill from file: ${source.source}`, error);
|
|
677
|
+
return null;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
async loadFromUrl(source) {
|
|
681
|
+
try {
|
|
682
|
+
const response = await fetch(source.source);
|
|
683
|
+
if (!response.ok) {
|
|
684
|
+
throw new Error(`HTTP ${response.status}`);
|
|
685
|
+
}
|
|
686
|
+
const module = await response.json();
|
|
687
|
+
return this.validateSkill(module);
|
|
688
|
+
} catch (error) {
|
|
689
|
+
console.error(`Failed to load skill from URL: ${source.source}`, error);
|
|
690
|
+
return null;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
async loadFromModule(source) {
|
|
694
|
+
try {
|
|
695
|
+
const module = await Promise.resolve().then(() => _interopRequireWildcard(require(source.source)));
|
|
696
|
+
const skill = module.default || module.skill || module;
|
|
697
|
+
return this.validateSkill(skill);
|
|
698
|
+
} catch (error) {
|
|
699
|
+
console.error(`Failed to load skill from module: ${source.source}`, error);
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
validateSkill(obj) {
|
|
704
|
+
if (typeof obj !== "object" || obj === null) return null;
|
|
705
|
+
const skill = obj;
|
|
706
|
+
if (typeof skill.name === "string" && typeof skill.description === "string" && typeof skill.parameters === "object" && typeof skill.handler === "function") {
|
|
707
|
+
return skill;
|
|
708
|
+
}
|
|
709
|
+
return null;
|
|
710
|
+
}
|
|
711
|
+
enforceCacheLimit() {
|
|
712
|
+
while (this.skillCache.size > this.config.cacheSize) {
|
|
713
|
+
const firstKey = this.skillCache.keys().next().value;
|
|
714
|
+
if (firstKey !== void 0) {
|
|
715
|
+
this.skillCache.delete(firstKey);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}, _class4);
|
|
720
|
+
|
|
721
|
+
// src/core/token-optimizer.ts
|
|
722
|
+
var TokenOptimizer = class {
|
|
723
|
+
|
|
724
|
+
constructor(config = {}) {
|
|
725
|
+
this.config = {
|
|
726
|
+
maxContextTokens: _nullishCoalesce(config.maxContextTokens, () => ( 4e3)),
|
|
727
|
+
maxSkillDescriptionLength: _nullishCoalesce(config.maxSkillDescriptionLength, () => ( 200)),
|
|
728
|
+
enableCompression: _nullishCoalesce(config.enableCompression, () => ( true)),
|
|
729
|
+
preserveSystemPrompt: _nullishCoalesce(config.preserveSystemPrompt, () => ( true))
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Optimize skills for minimal token usage
|
|
734
|
+
*/
|
|
735
|
+
optimizeSkills(skills, forQuery) {
|
|
736
|
+
if (!this.config.enableCompression) return skills;
|
|
737
|
+
return skills.map((skill) => this.compressSkill(skill, forQuery));
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Compress a single skill
|
|
741
|
+
*/
|
|
742
|
+
compressSkill(skill, forQuery) {
|
|
743
|
+
const compressed = {
|
|
744
|
+
...skill,
|
|
745
|
+
description: this.truncateDescription(skill.description),
|
|
746
|
+
parameters: this.compressParameters(skill.parameters)
|
|
747
|
+
};
|
|
748
|
+
if (forQuery && skill.metadata) {
|
|
749
|
+
const relevant = this.isMetadataRelevant(skill.metadata, forQuery);
|
|
750
|
+
if (!relevant) {
|
|
751
|
+
delete compressed.metadata;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
return compressed;
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Optimize tools for minimal token usage
|
|
758
|
+
*/
|
|
759
|
+
optimizeTools(tools) {
|
|
760
|
+
if (!this.config.enableCompression) return tools;
|
|
761
|
+
return tools.map((tool) => ({
|
|
762
|
+
...tool,
|
|
763
|
+
description: this.truncateDescription(tool.description),
|
|
764
|
+
parameters: tool.parameters ? this.compressParameters(tool.parameters) : void 0
|
|
765
|
+
}));
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Optimize messages for context window
|
|
769
|
+
*/
|
|
770
|
+
optimizeMessages(messages, maxTokens) {
|
|
771
|
+
const limit = _nullishCoalesce(maxTokens, () => ( this.config.maxContextTokens));
|
|
772
|
+
let totalTokens = this.estimateMessagesTokens(messages);
|
|
773
|
+
if (totalTokens <= limit) return messages;
|
|
774
|
+
const optimized = [];
|
|
775
|
+
let systemMessage = null;
|
|
776
|
+
if (this.config.preserveSystemPrompt) {
|
|
777
|
+
systemMessage = messages.find((m) => m.role === "system") || null;
|
|
778
|
+
if (systemMessage) {
|
|
779
|
+
optimized.push(systemMessage);
|
|
780
|
+
totalTokens -= this.estimateTokens(systemMessage.content);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
const recentMessages = messages.filter((m) => m.role !== "system").reverse();
|
|
784
|
+
for (const message of recentMessages) {
|
|
785
|
+
const messageTokens = this.estimateTokens(message.content);
|
|
786
|
+
if (totalTokens + messageTokens <= limit) {
|
|
787
|
+
optimized.unshift(message);
|
|
788
|
+
totalTokens += messageTokens;
|
|
789
|
+
} else {
|
|
790
|
+
break;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return optimized;
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Build optimized prompt with skills
|
|
797
|
+
*/
|
|
798
|
+
buildOptimizedPrompt(userInput, availableSkills, context) {
|
|
799
|
+
const parts = [];
|
|
800
|
+
if (context) {
|
|
801
|
+
parts.push(`Context: ${this.truncateDescription(context, 500)}`);
|
|
802
|
+
}
|
|
803
|
+
parts.push(`User: ${userInput}`);
|
|
804
|
+
if (availableSkills.length > 0) {
|
|
805
|
+
const skillDescriptions = availableSkills.map((skill) => this.formatSkillForPrompt(skill));
|
|
806
|
+
parts.push(`
|
|
807
|
+
Available skills:
|
|
808
|
+
${skillDescriptions.join("\n")}`);
|
|
809
|
+
}
|
|
810
|
+
return parts.join("\n\n");
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Estimate tokens for text
|
|
814
|
+
*/
|
|
815
|
+
estimateTokens(text) {
|
|
816
|
+
return Math.ceil(text.length / 4);
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Estimate tokens for messages
|
|
820
|
+
*/
|
|
821
|
+
estimateMessagesTokens(messages) {
|
|
822
|
+
return messages.reduce((total, msg) => {
|
|
823
|
+
const baseTokens = 4;
|
|
824
|
+
return total + baseTokens + this.estimateTokens(msg.content);
|
|
825
|
+
}, 0);
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Estimate tokens for skills
|
|
829
|
+
*/
|
|
830
|
+
estimateSkillsTokens(skills) {
|
|
831
|
+
return skills.reduce((total, skill) => {
|
|
832
|
+
return total + this.estimateTokens(skill.name) + this.estimateTokens(skill.description) + this.estimateTokens(JSON.stringify(skill.parameters));
|
|
833
|
+
}, 0);
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Get optimization stats
|
|
837
|
+
*/
|
|
838
|
+
getOptimizationStats(original, optimized) {
|
|
839
|
+
const originalTokens = this.estimateSkillsTokens(original);
|
|
840
|
+
const optimizedTokens = this.estimateSkillsTokens(optimized);
|
|
841
|
+
const savings = originalTokens - optimizedTokens;
|
|
842
|
+
return {
|
|
843
|
+
originalTokens,
|
|
844
|
+
optimizedTokens,
|
|
845
|
+
savings,
|
|
846
|
+
savingsPercent: originalTokens > 0 ? savings / originalTokens * 100 : 0
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
// Private helper methods
|
|
850
|
+
truncateDescription(description, maxLength) {
|
|
851
|
+
const limit = _nullishCoalesce(maxLength, () => ( this.config.maxSkillDescriptionLength));
|
|
852
|
+
if (description.length <= limit) return description;
|
|
853
|
+
return description.substring(0, limit - 3) + "...";
|
|
854
|
+
}
|
|
855
|
+
compressParameters(parameters) {
|
|
856
|
+
const compressed = {
|
|
857
|
+
type: parameters.type,
|
|
858
|
+
properties: {}
|
|
859
|
+
};
|
|
860
|
+
if (parameters.required) {
|
|
861
|
+
compressed.required = parameters.required;
|
|
862
|
+
}
|
|
863
|
+
for (const [key, prop] of Object.entries(parameters.properties)) {
|
|
864
|
+
compressed.properties[key] = {
|
|
865
|
+
type: prop.type,
|
|
866
|
+
description: this.truncateDescription(prop.description, 100),
|
|
867
|
+
...prop.enum && { enum: prop.enum },
|
|
868
|
+
...prop.default !== void 0 && { default: prop.default }
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
return compressed;
|
|
872
|
+
}
|
|
873
|
+
isMetadataRelevant(metadata, query) {
|
|
874
|
+
if (!metadata) return false;
|
|
875
|
+
const queryLower = query.toLowerCase();
|
|
876
|
+
const metadataStr = JSON.stringify(metadata).toLowerCase();
|
|
877
|
+
return metadataStr.includes(queryLower);
|
|
878
|
+
}
|
|
879
|
+
formatSkillForPrompt(skill) {
|
|
880
|
+
const params = Object.keys(skill.parameters.properties).join(", ");
|
|
881
|
+
return `- ${skill.name}(${params}): ${skill.description}`;
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
// src/core/evaluation-engine.ts
|
|
886
|
+
var ExactMatchEvaluator = (_class5 = class {constructor() { _class5.prototype.__init16.call(this); }
|
|
887
|
+
__init16() {this.name = "exact"}
|
|
888
|
+
async evaluate(result, context) {
|
|
889
|
+
if (context.expectedOutput === void 0) {
|
|
890
|
+
return {
|
|
891
|
+
overall: 0.5,
|
|
892
|
+
correctness: 0.5,
|
|
893
|
+
completeness: 0.5,
|
|
894
|
+
relevance: 0.5,
|
|
895
|
+
details: [{
|
|
896
|
+
category: "exact_match",
|
|
897
|
+
score: 0.5,
|
|
898
|
+
message: "No expected output provided for comparison"
|
|
899
|
+
}]
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
const isMatch = JSON.stringify(result) === JSON.stringify(context.expectedOutput);
|
|
903
|
+
const score = isMatch ? 1 : 0;
|
|
904
|
+
return {
|
|
905
|
+
overall: score,
|
|
906
|
+
correctness: score,
|
|
907
|
+
completeness: score,
|
|
908
|
+
relevance: score,
|
|
909
|
+
details: [{
|
|
910
|
+
category: "exact_match",
|
|
911
|
+
score,
|
|
912
|
+
message: isMatch ? "Result matches expected output exactly" : "Result does not match expected output",
|
|
913
|
+
suggestion: isMatch ? void 0 : "Check output format and values"
|
|
914
|
+
}]
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
}, _class5);
|
|
918
|
+
var SemanticEvaluator = (_class6 = class {constructor() { _class6.prototype.__init17.call(this); }
|
|
919
|
+
__init17() {this.name = "semantic"}
|
|
920
|
+
async evaluate(result, context) {
|
|
921
|
+
const resultStr = JSON.stringify(result).toLowerCase();
|
|
922
|
+
const inputStr = context.originalInput.toLowerCase();
|
|
923
|
+
const inputKeywords = this.extractKeywords(inputStr);
|
|
924
|
+
const resultKeywords = this.extractKeywords(resultStr);
|
|
925
|
+
const matchingKeywords = inputKeywords.filter(
|
|
926
|
+
(kw) => resultKeywords.some((rkw) => rkw.includes(kw) || kw.includes(rkw))
|
|
927
|
+
);
|
|
928
|
+
const relevanceScore = inputKeywords.length > 0 ? matchingKeywords.length / inputKeywords.length : 0.5;
|
|
929
|
+
const completenessScore = this.assessCompleteness(result);
|
|
930
|
+
return {
|
|
931
|
+
overall: (relevanceScore + completenessScore) / 2,
|
|
932
|
+
correctness: relevanceScore,
|
|
933
|
+
completeness: completenessScore,
|
|
934
|
+
relevance: relevanceScore,
|
|
935
|
+
details: [
|
|
936
|
+
{
|
|
937
|
+
category: "semantic_relevance",
|
|
938
|
+
score: relevanceScore,
|
|
939
|
+
message: `Matched ${matchingKeywords.length}/${inputKeywords.length} keywords`
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
category: "completeness",
|
|
943
|
+
score: completenessScore,
|
|
944
|
+
message: completenessScore > 0.8 ? "Result appears complete" : "Result may be incomplete"
|
|
945
|
+
}
|
|
946
|
+
]
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
extractKeywords(text) {
|
|
950
|
+
return text.replace(/[^\w\s]/g, " ").split(/\s+/).filter((w) => w.length > 2).filter((w) => !this.isStopWord(w));
|
|
951
|
+
}
|
|
952
|
+
isStopWord(word) {
|
|
953
|
+
const stopWords = /* @__PURE__ */ new Set([
|
|
954
|
+
"the",
|
|
955
|
+
"a",
|
|
956
|
+
"an",
|
|
957
|
+
"is",
|
|
958
|
+
"are",
|
|
959
|
+
"was",
|
|
960
|
+
"were",
|
|
961
|
+
"be",
|
|
962
|
+
"been",
|
|
963
|
+
"have",
|
|
964
|
+
"has",
|
|
965
|
+
"had",
|
|
966
|
+
"do",
|
|
967
|
+
"does",
|
|
968
|
+
"did",
|
|
969
|
+
"will",
|
|
970
|
+
"would",
|
|
971
|
+
"could",
|
|
972
|
+
"should",
|
|
973
|
+
"may",
|
|
974
|
+
"might",
|
|
975
|
+
"must",
|
|
976
|
+
"shall",
|
|
977
|
+
"can",
|
|
978
|
+
"need",
|
|
979
|
+
"dare",
|
|
980
|
+
"ought",
|
|
981
|
+
"used",
|
|
982
|
+
"to",
|
|
983
|
+
"of",
|
|
984
|
+
"in",
|
|
985
|
+
"for",
|
|
986
|
+
"on",
|
|
987
|
+
"with",
|
|
988
|
+
"at",
|
|
989
|
+
"by",
|
|
990
|
+
"from",
|
|
991
|
+
"as",
|
|
992
|
+
"into",
|
|
993
|
+
"through",
|
|
994
|
+
"during",
|
|
995
|
+
"before",
|
|
996
|
+
"after",
|
|
997
|
+
"above",
|
|
998
|
+
"below",
|
|
999
|
+
"between",
|
|
1000
|
+
"and",
|
|
1001
|
+
"but",
|
|
1002
|
+
"or",
|
|
1003
|
+
"yet",
|
|
1004
|
+
"so",
|
|
1005
|
+
"if",
|
|
1006
|
+
"because",
|
|
1007
|
+
"although",
|
|
1008
|
+
"though",
|
|
1009
|
+
"while",
|
|
1010
|
+
"where",
|
|
1011
|
+
"when",
|
|
1012
|
+
"that",
|
|
1013
|
+
"which",
|
|
1014
|
+
"who",
|
|
1015
|
+
"whom",
|
|
1016
|
+
"whose",
|
|
1017
|
+
"what",
|
|
1018
|
+
"this",
|
|
1019
|
+
"these",
|
|
1020
|
+
"those",
|
|
1021
|
+
"i",
|
|
1022
|
+
"you",
|
|
1023
|
+
"he",
|
|
1024
|
+
"she",
|
|
1025
|
+
"it",
|
|
1026
|
+
"we",
|
|
1027
|
+
"they",
|
|
1028
|
+
"me",
|
|
1029
|
+
"him",
|
|
1030
|
+
"her",
|
|
1031
|
+
"us",
|
|
1032
|
+
"them",
|
|
1033
|
+
"my",
|
|
1034
|
+
"your",
|
|
1035
|
+
"his",
|
|
1036
|
+
"its",
|
|
1037
|
+
"our",
|
|
1038
|
+
"their"
|
|
1039
|
+
]);
|
|
1040
|
+
return stopWords.has(word.toLowerCase());
|
|
1041
|
+
}
|
|
1042
|
+
assessCompleteness(result) {
|
|
1043
|
+
if (result === null || result === void 0) return 0;
|
|
1044
|
+
if (typeof result === "string") {
|
|
1045
|
+
return result.length > 10 ? 0.8 : 0.5;
|
|
1046
|
+
}
|
|
1047
|
+
if (typeof result === "object" && result !== null) {
|
|
1048
|
+
const keys = Object.keys(result);
|
|
1049
|
+
if (keys.length === 0) return 0.3;
|
|
1050
|
+
if (keys.length >= 3) return 0.9;
|
|
1051
|
+
return 0.6;
|
|
1052
|
+
}
|
|
1053
|
+
return 0.7;
|
|
1054
|
+
}
|
|
1055
|
+
}, _class6);
|
|
1056
|
+
var SchemaValidator = (_class7 = class {constructor() { _class7.prototype.__init18.call(this); }
|
|
1057
|
+
__init18() {this.name = "schema"}
|
|
1058
|
+
async evaluate(result, context) {
|
|
1059
|
+
if (!context.expectedSchema) {
|
|
1060
|
+
return {
|
|
1061
|
+
overall: 0.5,
|
|
1062
|
+
correctness: 0.5,
|
|
1063
|
+
completeness: 0.5,
|
|
1064
|
+
relevance: 0.5,
|
|
1065
|
+
details: [{
|
|
1066
|
+
category: "schema_validation",
|
|
1067
|
+
score: 0.5,
|
|
1068
|
+
message: "No schema provided for validation"
|
|
1069
|
+
}]
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
const validation = this.validateAgainstSchema(result, context.expectedSchema);
|
|
1073
|
+
return {
|
|
1074
|
+
overall: validation.score,
|
|
1075
|
+
correctness: validation.score,
|
|
1076
|
+
completeness: validation.score,
|
|
1077
|
+
relevance: validation.score,
|
|
1078
|
+
details: validation.errors.map((err) => ({
|
|
1079
|
+
category: "schema_validation",
|
|
1080
|
+
score: 0,
|
|
1081
|
+
message: err
|
|
1082
|
+
}))
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
validateAgainstSchema(result, schema) {
|
|
1086
|
+
const errors = [];
|
|
1087
|
+
if (typeof schema !== "object" || schema === null) {
|
|
1088
|
+
return { score: 1, errors: [] };
|
|
1089
|
+
}
|
|
1090
|
+
const schemaObj = schema;
|
|
1091
|
+
if (schemaObj.type && typeof schemaObj.type === "string" && typeof result !== schemaObj.type) {
|
|
1092
|
+
errors.push(`Expected type ${schemaObj.type}, got ${typeof result}`);
|
|
1093
|
+
}
|
|
1094
|
+
if (schemaObj.required && Array.isArray(schemaObj.required)) {
|
|
1095
|
+
if (typeof result === "object" && result !== null) {
|
|
1096
|
+
const resultObj = result;
|
|
1097
|
+
for (const prop of schemaObj.required) {
|
|
1098
|
+
if (!(prop in resultObj)) {
|
|
1099
|
+
errors.push(`Missing required property: ${prop}`);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
if (schemaObj.properties && typeof result === "object" && result !== null) {
|
|
1105
|
+
const resultObj = result;
|
|
1106
|
+
const properties = schemaObj.properties;
|
|
1107
|
+
for (const [key, propSchema] of Object.entries(properties)) {
|
|
1108
|
+
if (key in resultObj) {
|
|
1109
|
+
const propValidation = this.validateAgainstSchema(resultObj[key], propSchema);
|
|
1110
|
+
errors.push(...propValidation.errors);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
const score = errors.length === 0 ? 1 : Math.max(0, 1 - errors.length * 0.2);
|
|
1115
|
+
return { score, errors };
|
|
1116
|
+
}
|
|
1117
|
+
}, _class7);
|
|
1118
|
+
var EvaluationEngine = (_class8 = class {
|
|
1119
|
+
|
|
1120
|
+
__init19() {this.evaluators = /* @__PURE__ */ new Map()}
|
|
1121
|
+
__init20() {this.evaluationHistory = []}
|
|
1122
|
+
constructor(config = {}) {;_class8.prototype.__init19.call(this);_class8.prototype.__init20.call(this);
|
|
1123
|
+
this.config = {
|
|
1124
|
+
enabled: _nullishCoalesce(config.enabled, () => ( true)),
|
|
1125
|
+
level: _nullishCoalesce(config.level, () => ( "standard")),
|
|
1126
|
+
strategies: _nullishCoalesce(config.strategies, () => ( ["semantic"])),
|
|
1127
|
+
threshold: _nullishCoalesce(config.threshold, () => ( 0.7)),
|
|
1128
|
+
autoRetry: _nullishCoalesce(config.autoRetry, () => ( false)),
|
|
1129
|
+
maxRetries: _nullishCoalesce(config.maxRetries, () => ( 3)),
|
|
1130
|
+
customValidator: config.customValidator
|
|
1131
|
+
};
|
|
1132
|
+
this.registerBuiltInEvaluators();
|
|
1133
|
+
}
|
|
1134
|
+
registerBuiltInEvaluators() {
|
|
1135
|
+
this.evaluators.set("exact", new ExactMatchEvaluator());
|
|
1136
|
+
this.evaluators.set("semantic", new SemanticEvaluator());
|
|
1137
|
+
this.evaluators.set("schema", new SchemaValidator());
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Evaluate execution result
|
|
1141
|
+
*/
|
|
1142
|
+
async evaluate(result, context) {
|
|
1143
|
+
if (!this.config.enabled || this.config.level === "none") {
|
|
1144
|
+
return this.createPassThroughResult(result);
|
|
1145
|
+
}
|
|
1146
|
+
const startTime = Date.now();
|
|
1147
|
+
let tokensUsed = 0;
|
|
1148
|
+
const scores = [];
|
|
1149
|
+
for (const strategy of this.config.strategies) {
|
|
1150
|
+
const evaluator = this.evaluators.get(strategy);
|
|
1151
|
+
if (evaluator) {
|
|
1152
|
+
const score = await evaluator.evaluate(result.data, context);
|
|
1153
|
+
scores.push(score);
|
|
1154
|
+
tokensUsed += 50;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
if (this.config.customValidator) {
|
|
1158
|
+
const customScore = this.config.customValidator(result.data, context.expectedOutput);
|
|
1159
|
+
scores.push(customScore);
|
|
1160
|
+
}
|
|
1161
|
+
const finalScore = this.aggregateScores(scores);
|
|
1162
|
+
const passed = this.determinePassFail(finalScore);
|
|
1163
|
+
const evaluationResult = {
|
|
1164
|
+
passed,
|
|
1165
|
+
score: finalScore,
|
|
1166
|
+
feedback: this.generateFeedback(finalScore, passed),
|
|
1167
|
+
suggestions: this.generateSuggestions(finalScore),
|
|
1168
|
+
metadata: {
|
|
1169
|
+
executionTime: Date.now() - startTime,
|
|
1170
|
+
tokensUsed,
|
|
1171
|
+
strategyUsed: this.config.strategies[0]
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
this.evaluationHistory.push({
|
|
1175
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1176
|
+
result: evaluationResult,
|
|
1177
|
+
context
|
|
1178
|
+
});
|
|
1179
|
+
if (this.evaluationHistory.length > 1e3) {
|
|
1180
|
+
this.evaluationHistory = this.evaluationHistory.slice(-500);
|
|
1181
|
+
}
|
|
1182
|
+
return evaluationResult;
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Evaluate full execution result
|
|
1186
|
+
*/
|
|
1187
|
+
async evaluateExecution(executionResult, context) {
|
|
1188
|
+
if (!this.config.enabled || this.config.level === "none") {
|
|
1189
|
+
return this.createPassThroughResult(executionResult.finalOutput);
|
|
1190
|
+
}
|
|
1191
|
+
const stepEvaluations = [];
|
|
1192
|
+
for (const stepResult of executionResult.stepResults) {
|
|
1193
|
+
if (stepResult.output !== void 0) {
|
|
1194
|
+
const stepContext = {
|
|
1195
|
+
...context,
|
|
1196
|
+
executionHistory: executionResult.stepResults.slice(0, -1)
|
|
1197
|
+
};
|
|
1198
|
+
const score = await this.evaluateStep(stepResult, stepContext);
|
|
1199
|
+
stepEvaluations.push(score);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
const finalScore = await this.evaluateFinalOutput(
|
|
1203
|
+
executionResult.finalOutput,
|
|
1204
|
+
context
|
|
1205
|
+
);
|
|
1206
|
+
const allScores = [...stepEvaluations, finalScore];
|
|
1207
|
+
const aggregatedScore = this.aggregateScores(allScores);
|
|
1208
|
+
const passed = this.determinePassFail(aggregatedScore);
|
|
1209
|
+
return {
|
|
1210
|
+
passed,
|
|
1211
|
+
score: aggregatedScore,
|
|
1212
|
+
feedback: this.generateFeedback(aggregatedScore, passed),
|
|
1213
|
+
suggestions: this.generateSuggestions(aggregatedScore),
|
|
1214
|
+
metadata: {
|
|
1215
|
+
executionTime: executionResult.metrics.totalTime,
|
|
1216
|
+
tokensUsed: executionResult.metrics.totalTokens,
|
|
1217
|
+
strategyUsed: this.config.strategies[0]
|
|
1218
|
+
}
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
async evaluateStep(stepResult, context) {
|
|
1222
|
+
const evaluator = this.evaluators.get(this.config.strategies[0]);
|
|
1223
|
+
if (!evaluator) {
|
|
1224
|
+
return this.createDefaultScore();
|
|
1225
|
+
}
|
|
1226
|
+
return evaluator.evaluate(stepResult.output, context);
|
|
1227
|
+
}
|
|
1228
|
+
async evaluateFinalOutput(output, context) {
|
|
1229
|
+
const evaluator = this.evaluators.get(this.config.strategies[0]);
|
|
1230
|
+
if (!evaluator) {
|
|
1231
|
+
return this.createDefaultScore();
|
|
1232
|
+
}
|
|
1233
|
+
return evaluator.evaluate(output, context);
|
|
1234
|
+
}
|
|
1235
|
+
aggregateScores(scores) {
|
|
1236
|
+
if (scores.length === 0) {
|
|
1237
|
+
return this.createDefaultScore();
|
|
1238
|
+
}
|
|
1239
|
+
if (scores.length === 1) {
|
|
1240
|
+
return scores[0];
|
|
1241
|
+
}
|
|
1242
|
+
const weights = this.getLevelWeights();
|
|
1243
|
+
const overall = this.weightedAverage(scores.map((s) => s.overall), weights);
|
|
1244
|
+
const correctness = this.weightedAverage(scores.map((s) => s.correctness), weights);
|
|
1245
|
+
const completeness = this.weightedAverage(scores.map((s) => s.completeness), weights);
|
|
1246
|
+
const relevance = this.weightedAverage(scores.map((s) => s.relevance), weights);
|
|
1247
|
+
const allDetails = scores.flatMap((s) => s.details);
|
|
1248
|
+
return {
|
|
1249
|
+
overall,
|
|
1250
|
+
correctness,
|
|
1251
|
+
completeness,
|
|
1252
|
+
relevance,
|
|
1253
|
+
details: allDetails
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
getLevelWeights() {
|
|
1257
|
+
switch (this.config.level) {
|
|
1258
|
+
case "basic":
|
|
1259
|
+
return [0.6, 0.4];
|
|
1260
|
+
case "strict":
|
|
1261
|
+
return [0.5, 0.3, 0.2];
|
|
1262
|
+
case "standard":
|
|
1263
|
+
default:
|
|
1264
|
+
return [0.5, 0.5];
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
weightedAverage(values, weights) {
|
|
1268
|
+
const sum = values.reduce((acc, val, i) => acc + val * (_nullishCoalesce(weights[i], () => ( 0.5))), 0);
|
|
1269
|
+
const weightSum = weights.slice(0, values.length).reduce((a, b) => a + b, 0);
|
|
1270
|
+
return weightSum > 0 ? sum / weightSum : sum;
|
|
1271
|
+
}
|
|
1272
|
+
determinePassFail(score) {
|
|
1273
|
+
const threshold = _nullishCoalesce(this.config.threshold, () => ( 0.7));
|
|
1274
|
+
switch (this.config.level) {
|
|
1275
|
+
case "basic":
|
|
1276
|
+
return score.overall >= threshold * 0.8;
|
|
1277
|
+
case "strict":
|
|
1278
|
+
return score.overall >= threshold && score.correctness >= threshold && score.completeness >= threshold;
|
|
1279
|
+
case "standard":
|
|
1280
|
+
default:
|
|
1281
|
+
return score.overall >= threshold;
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
generateFeedback(score, passed) {
|
|
1285
|
+
if (passed) {
|
|
1286
|
+
if (score.overall >= 0.9) {
|
|
1287
|
+
return "Excellent result! High quality output with strong correctness and completeness.";
|
|
1288
|
+
} else if (score.overall >= 0.8) {
|
|
1289
|
+
return "Good result. Output meets expectations with minor room for improvement.";
|
|
1290
|
+
} else {
|
|
1291
|
+
return "Acceptable result. Output is usable but could be improved.";
|
|
1292
|
+
}
|
|
1293
|
+
} else {
|
|
1294
|
+
if (score.correctness < this.config.threshold) {
|
|
1295
|
+
return "Result failed correctness check. Please review the output for accuracy.";
|
|
1296
|
+
} else if (score.completeness < this.config.threshold) {
|
|
1297
|
+
return "Result appears incomplete. Consider providing more comprehensive output.";
|
|
1298
|
+
} else {
|
|
1299
|
+
return "Result does not meet quality standards. Please review and retry.";
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
generateSuggestions(score) {
|
|
1304
|
+
const suggestions = [];
|
|
1305
|
+
if (score.correctness < 0.7) {
|
|
1306
|
+
suggestions.push("Verify output accuracy against expected results");
|
|
1307
|
+
}
|
|
1308
|
+
if (score.completeness < 0.7) {
|
|
1309
|
+
suggestions.push("Include more details or missing information in the output");
|
|
1310
|
+
}
|
|
1311
|
+
if (score.relevance < 0.7) {
|
|
1312
|
+
suggestions.push("Ensure output directly addresses the input query");
|
|
1313
|
+
}
|
|
1314
|
+
for (const detail of score.details) {
|
|
1315
|
+
if (detail.suggestion && detail.score < 0.7) {
|
|
1316
|
+
suggestions.push(detail.suggestion);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
return [...new Set(suggestions)];
|
|
1320
|
+
}
|
|
1321
|
+
createPassThroughResult(_result) {
|
|
1322
|
+
return {
|
|
1323
|
+
passed: true,
|
|
1324
|
+
score: {
|
|
1325
|
+
overall: 1,
|
|
1326
|
+
correctness: 1,
|
|
1327
|
+
completeness: 1,
|
|
1328
|
+
relevance: 1,
|
|
1329
|
+
details: [{
|
|
1330
|
+
category: "evaluation_disabled",
|
|
1331
|
+
score: 1,
|
|
1332
|
+
message: "Evaluation is disabled, passing through"
|
|
1333
|
+
}]
|
|
1334
|
+
},
|
|
1335
|
+
feedback: "Evaluation disabled. Result passed through without validation.",
|
|
1336
|
+
suggestions: [],
|
|
1337
|
+
metadata: {
|
|
1338
|
+
executionTime: 0,
|
|
1339
|
+
tokensUsed: 0,
|
|
1340
|
+
strategyUsed: this.config.strategies[0]
|
|
1341
|
+
}
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
createDefaultScore() {
|
|
1345
|
+
return {
|
|
1346
|
+
overall: 0.5,
|
|
1347
|
+
correctness: 0.5,
|
|
1348
|
+
completeness: 0.5,
|
|
1349
|
+
relevance: 0.5,
|
|
1350
|
+
details: []
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
/**
|
|
1354
|
+
* Register custom evaluator
|
|
1355
|
+
*/
|
|
1356
|
+
registerEvaluator(strategy, evaluator) {
|
|
1357
|
+
this.evaluators.set(strategy, evaluator);
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Update configuration
|
|
1361
|
+
*/
|
|
1362
|
+
updateConfig(config) {
|
|
1363
|
+
this.config = { ...this.config, ...config };
|
|
1364
|
+
}
|
|
1365
|
+
/**
|
|
1366
|
+
* Get current configuration
|
|
1367
|
+
*/
|
|
1368
|
+
getConfig() {
|
|
1369
|
+
return { ...this.config };
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* Get evaluation statistics
|
|
1373
|
+
*/
|
|
1374
|
+
getStats() {
|
|
1375
|
+
const total = this.evaluationHistory.length;
|
|
1376
|
+
if (total === 0) {
|
|
1377
|
+
return {
|
|
1378
|
+
totalEvaluations: 0,
|
|
1379
|
+
passRate: 0,
|
|
1380
|
+
averageScore: 0,
|
|
1381
|
+
historySize: 0
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
const passed = this.evaluationHistory.filter((h) => h.result.passed).length;
|
|
1385
|
+
const avgScore = this.evaluationHistory.reduce((sum, h) => sum + h.result.score.overall, 0) / total;
|
|
1386
|
+
return {
|
|
1387
|
+
totalEvaluations: total,
|
|
1388
|
+
passRate: passed / total,
|
|
1389
|
+
averageScore: avgScore,
|
|
1390
|
+
historySize: this.evaluationHistory.length
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Clear evaluation history
|
|
1395
|
+
*/
|
|
1396
|
+
clearHistory() {
|
|
1397
|
+
this.evaluationHistory = [];
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Get recent evaluations
|
|
1401
|
+
*/
|
|
1402
|
+
getRecentEvaluations(limit = 10) {
|
|
1403
|
+
return this.evaluationHistory.slice(-limit).map((h) => ({
|
|
1404
|
+
timestamp: h.timestamp,
|
|
1405
|
+
passed: h.result.passed,
|
|
1406
|
+
score: h.result.score.overall,
|
|
1407
|
+
input: h.context.originalInput.substring(0, 100)
|
|
1408
|
+
}));
|
|
1409
|
+
}
|
|
1410
|
+
}, _class8);
|
|
1411
|
+
|
|
1412
|
+
// src/core/smart-agent.ts
|
|
1413
|
+
var SmartAgent = (_class9 = class extends Agent {
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
__init21() {this.executionHistory = []}
|
|
1419
|
+
constructor(config) {
|
|
1420
|
+
super(config);_class9.prototype.__init21.call(this);;
|
|
1421
|
+
this.decisionEngine = new DecisionEngine(config.decisionEngine);
|
|
1422
|
+
this.skillLoader = new DynamicSkillLoader(config.skillLoader);
|
|
1423
|
+
this.tokenOptimizer = new TokenOptimizer(config.tokenOptimizer);
|
|
1424
|
+
this.evaluationEngine = new EvaluationEngine(_nullishCoalesce(config.evaluation, () => ( { enabled: true, level: "standard", strategies: ["semantic"] })));
|
|
1425
|
+
void config.autoDecide;
|
|
1426
|
+
void config.maxAutoIterations;
|
|
1427
|
+
void config.enableStreaming;
|
|
1428
|
+
}
|
|
1429
|
+
/**
|
|
1430
|
+
* Initialize the smart agent
|
|
1431
|
+
*/
|
|
1432
|
+
async initialize() {
|
|
1433
|
+
await super.initialize();
|
|
1434
|
+
for (const skill of this.getAllSkills()) {
|
|
1435
|
+
await this.decisionEngine.indexSkill(skill);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Auto-process user input with smart decision making and evaluation
|
|
1440
|
+
*/
|
|
1441
|
+
async process(input, context) {
|
|
1442
|
+
const startTime = Date.now();
|
|
1443
|
+
const tokensUsed = 0;
|
|
1444
|
+
const decision = await this.makeDecision(input, context);
|
|
1445
|
+
const loadedSkills = [];
|
|
1446
|
+
if (decision.skills) {
|
|
1447
|
+
for (const skillName of decision.skills) {
|
|
1448
|
+
if (!this.getSkill(skillName)) {
|
|
1449
|
+
const skill = await this.skillLoader.load(skillName);
|
|
1450
|
+
if (skill) {
|
|
1451
|
+
this.registerSkill(skill);
|
|
1452
|
+
await this.decisionEngine.indexSkill(skill);
|
|
1453
|
+
loadedSkills.push(skillName);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
let result;
|
|
1459
|
+
let skillUsed;
|
|
1460
|
+
switch (decision.type) {
|
|
1461
|
+
case "skill":
|
|
1462
|
+
if (_optionalChain([decision, 'access', _40 => _40.skills, 'optionalAccess', _41 => _41.length]) === 1) {
|
|
1463
|
+
const skillName = decision.skills[0];
|
|
1464
|
+
skillUsed = this.getSkill(skillName);
|
|
1465
|
+
const params = await this.extractParameters(input, skillName);
|
|
1466
|
+
const skillResult = await this.executeSkill(skillName, params);
|
|
1467
|
+
result = skillResult.success ? String(_nullishCoalesce(skillResult.data, () => ( "Success"))) : String(_nullishCoalesce(skillResult.error, () => ( "Error")));
|
|
1468
|
+
} else {
|
|
1469
|
+
result = await this.coordinateSkills(input, decision.skills || []);
|
|
1470
|
+
}
|
|
1471
|
+
break;
|
|
1472
|
+
case "tool":
|
|
1473
|
+
if (_optionalChain([decision, 'access', _42 => _42.tools, 'optionalAccess', _43 => _43.length]) === 1) {
|
|
1474
|
+
const toolName = decision.tools[0];
|
|
1475
|
+
const toolResult = await this.executeTool(toolName, input);
|
|
1476
|
+
result = toolResult.isError ? String(_nullishCoalesce(_optionalChain([toolResult, 'access', _44 => _44.content, 'access', _45 => _45[0], 'optionalAccess', _46 => _46.text]), () => ( "Error"))) : String(_nullishCoalesce(_optionalChain([toolResult, 'access', _47 => _47.content, 'access', _48 => _48[0], 'optionalAccess', _49 => _49.text]), () => ( "Success")));
|
|
1477
|
+
} else {
|
|
1478
|
+
result = await this.coordinateTools(input, decision.tools || []);
|
|
1479
|
+
}
|
|
1480
|
+
break;
|
|
1481
|
+
case "multi":
|
|
1482
|
+
result = await this.executeMixed(input, decision);
|
|
1483
|
+
break;
|
|
1484
|
+
case "llm":
|
|
1485
|
+
default:
|
|
1486
|
+
result = await this.directLLMResponse(input, context);
|
|
1487
|
+
break;
|
|
1488
|
+
}
|
|
1489
|
+
let evaluation;
|
|
1490
|
+
const config = this.evaluationEngine.getConfig();
|
|
1491
|
+
if (config.enabled && config.level !== "none") {
|
|
1492
|
+
const skillResult = typeof result === "string" ? { success: true, data: result } : result;
|
|
1493
|
+
const evalContext = {
|
|
1494
|
+
originalInput: input,
|
|
1495
|
+
skill: skillUsed
|
|
1496
|
+
};
|
|
1497
|
+
evaluation = await this.evaluationEngine.evaluate(skillResult, evalContext);
|
|
1498
|
+
if (!evaluation.passed && config.autoRetry && config.maxRetries && config.maxRetries > 0) {
|
|
1499
|
+
const retryResult = await this.attemptRetry(input, context, decision, config.maxRetries);
|
|
1500
|
+
if (retryResult) {
|
|
1501
|
+
result = retryResult.result;
|
|
1502
|
+
evaluation = retryResult.evaluation;
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
this.executionHistory.push({
|
|
1507
|
+
input,
|
|
1508
|
+
decision,
|
|
1509
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1510
|
+
evaluation
|
|
1511
|
+
});
|
|
1512
|
+
const executionTime = Date.now() - startTime;
|
|
1513
|
+
return {
|
|
1514
|
+
decision,
|
|
1515
|
+
result,
|
|
1516
|
+
tokensUsed,
|
|
1517
|
+
executionTime,
|
|
1518
|
+
skillsLoaded: loadedSkills.length > 0 ? loadedSkills : void 0,
|
|
1519
|
+
evaluation
|
|
1520
|
+
};
|
|
1521
|
+
}
|
|
1522
|
+
/**
|
|
1523
|
+
* Attempt retry with improved parameters
|
|
1524
|
+
*/
|
|
1525
|
+
async attemptRetry(input, context, originalDecision, maxRetries) {
|
|
1526
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
1527
|
+
const retryDecision = {
|
|
1528
|
+
...originalDecision,
|
|
1529
|
+
reasoning: `${originalDecision.reasoning} (retry attempt ${attempt})`
|
|
1530
|
+
};
|
|
1531
|
+
let retryResult;
|
|
1532
|
+
switch (retryDecision.type) {
|
|
1533
|
+
case "skill":
|
|
1534
|
+
if (_optionalChain([retryDecision, 'access', _50 => _50.skills, 'optionalAccess', _51 => _51.length]) === 1) {
|
|
1535
|
+
const skillName = retryDecision.skills[0];
|
|
1536
|
+
const params = await this.extractParameters(input, skillName);
|
|
1537
|
+
const skillResult2 = await this.executeSkill(skillName, params);
|
|
1538
|
+
retryResult = skillResult2.success ? String(_nullishCoalesce(skillResult2.data, () => ( "Success"))) : String(_nullishCoalesce(skillResult2.error, () => ( "Error")));
|
|
1539
|
+
} else {
|
|
1540
|
+
retryResult = await this.coordinateSkills(input, retryDecision.skills || []);
|
|
1541
|
+
}
|
|
1542
|
+
break;
|
|
1543
|
+
case "llm":
|
|
1544
|
+
default:
|
|
1545
|
+
retryResult = await this.directLLMResponse(input, context);
|
|
1546
|
+
break;
|
|
1547
|
+
}
|
|
1548
|
+
const skillResult = typeof retryResult === "string" ? { success: true, data: retryResult } : retryResult;
|
|
1549
|
+
const evalContext = {
|
|
1550
|
+
originalInput: input
|
|
1551
|
+
};
|
|
1552
|
+
const evaluation = await this.evaluationEngine.evaluate(skillResult, evalContext);
|
|
1553
|
+
if (evaluation.passed) {
|
|
1554
|
+
return { result: retryResult, evaluation };
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
return null;
|
|
1558
|
+
}
|
|
1559
|
+
/**
|
|
1560
|
+
* Stream process user input with evaluation
|
|
1561
|
+
*/
|
|
1562
|
+
async *streamProcess(input, context) {
|
|
1563
|
+
const decision = await this.makeDecision(input, context);
|
|
1564
|
+
yield { type: "decision", data: decision };
|
|
1565
|
+
let result = "";
|
|
1566
|
+
let skillUsed;
|
|
1567
|
+
switch (decision.type) {
|
|
1568
|
+
case "skill":
|
|
1569
|
+
for (const skillName of decision.skills || []) {
|
|
1570
|
+
yield { type: "skill", data: { name: skillName, status: "executing" } };
|
|
1571
|
+
skillUsed = this.getSkill(skillName);
|
|
1572
|
+
const params = await this.extractParameters(input, skillName);
|
|
1573
|
+
const skillResult = await this.executeSkill(skillName, params);
|
|
1574
|
+
result = skillResult.success ? String(_nullishCoalesce(skillResult.data, () => ( "Success"))) : String(_nullishCoalesce(skillResult.error, () => ( "Error")));
|
|
1575
|
+
yield { type: "skill", data: { name: skillName, result } };
|
|
1576
|
+
}
|
|
1577
|
+
break;
|
|
1578
|
+
case "tool":
|
|
1579
|
+
for (const toolName of decision.tools || []) {
|
|
1580
|
+
yield { type: "tool", data: { name: toolName, status: "executing" } };
|
|
1581
|
+
const toolResult = await this.executeTool(toolName, input);
|
|
1582
|
+
result = toolResult.isError ? String(_nullishCoalesce(_optionalChain([toolResult, 'access', _52 => _52.content, 'access', _53 => _53[0], 'optionalAccess', _54 => _54.text]), () => ( "Error"))) : String(_nullishCoalesce(_optionalChain([toolResult, 'access', _55 => _55.content, 'access', _56 => _56[0], 'optionalAccess', _57 => _57.text]), () => ( "Success")));
|
|
1583
|
+
yield { type: "tool", data: { name: toolName, result } };
|
|
1584
|
+
}
|
|
1585
|
+
break;
|
|
1586
|
+
case "llm":
|
|
1587
|
+
yield { type: "llm", data: { status: "generating" } };
|
|
1588
|
+
const messages = [{ role: "user", content: input }];
|
|
1589
|
+
let fullResponse = "";
|
|
1590
|
+
for await (const chunk of this.streamChat(messages)) {
|
|
1591
|
+
if (chunk.delta.content) {
|
|
1592
|
+
fullResponse += chunk.delta.content;
|
|
1593
|
+
yield { type: "llm", data: { chunk: chunk.delta.content } };
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
result = fullResponse;
|
|
1597
|
+
break;
|
|
1598
|
+
}
|
|
1599
|
+
const config = this.evaluationEngine.getConfig();
|
|
1600
|
+
if (config.enabled && config.level !== "none") {
|
|
1601
|
+
const skillResult = typeof result === "string" ? { success: true, data: result } : result;
|
|
1602
|
+
const evalContext = {
|
|
1603
|
+
originalInput: input,
|
|
1604
|
+
skill: skillUsed
|
|
1605
|
+
};
|
|
1606
|
+
const evaluation = await this.evaluationEngine.evaluate(skillResult, evalContext);
|
|
1607
|
+
yield { type: "evaluation", data: evaluation };
|
|
1608
|
+
}
|
|
1609
|
+
yield { type: "complete" };
|
|
1610
|
+
}
|
|
1611
|
+
/**
|
|
1612
|
+
* Make decision based on input
|
|
1613
|
+
*/
|
|
1614
|
+
async makeDecision(input, context) {
|
|
1615
|
+
const decisionContext = {
|
|
1616
|
+
input,
|
|
1617
|
+
history: this.executionHistory.slice(-5).map((h) => h.input),
|
|
1618
|
+
availableSkills: this.getSkillNames(),
|
|
1619
|
+
availableTools: this.getToolNames(),
|
|
1620
|
+
metadata: context ? { context } : void 0
|
|
1621
|
+
};
|
|
1622
|
+
return this.decisionEngine.decide(decisionContext);
|
|
1623
|
+
}
|
|
1624
|
+
/**
|
|
1625
|
+
* Extract parameters from input for a skill
|
|
1626
|
+
*/
|
|
1627
|
+
async extractParameters(input, skillName) {
|
|
1628
|
+
const skill = this.getSkill(skillName);
|
|
1629
|
+
if (!skill) return {};
|
|
1630
|
+
if (this.llmProvider) {
|
|
1631
|
+
const prompt = this.buildParameterExtractionPrompt(input, skill);
|
|
1632
|
+
const response = await this.chat([{ role: "user", content: prompt }]);
|
|
1633
|
+
try {
|
|
1634
|
+
const params = JSON.parse(response.content);
|
|
1635
|
+
return params;
|
|
1636
|
+
} catch (e2) {
|
|
1637
|
+
return {};
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
return this.simpleParameterExtraction(input, skill);
|
|
1641
|
+
}
|
|
1642
|
+
/**
|
|
1643
|
+
* Coordinate multiple skills
|
|
1644
|
+
*/
|
|
1645
|
+
async coordinateSkills(input, skillNames) {
|
|
1646
|
+
const skills = skillNames.map((name) => this.getSkill(name)).filter((s) => s !== void 0);
|
|
1647
|
+
const optimizedSkills = this.tokenOptimizer.optimizeSkills(skills, input);
|
|
1648
|
+
if (!this.llmProvider) {
|
|
1649
|
+
const results = [];
|
|
1650
|
+
for (const skill of optimizedSkills) {
|
|
1651
|
+
const params = await this.extractParameters(input, skill.name);
|
|
1652
|
+
const result = await this.executeSkill(skill.name, params);
|
|
1653
|
+
results.push(`${skill.name}: ${result.success ? result.data : result.error}`);
|
|
1654
|
+
}
|
|
1655
|
+
return results.join("\n");
|
|
1656
|
+
}
|
|
1657
|
+
const prompt = this.tokenOptimizer.buildOptimizedPrompt(
|
|
1658
|
+
input,
|
|
1659
|
+
optimizedSkills,
|
|
1660
|
+
"Coordinate the following skills to answer the user query."
|
|
1661
|
+
);
|
|
1662
|
+
const response = await this.chat([{ role: "user", content: prompt }]);
|
|
1663
|
+
return response.content;
|
|
1664
|
+
}
|
|
1665
|
+
/**
|
|
1666
|
+
* Coordinate multiple tools
|
|
1667
|
+
*/
|
|
1668
|
+
async coordinateTools(input, toolNames) {
|
|
1669
|
+
const tools = toolNames.map((name) => this.getTool(name)).filter((t) => t !== void 0);
|
|
1670
|
+
const results = [];
|
|
1671
|
+
for (const tool of tools) {
|
|
1672
|
+
const result = await this.executeTool(tool.name, input);
|
|
1673
|
+
results.push(`${tool.name}: ${_nullishCoalesce(_optionalChain([result, 'access', _58 => _58.content, 'access', _59 => _59[0], 'optionalAccess', _60 => _60.text]), () => ( "No output"))}`);
|
|
1674
|
+
}
|
|
1675
|
+
return results.join("\n");
|
|
1676
|
+
}
|
|
1677
|
+
/**
|
|
1678
|
+
* Execute mixed skills and tools
|
|
1679
|
+
*/
|
|
1680
|
+
async executeMixed(input, decision) {
|
|
1681
|
+
const results = [];
|
|
1682
|
+
if (decision.skills) {
|
|
1683
|
+
for (const skillName of decision.skills) {
|
|
1684
|
+
const params = await this.extractParameters(input, skillName);
|
|
1685
|
+
const result = await this.executeSkill(skillName, params);
|
|
1686
|
+
results.push(`Skill ${skillName}: ${result.success ? result.data : result.error}`);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
if (decision.tools) {
|
|
1690
|
+
for (const toolName of decision.tools) {
|
|
1691
|
+
const result = await this.executeTool(toolName, input);
|
|
1692
|
+
results.push(`Tool ${toolName}: ${_nullishCoalesce(_optionalChain([result, 'access', _61 => _61.content, 'access', _62 => _62[0], 'optionalAccess', _63 => _63.text]), () => ( "No output"))}`);
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
return results.join("\n");
|
|
1696
|
+
}
|
|
1697
|
+
/**
|
|
1698
|
+
* Direct LLM response
|
|
1699
|
+
*/
|
|
1700
|
+
async directLLMResponse(input, context) {
|
|
1701
|
+
if (!this.llmProvider) {
|
|
1702
|
+
return "No LLM provider configured";
|
|
1703
|
+
}
|
|
1704
|
+
const messages = [];
|
|
1705
|
+
if (context) {
|
|
1706
|
+
messages.push({
|
|
1707
|
+
role: "system",
|
|
1708
|
+
content: `Context: ${context}`
|
|
1709
|
+
});
|
|
1710
|
+
}
|
|
1711
|
+
messages.push({ role: "user", content: input });
|
|
1712
|
+
const response = await this.chat(messages);
|
|
1713
|
+
return response.content;
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Build parameter extraction prompt
|
|
1717
|
+
*/
|
|
1718
|
+
buildParameterExtractionPrompt(input, skill) {
|
|
1719
|
+
const params = Object.entries(skill.parameters.properties).map(([key, prop]) => {
|
|
1720
|
+
const required = _optionalChain([skill, 'access', _64 => _64.parameters, 'access', _65 => _65.required, 'optionalAccess', _66 => _66.includes, 'call', _67 => _67(key)]) ? " (required)" : "";
|
|
1721
|
+
return `- ${key}: ${prop.description}${required}`;
|
|
1722
|
+
}).join("\n");
|
|
1723
|
+
return `Extract parameters for skill "${skill.name}" from the following input.
|
|
1724
|
+
|
|
1725
|
+
Skill description: ${skill.description}
|
|
1726
|
+
|
|
1727
|
+
Parameters:
|
|
1728
|
+
${params}
|
|
1729
|
+
|
|
1730
|
+
Input: "${input}"
|
|
1731
|
+
|
|
1732
|
+
Return only a JSON object with the parameter names and values. If a parameter cannot be determined, use null or omit it.`;
|
|
1733
|
+
}
|
|
1734
|
+
/**
|
|
1735
|
+
* Simple parameter extraction without LLM
|
|
1736
|
+
*/
|
|
1737
|
+
simpleParameterExtraction(input, skill) {
|
|
1738
|
+
const params = {};
|
|
1739
|
+
for (const [key, prop] of Object.entries(skill.parameters.properties)) {
|
|
1740
|
+
const patterns = [
|
|
1741
|
+
new RegExp(`${key}[:=]\\s*([^,\\s]+)`, "i"),
|
|
1742
|
+
new RegExp(`${key}\\s+is\\s+([^,\\s]+)`, "i"),
|
|
1743
|
+
new RegExp(`${key}\\s+([^,\\s]+)`, "i")
|
|
1744
|
+
];
|
|
1745
|
+
for (const pattern of patterns) {
|
|
1746
|
+
const match = input.match(pattern);
|
|
1747
|
+
if (match) {
|
|
1748
|
+
let value = match[1];
|
|
1749
|
+
if (prop.type === "number") {
|
|
1750
|
+
value = parseFloat(value);
|
|
1751
|
+
} else if (prop.type === "boolean") {
|
|
1752
|
+
value = ["true", "yes", "1"].includes(value.toLowerCase());
|
|
1753
|
+
}
|
|
1754
|
+
params[key] = value;
|
|
1755
|
+
break;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
if (!(key in params) && prop.default !== void 0) {
|
|
1759
|
+
params[key] = prop.default;
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
return params;
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Register a skill source for dynamic loading
|
|
1766
|
+
*/
|
|
1767
|
+
registerSkillSource(name, source, type) {
|
|
1768
|
+
this.skillLoader.registerSource({
|
|
1769
|
+
name,
|
|
1770
|
+
type,
|
|
1771
|
+
source
|
|
1772
|
+
});
|
|
1773
|
+
}
|
|
1774
|
+
/**
|
|
1775
|
+
* Get execution history
|
|
1776
|
+
*/
|
|
1777
|
+
getExecutionHistory() {
|
|
1778
|
+
return [...this.executionHistory];
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Get decision engine stats
|
|
1782
|
+
*/
|
|
1783
|
+
getDecisionStats() {
|
|
1784
|
+
return {
|
|
1785
|
+
cacheSize: this.decisionEngine.getCacheStats().size,
|
|
1786
|
+
loadedSkills: this.skillLoader.getStats().loaded,
|
|
1787
|
+
historySize: this.executionHistory.length
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
/**
|
|
1791
|
+
* Get evaluation stats
|
|
1792
|
+
*/
|
|
1793
|
+
getEvaluationStats() {
|
|
1794
|
+
const stats = this.evaluationEngine.getStats();
|
|
1795
|
+
const config = this.evaluationEngine.getConfig();
|
|
1796
|
+
return {
|
|
1797
|
+
...stats,
|
|
1798
|
+
config: {
|
|
1799
|
+
enabled: config.enabled,
|
|
1800
|
+
level: config.level
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
/**
|
|
1805
|
+
* Update evaluation configuration
|
|
1806
|
+
*/
|
|
1807
|
+
updateEvaluationConfig(config) {
|
|
1808
|
+
this.evaluationEngine.updateConfig(config);
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* Get evaluation configuration
|
|
1812
|
+
*/
|
|
1813
|
+
getEvaluationConfig() {
|
|
1814
|
+
return this.evaluationEngine.getConfig();
|
|
1815
|
+
}
|
|
1816
|
+
/**
|
|
1817
|
+
* Clear execution history
|
|
1818
|
+
*/
|
|
1819
|
+
clearHistory() {
|
|
1820
|
+
this.executionHistory = [];
|
|
1821
|
+
this.decisionEngine.clearCache();
|
|
1822
|
+
this.evaluationEngine.clearHistory();
|
|
1823
|
+
}
|
|
1824
|
+
/**
|
|
1825
|
+
* Get recent evaluations
|
|
1826
|
+
*/
|
|
1827
|
+
getRecentEvaluations(limit = 10) {
|
|
1828
|
+
return this.executionHistory.filter((h) => h.evaluation).slice(-limit).map((h) => ({
|
|
1829
|
+
timestamp: h.timestamp,
|
|
1830
|
+
passed: h.evaluation.passed,
|
|
1831
|
+
score: h.evaluation.score.overall,
|
|
1832
|
+
input: h.input.substring(0, 100),
|
|
1833
|
+
feedback: h.evaluation.feedback
|
|
1834
|
+
}));
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Generate evaluation report
|
|
1838
|
+
*/
|
|
1839
|
+
generateEvaluationReport() {
|
|
1840
|
+
const stats = this.evaluationEngine.getStats();
|
|
1841
|
+
const recent = this.getRecentEvaluations(10);
|
|
1842
|
+
const allSuggestions = this.executionHistory.filter((h) => h.evaluation).flatMap((h) => h.evaluation.suggestions);
|
|
1843
|
+
const uniqueSuggestions = [...new Set(allSuggestions)].slice(0, 10);
|
|
1844
|
+
return {
|
|
1845
|
+
summary: {
|
|
1846
|
+
totalExecutions: this.executionHistory.length,
|
|
1847
|
+
evaluatedExecutions: stats.totalEvaluations,
|
|
1848
|
+
passRate: stats.passRate,
|
|
1849
|
+
averageScore: stats.averageScore
|
|
1850
|
+
},
|
|
1851
|
+
recentEvaluations: recent,
|
|
1852
|
+
suggestions: uniqueSuggestions
|
|
1853
|
+
};
|
|
1854
|
+
}
|
|
1855
|
+
}, _class9);
|
|
1856
|
+
|
|
1857
|
+
// src/core/advanced-decision-engine.ts
|
|
1858
|
+
var AdvancedDecisionEngine = (_class10 = class {
|
|
1859
|
+
__init22() {this.skillEmbeddings = /* @__PURE__ */ new Map()}
|
|
1860
|
+
__init23() {this.intentPatterns = []}
|
|
1861
|
+
|
|
1862
|
+
__init24() {this.decisionCache = /* @__PURE__ */ new Map()}
|
|
1863
|
+
__init25() {this.executionHistory = []}
|
|
1864
|
+
|
|
1865
|
+
constructor(config = {}, embeddingProvider) {;_class10.prototype.__init22.call(this);_class10.prototype.__init23.call(this);_class10.prototype.__init24.call(this);_class10.prototype.__init25.call(this);
|
|
1866
|
+
this.config = {
|
|
1867
|
+
threshold: _nullishCoalesce(config.threshold, () => ( 0.6)),
|
|
1868
|
+
maxSkills: _nullishCoalesce(config.maxSkills, () => ( 3)),
|
|
1869
|
+
enableEmbeddings: _nullishCoalesce(config.enableEmbeddings, () => ( true)),
|
|
1870
|
+
enableCaching: _nullishCoalesce(config.enableCaching, () => ( true)),
|
|
1871
|
+
similarityThreshold: _nullishCoalesce(config.similarityThreshold, () => ( 0.5)),
|
|
1872
|
+
enableIntentClassification: _nullishCoalesce(config.enableIntentClassification, () => ( true)),
|
|
1873
|
+
enableContextualMemory: _nullishCoalesce(config.enableContextualMemory, () => ( true)),
|
|
1874
|
+
learningRate: _nullishCoalesce(config.learningRate, () => ( 0.1))
|
|
1875
|
+
};
|
|
1876
|
+
this.embeddingProvider = _nullishCoalesce(embeddingProvider, () => ( new SimpleEmbeddingProvider()));
|
|
1877
|
+
this.initializeIntentPatterns();
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Initialize common intent patterns
|
|
1881
|
+
*/
|
|
1882
|
+
initializeIntentPatterns() {
|
|
1883
|
+
this.intentPatterns = [
|
|
1884
|
+
{
|
|
1885
|
+
name: "calculation",
|
|
1886
|
+
patterns: [/calculate|compute|sum|add|subtract|multiply|divide/i],
|
|
1887
|
+
keywords: ["math", "calculate", "compute", "number", "sum", "total"],
|
|
1888
|
+
weight: 1,
|
|
1889
|
+
relatedSkills: ["math", "calculator", "arithmetic"]
|
|
1890
|
+
},
|
|
1891
|
+
{
|
|
1892
|
+
name: "data_processing",
|
|
1893
|
+
patterns: [/process|transform|convert|parse|extract/i],
|
|
1894
|
+
keywords: ["data", "process", "transform", "convert", "parse", "extract"],
|
|
1895
|
+
weight: 1,
|
|
1896
|
+
relatedSkills: ["data-processor", "transformer", "parser"]
|
|
1897
|
+
},
|
|
1898
|
+
{
|
|
1899
|
+
name: "document_analysis",
|
|
1900
|
+
patterns: [/analyze|read|extract|summarize.*document|pdf/i],
|
|
1901
|
+
keywords: ["document", "pdf", "analyze", "read", "extract", "text"],
|
|
1902
|
+
weight: 1,
|
|
1903
|
+
relatedSkills: ["pdf-processor", "document-reader", "text-extractor"]
|
|
1904
|
+
},
|
|
1905
|
+
{
|
|
1906
|
+
name: "search_query",
|
|
1907
|
+
patterns: [/search|find|lookup|query/i],
|
|
1908
|
+
keywords: ["search", "find", "lookup", "query", "retrieve"],
|
|
1909
|
+
weight: 0.9,
|
|
1910
|
+
relatedSkills: ["search", "retrieval", "lookup"]
|
|
1911
|
+
},
|
|
1912
|
+
{
|
|
1913
|
+
name: "generation",
|
|
1914
|
+
patterns: [/generate|create|write|compose|draft/i],
|
|
1915
|
+
keywords: ["generate", "create", "write", "compose", "draft", "produce"],
|
|
1916
|
+
weight: 0.9,
|
|
1917
|
+
relatedSkills: ["generator", "writer", "creator"]
|
|
1918
|
+
},
|
|
1919
|
+
{
|
|
1920
|
+
name: "comparison",
|
|
1921
|
+
patterns: [/compare|difference|versus|vs|better|best/i],
|
|
1922
|
+
keywords: ["compare", "difference", "versus", "contrast", "evaluate"],
|
|
1923
|
+
weight: 0.8,
|
|
1924
|
+
relatedSkills: ["comparator", "evaluator"]
|
|
1925
|
+
},
|
|
1926
|
+
{
|
|
1927
|
+
name: "information_retrieval",
|
|
1928
|
+
patterns: [/what is|how to|explain|tell me about|describe/i],
|
|
1929
|
+
keywords: ["information", "explain", "describe", "what", "how", "why"],
|
|
1930
|
+
weight: 0.7,
|
|
1931
|
+
relatedSkills: ["qa", "information-retrieval", "explainer"]
|
|
1932
|
+
}
|
|
1933
|
+
];
|
|
1934
|
+
}
|
|
1935
|
+
/**
|
|
1936
|
+
* Make advanced decision with full context analysis
|
|
1937
|
+
*/
|
|
1938
|
+
async decide(context, executionContext) {
|
|
1939
|
+
const cacheKey = this.generateCacheKey(context, executionContext);
|
|
1940
|
+
if (this.config.enableCaching) {
|
|
1941
|
+
const cached = this.decisionCache.get(cacheKey);
|
|
1942
|
+
if (cached) {
|
|
1943
|
+
return this.enrichDecisionWithContext(cached, executionContext);
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
const intentResult = this.config.enableIntentClassification ? this.classifyIntent(context.input) : { intent: "general", confidence: 0.5 };
|
|
1947
|
+
const relevantSkills = await this.findRelevantSkills(context, intentResult);
|
|
1948
|
+
const relevantTools = this.findRelevantTools(context, intentResult);
|
|
1949
|
+
const decision = await this.buildDecision(
|
|
1950
|
+
context,
|
|
1951
|
+
intentResult,
|
|
1952
|
+
relevantSkills,
|
|
1953
|
+
relevantTools,
|
|
1954
|
+
executionContext
|
|
1955
|
+
);
|
|
1956
|
+
if (this.config.enableCaching) {
|
|
1957
|
+
this.decisionCache.set(cacheKey, decision);
|
|
1958
|
+
this.limitCacheSize();
|
|
1959
|
+
}
|
|
1960
|
+
return decision;
|
|
1961
|
+
}
|
|
1962
|
+
/**
|
|
1963
|
+
* Classify user intent from input
|
|
1964
|
+
*/
|
|
1965
|
+
classifyIntent(input) {
|
|
1966
|
+
const scores = [];
|
|
1967
|
+
for (const pattern of this.intentPatterns) {
|
|
1968
|
+
let score = 0;
|
|
1969
|
+
for (const regex of pattern.patterns) {
|
|
1970
|
+
if (regex.test(input)) {
|
|
1971
|
+
score += pattern.weight * 0.6;
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
const inputLower = input.toLowerCase();
|
|
1975
|
+
const keywordMatches = pattern.keywords.filter((kw) => inputLower.includes(kw));
|
|
1976
|
+
score += keywordMatches.length / pattern.keywords.length * pattern.weight * 0.4;
|
|
1977
|
+
if (score > 0) {
|
|
1978
|
+
scores.push({ intent: pattern.name, score });
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
scores.sort((a, b) => b.score - a.score);
|
|
1982
|
+
if (scores.length === 0) {
|
|
1983
|
+
return { intent: "general", confidence: 0.3 };
|
|
1984
|
+
}
|
|
1985
|
+
const topScore = scores[0].score;
|
|
1986
|
+
const normalizedConfidence = Math.min(topScore / 0.8, 1);
|
|
1987
|
+
return {
|
|
1988
|
+
intent: scores[0].intent,
|
|
1989
|
+
confidence: normalizedConfidence
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
/**
|
|
1993
|
+
* Find relevant skills with intent boosting
|
|
1994
|
+
*/
|
|
1995
|
+
async findRelevantSkills(decisionContext, intentResult) {
|
|
1996
|
+
const results = [];
|
|
1997
|
+
const intentPattern = this.intentPatterns.find((p) => p.name === intentResult.intent);
|
|
1998
|
+
if (this.config.enableEmbeddings && this.skillEmbeddings.size > 0) {
|
|
1999
|
+
const inputEmbedding = await this.embeddingProvider.embed(decisionContext.input);
|
|
2000
|
+
for (const [skillName, skillEmbedding] of this.skillEmbeddings) {
|
|
2001
|
+
const similarity = this.embeddingProvider.similarity(inputEmbedding, skillEmbedding);
|
|
2002
|
+
let confidence = similarity;
|
|
2003
|
+
const reasons = [];
|
|
2004
|
+
if (_optionalChain([intentPattern, 'optionalAccess', _68 => _68.relatedSkills, 'access', _69 => _69.includes, 'call', _70 => _70(skillName)])) {
|
|
2005
|
+
confidence = Math.min(confidence * 1.3, 1);
|
|
2006
|
+
reasons.push(`Matches ${intentResult.intent} intent`);
|
|
2007
|
+
}
|
|
2008
|
+
if (confidence >= this.config.similarityThreshold) {
|
|
2009
|
+
results.push({ name: skillName, confidence, reasons });
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
} else {
|
|
2013
|
+
const inputKeywords = this.extractKeywordsFromText(decisionContext.input);
|
|
2014
|
+
for (const skillName of decisionContext.availableSkills) {
|
|
2015
|
+
const skillKeywords = skillName.toLowerCase().split(/[_-]/);
|
|
2016
|
+
const matches = inputKeywords.filter(
|
|
2017
|
+
(kw) => skillKeywords.some((sk) => sk.includes(kw) || kw.includes(sk))
|
|
2018
|
+
);
|
|
2019
|
+
if (matches.length > 0) {
|
|
2020
|
+
let confidence = matches.length / Math.max(inputKeywords.length, skillKeywords.length);
|
|
2021
|
+
const reasons = [`Keyword match: ${matches.join(", ")}`];
|
|
2022
|
+
if (_optionalChain([intentPattern, 'optionalAccess', _71 => _71.relatedSkills, 'access', _72 => _72.includes, 'call', _73 => _73(skillName)])) {
|
|
2023
|
+
confidence = Math.min(confidence * 1.3, 1);
|
|
2024
|
+
reasons.push(`Matches ${intentResult.intent} intent`);
|
|
2025
|
+
}
|
|
2026
|
+
if (confidence >= this.config.threshold) {
|
|
2027
|
+
results.push({ name: skillName, confidence, reasons });
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
results.sort((a, b) => b.confidence - a.confidence);
|
|
2033
|
+
return results;
|
|
2034
|
+
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Find relevant tools with intent consideration
|
|
2037
|
+
*/
|
|
2038
|
+
findRelevantTools(context, intentResult) {
|
|
2039
|
+
const inputKeywords = this.extractKeywordsFromText(context.input);
|
|
2040
|
+
const results = [];
|
|
2041
|
+
for (const toolName of context.availableTools) {
|
|
2042
|
+
const toolKeywords = toolName.toLowerCase().split(/[_-]/);
|
|
2043
|
+
const matches = inputKeywords.filter(
|
|
2044
|
+
(kw) => toolKeywords.some((tk) => tk.includes(kw) || kw.includes(tk))
|
|
2045
|
+
);
|
|
2046
|
+
if (matches.length > 0) {
|
|
2047
|
+
let confidence = matches.length / Math.max(inputKeywords.length, toolKeywords.length);
|
|
2048
|
+
const reasons = [`Keyword match: ${matches.join(", ")}`];
|
|
2049
|
+
if (intentResult.intent !== "general" && matches.some((m) => m.includes(intentResult.intent))) {
|
|
2050
|
+
confidence = Math.min(confidence * 1.2, 1);
|
|
2051
|
+
reasons.push(`Matches ${intentResult.intent} intent`);
|
|
2052
|
+
}
|
|
2053
|
+
if (confidence >= this.config.threshold) {
|
|
2054
|
+
results.push({ name: toolName, confidence, reasons });
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
results.sort((a, b) => b.confidence - a.confidence);
|
|
2059
|
+
return results;
|
|
2060
|
+
}
|
|
2061
|
+
/**
|
|
2062
|
+
* Build comprehensive decision
|
|
2063
|
+
*/
|
|
2064
|
+
async buildDecision(_decisionContext, intentResult, relevantSkills, relevantTools, executionContext) {
|
|
2065
|
+
let type = "llm";
|
|
2066
|
+
let skills;
|
|
2067
|
+
let tools;
|
|
2068
|
+
let reasoning;
|
|
2069
|
+
let confidence;
|
|
2070
|
+
let subDecisions;
|
|
2071
|
+
const topSkills = relevantSkills.slice(0, this.config.maxSkills);
|
|
2072
|
+
const topTools = relevantTools.slice(0, 2);
|
|
2073
|
+
if (topSkills.length === 0 && topTools.length === 0) {
|
|
2074
|
+
type = "llm";
|
|
2075
|
+
confidence = 1;
|
|
2076
|
+
reasoning = `No relevant skills/tools found for intent "${intentResult.intent}". Using LLM directly.`;
|
|
2077
|
+
} else if (topSkills.length === 1 && topTools.length === 0) {
|
|
2078
|
+
type = "skill";
|
|
2079
|
+
skills = [topSkills[0].name];
|
|
2080
|
+
confidence = topSkills[0].confidence * intentResult.confidence;
|
|
2081
|
+
reasoning = `Single skill match: ${topSkills[0].name}. ${topSkills[0].reasons.join("; ")}`;
|
|
2082
|
+
} else if (topTools.length === 1 && topSkills.length === 0) {
|
|
2083
|
+
type = "tool";
|
|
2084
|
+
tools = [topTools[0].name];
|
|
2085
|
+
confidence = topTools[0].confidence * intentResult.confidence;
|
|
2086
|
+
reasoning = `Single tool match: ${topTools[0].name}. ${topTools[0].reasons.join("; ")}`;
|
|
2087
|
+
} else {
|
|
2088
|
+
type = "multi";
|
|
2089
|
+
skills = topSkills.map((s) => s.name);
|
|
2090
|
+
tools = topTools.map((t) => t.name);
|
|
2091
|
+
confidence = Math.max(
|
|
2092
|
+
_nullishCoalesce(_optionalChain([topSkills, 'access', _74 => _74[0], 'optionalAccess', _75 => _75.confidence]), () => ( 0)),
|
|
2093
|
+
_nullishCoalesce(_optionalChain([topTools, 'access', _76 => _76[0], 'optionalAccess', _77 => _77.confidence]), () => ( 0))
|
|
2094
|
+
) * intentResult.confidence;
|
|
2095
|
+
reasoning = `Multiple matches for intent "${intentResult.intent}": Skills [${skills.join(", ")}], Tools [${tools.join(", ")}]`;
|
|
2096
|
+
subDecisions = this.buildSubDecisions(topSkills, topTools);
|
|
2097
|
+
}
|
|
2098
|
+
const estimatedTokens = this.estimateTokenUsage(type, skills, tools);
|
|
2099
|
+
const estimatedTime = this.estimateExecutionTime(type, skills, tools);
|
|
2100
|
+
if (_optionalChain([executionContext, 'optionalAccess', _78 => _78.constraints])) {
|
|
2101
|
+
const { maxTokens, maxTime, allowedSkills, blockedSkills } = executionContext.constraints;
|
|
2102
|
+
if (maxTokens && estimatedTokens > maxTokens) {
|
|
2103
|
+
reasoning += ` (Token limit exceeded: ${estimatedTokens} > ${maxTokens})`;
|
|
2104
|
+
confidence *= 0.8;
|
|
2105
|
+
}
|
|
2106
|
+
if (maxTime && estimatedTime > maxTime) {
|
|
2107
|
+
reasoning += ` (Time limit exceeded: ${estimatedTime}ms > ${maxTime}ms)`;
|
|
2108
|
+
confidence *= 0.8;
|
|
2109
|
+
}
|
|
2110
|
+
if (blockedSkills && skills) {
|
|
2111
|
+
skills = skills.filter((s) => !blockedSkills.includes(s));
|
|
2112
|
+
}
|
|
2113
|
+
if (allowedSkills && skills) {
|
|
2114
|
+
skills = skills.filter((s) => allowedSkills.includes(s));
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
return {
|
|
2118
|
+
type,
|
|
2119
|
+
skills,
|
|
2120
|
+
tools,
|
|
2121
|
+
confidence,
|
|
2122
|
+
reasoning,
|
|
2123
|
+
fallback: confidence < 0.5 ? "llm" : void 0,
|
|
2124
|
+
intent: intentResult.intent,
|
|
2125
|
+
intentConfidence: intentResult.confidence,
|
|
2126
|
+
subDecisions,
|
|
2127
|
+
estimatedTokens,
|
|
2128
|
+
estimatedTime
|
|
2129
|
+
};
|
|
2130
|
+
}
|
|
2131
|
+
/**
|
|
2132
|
+
* Build sub-decisions for complex scenarios
|
|
2133
|
+
*/
|
|
2134
|
+
buildSubDecisions(skills, tools) {
|
|
2135
|
+
const subDecisions = [];
|
|
2136
|
+
for (const skill of skills) {
|
|
2137
|
+
subDecisions.push({
|
|
2138
|
+
type: "skill",
|
|
2139
|
+
skills: [skill.name],
|
|
2140
|
+
confidence: skill.confidence,
|
|
2141
|
+
reasoning: `Execute skill: ${skill.name}`,
|
|
2142
|
+
intent: "sub-task",
|
|
2143
|
+
intentConfidence: skill.confidence,
|
|
2144
|
+
estimatedTokens: 500,
|
|
2145
|
+
estimatedTime: 1e3
|
|
2146
|
+
});
|
|
2147
|
+
}
|
|
2148
|
+
for (const tool of tools) {
|
|
2149
|
+
subDecisions.push({
|
|
2150
|
+
type: "tool",
|
|
2151
|
+
tools: [tool.name],
|
|
2152
|
+
confidence: tool.confidence,
|
|
2153
|
+
reasoning: `Execute tool: ${tool.name}`,
|
|
2154
|
+
intent: "sub-task",
|
|
2155
|
+
intentConfidence: tool.confidence,
|
|
2156
|
+
estimatedTokens: 200,
|
|
2157
|
+
estimatedTime: 500
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
return subDecisions;
|
|
2161
|
+
}
|
|
2162
|
+
/**
|
|
2163
|
+
* Enrich decision with execution context
|
|
2164
|
+
*/
|
|
2165
|
+
enrichDecisionWithContext(decision, executionContext) {
|
|
2166
|
+
if (!executionContext || !this.config.enableContextualMemory) {
|
|
2167
|
+
return decision;
|
|
2168
|
+
}
|
|
2169
|
+
const similarDecisions = executionContext.previousDecisions.filter(
|
|
2170
|
+
(d) => d.intent === decision.intent
|
|
2171
|
+
);
|
|
2172
|
+
if (similarDecisions.length > 0) {
|
|
2173
|
+
const avgSuccess = similarDecisions.filter((d) => d.confidence > 0.7).length / similarDecisions.length;
|
|
2174
|
+
decision.confidence = decision.confidence * (0.8 + avgSuccess * 0.2);
|
|
2175
|
+
}
|
|
2176
|
+
return decision;
|
|
2177
|
+
}
|
|
2178
|
+
/**
|
|
2179
|
+
* Estimate token usage
|
|
2180
|
+
*/
|
|
2181
|
+
estimateTokenUsage(type, skills, tools) {
|
|
2182
|
+
let tokens = 500;
|
|
2183
|
+
if (type === "skill" || type === "multi") {
|
|
2184
|
+
tokens += (_nullishCoalesce(_optionalChain([skills, 'optionalAccess', _79 => _79.length]), () => ( 0))) * 800;
|
|
2185
|
+
}
|
|
2186
|
+
if (type === "tool" || type === "multi") {
|
|
2187
|
+
tokens += (_nullishCoalesce(_optionalChain([tools, 'optionalAccess', _80 => _80.length]), () => ( 0))) * 300;
|
|
2188
|
+
}
|
|
2189
|
+
if (type === "llm") {
|
|
2190
|
+
tokens += 2e3;
|
|
2191
|
+
}
|
|
2192
|
+
return tokens;
|
|
2193
|
+
}
|
|
2194
|
+
/**
|
|
2195
|
+
* Estimate execution time
|
|
2196
|
+
*/
|
|
2197
|
+
estimateExecutionTime(type, skills, tools) {
|
|
2198
|
+
let time = 500;
|
|
2199
|
+
if (type === "skill" || type === "multi") {
|
|
2200
|
+
time += (_nullishCoalesce(_optionalChain([skills, 'optionalAccess', _81 => _81.length]), () => ( 0))) * 2e3;
|
|
2201
|
+
}
|
|
2202
|
+
if (type === "tool" || type === "multi") {
|
|
2203
|
+
time += (_nullishCoalesce(_optionalChain([tools, 'optionalAccess', _82 => _82.length]), () => ( 0))) * 1e3;
|
|
2204
|
+
}
|
|
2205
|
+
if (type === "llm") {
|
|
2206
|
+
time += 3e3;
|
|
2207
|
+
}
|
|
2208
|
+
return time;
|
|
2209
|
+
}
|
|
2210
|
+
/**
|
|
2211
|
+
* Learn from execution result
|
|
2212
|
+
*/
|
|
2213
|
+
learn(input, decision, success, executionTime) {
|
|
2214
|
+
this.executionHistory.push({
|
|
2215
|
+
input,
|
|
2216
|
+
decision,
|
|
2217
|
+
success,
|
|
2218
|
+
executionTime
|
|
2219
|
+
});
|
|
2220
|
+
if (this.executionHistory.length > 1e3) {
|
|
2221
|
+
this.executionHistory = this.executionHistory.slice(-500);
|
|
2222
|
+
}
|
|
2223
|
+
if (this.config.enableContextualMemory) {
|
|
2224
|
+
const pattern = this.intentPatterns.find((p) => p.name === decision.intent);
|
|
2225
|
+
if (pattern) {
|
|
2226
|
+
const adjustment = success ? this.config.learningRate : -this.config.learningRate;
|
|
2227
|
+
pattern.weight = Math.max(0.1, Math.min(2, pattern.weight + adjustment));
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
/**
|
|
2232
|
+
* Index skill for retrieval
|
|
2233
|
+
*/
|
|
2234
|
+
async indexSkill(skill) {
|
|
2235
|
+
if (!this.config.enableEmbeddings) return;
|
|
2236
|
+
const text = `${skill.name} ${skill.description} ${this.extractKeywords(skill)}`;
|
|
2237
|
+
const embedding = await this.embeddingProvider.embed(text);
|
|
2238
|
+
this.skillEmbeddings.set(skill.name, embedding);
|
|
2239
|
+
}
|
|
2240
|
+
/**
|
|
2241
|
+
* Extract keywords from skill
|
|
2242
|
+
*/
|
|
2243
|
+
extractKeywords(skill) {
|
|
2244
|
+
const keywords = [
|
|
2245
|
+
skill.name,
|
|
2246
|
+
skill.description,
|
|
2247
|
+
..._nullishCoalesce(_optionalChain([skill, 'access', _83 => _83.metadata, 'optionalAccess', _84 => _84.tags]), () => ( [])),
|
|
2248
|
+
_nullishCoalesce(_optionalChain([skill, 'access', _85 => _85.metadata, 'optionalAccess', _86 => _86.category]), () => ( ""))
|
|
2249
|
+
];
|
|
2250
|
+
for (const [key, prop] of Object.entries(skill.parameters.properties)) {
|
|
2251
|
+
keywords.push(key, prop.description);
|
|
2252
|
+
}
|
|
2253
|
+
return keywords.join(" ");
|
|
2254
|
+
}
|
|
2255
|
+
/**
|
|
2256
|
+
* Extract keywords from text
|
|
2257
|
+
*/
|
|
2258
|
+
extractKeywordsFromText(text) {
|
|
2259
|
+
return text.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((t) => t.length > 2);
|
|
2260
|
+
}
|
|
2261
|
+
/**
|
|
2262
|
+
* Generate cache key
|
|
2263
|
+
*/
|
|
2264
|
+
generateCacheKey(context, executionContext) {
|
|
2265
|
+
const base = `${context.input}:${context.availableSkills.join(",")}:${context.availableTools.join(",")}`;
|
|
2266
|
+
if (_optionalChain([executionContext, 'optionalAccess', _87 => _87.constraints, 'access', _88 => _88.allowedSkills])) {
|
|
2267
|
+
return `${base}:${executionContext.constraints.allowedSkills.join(",")}`;
|
|
2268
|
+
}
|
|
2269
|
+
return base;
|
|
2270
|
+
}
|
|
2271
|
+
/**
|
|
2272
|
+
* Limit cache size
|
|
2273
|
+
*/
|
|
2274
|
+
limitCacheSize() {
|
|
2275
|
+
if (this.decisionCache.size > 1e3) {
|
|
2276
|
+
const firstKey = this.decisionCache.keys().next().value;
|
|
2277
|
+
if (firstKey !== void 0) {
|
|
2278
|
+
this.decisionCache.delete(firstKey);
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
/**
|
|
2283
|
+
* Get performance statistics
|
|
2284
|
+
*/
|
|
2285
|
+
getStats() {
|
|
2286
|
+
const successCount = this.executionHistory.filter((h) => h.success).length;
|
|
2287
|
+
const averageSuccessRate = this.executionHistory.length > 0 ? successCount / this.executionHistory.length : 0;
|
|
2288
|
+
return {
|
|
2289
|
+
cacheSize: this.decisionCache.size,
|
|
2290
|
+
historySize: this.executionHistory.length,
|
|
2291
|
+
intentPatterns: this.intentPatterns.map((p) => ({ name: p.name, weight: p.weight })),
|
|
2292
|
+
averageSuccessRate
|
|
2293
|
+
};
|
|
2294
|
+
}
|
|
2295
|
+
/**
|
|
2296
|
+
* Clear all data
|
|
2297
|
+
*/
|
|
2298
|
+
clear() {
|
|
2299
|
+
this.decisionCache.clear();
|
|
2300
|
+
this.executionHistory = [];
|
|
2301
|
+
this.skillEmbeddings.clear();
|
|
2302
|
+
}
|
|
2303
|
+
}, _class10);
|
|
2304
|
+
|
|
2305
|
+
// src/core/parameter-extractor.ts
|
|
2306
|
+
var ParameterExtractor = class {
|
|
2307
|
+
|
|
2308
|
+
constructor(config = {}) {
|
|
2309
|
+
this.config = {
|
|
2310
|
+
useLLM: _nullishCoalesce(config.useLLM, () => ( true)),
|
|
2311
|
+
usePatternMatching: _nullishCoalesce(config.usePatternMatching, () => ( true)),
|
|
2312
|
+
useContextInference: _nullishCoalesce(config.useContextInference, () => ( true)),
|
|
2313
|
+
confidenceThreshold: _nullishCoalesce(config.confidenceThreshold, () => ( 0.7)),
|
|
2314
|
+
maxRetries: _nullishCoalesce(config.maxRetries, () => ( 3))
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
/**
|
|
2318
|
+
* Extract parameters from input using multiple strategies
|
|
2319
|
+
*/
|
|
2320
|
+
async extract(input, skill, context, llmProvider) {
|
|
2321
|
+
const results = [];
|
|
2322
|
+
if (this.config.usePatternMatching) {
|
|
2323
|
+
const patternResult = this.extractWithPatterns(input, skill);
|
|
2324
|
+
results.push(patternResult);
|
|
2325
|
+
}
|
|
2326
|
+
if (this.config.useContextInference && context) {
|
|
2327
|
+
const contextResult = this.extractFromContext(skill, context);
|
|
2328
|
+
results.push(contextResult);
|
|
2329
|
+
}
|
|
2330
|
+
if (this.config.useLLM && llmProvider) {
|
|
2331
|
+
const llmResult = await this.extractWithLLM(input, skill, llmProvider);
|
|
2332
|
+
results.push(llmResult);
|
|
2333
|
+
}
|
|
2334
|
+
return this.mergeResults(results, skill);
|
|
2335
|
+
}
|
|
2336
|
+
/**
|
|
2337
|
+
* Extract parameters using pattern matching
|
|
2338
|
+
*/
|
|
2339
|
+
extractWithPatterns(input, skill) {
|
|
2340
|
+
const params = {};
|
|
2341
|
+
const missing = [];
|
|
2342
|
+
const invalid = [];
|
|
2343
|
+
const suggestions = [];
|
|
2344
|
+
let confidence = 0;
|
|
2345
|
+
for (const [key, prop] of Object.entries(skill.parameters.properties)) {
|
|
2346
|
+
const schema = this.convertPropertyToSchema(prop);
|
|
2347
|
+
const value = this.extractValueWithPatterns(input, key, schema);
|
|
2348
|
+
if (value !== void 0) {
|
|
2349
|
+
const validation = this.validateValue(value, schema);
|
|
2350
|
+
if (validation.valid) {
|
|
2351
|
+
params[key] = value;
|
|
2352
|
+
confidence += 0.3;
|
|
2353
|
+
} else {
|
|
2354
|
+
invalid.push({ param: key, reason: validation.reason || "Invalid value" });
|
|
2355
|
+
suggestions.push({
|
|
2356
|
+
param: key,
|
|
2357
|
+
suggestion: this.generateSuggestion(schema, validation.reason)
|
|
2358
|
+
});
|
|
2359
|
+
}
|
|
2360
|
+
} else if (_optionalChain([skill, 'access', _89 => _89.parameters, 'access', _90 => _90.required, 'optionalAccess', _91 => _91.includes, 'call', _92 => _92(key)])) {
|
|
2361
|
+
missing.push(key);
|
|
2362
|
+
suggestions.push({
|
|
2363
|
+
param: key,
|
|
2364
|
+
suggestion: `Please provide ${prop.description}`
|
|
2365
|
+
});
|
|
2366
|
+
} else if (prop.default !== void 0) {
|
|
2367
|
+
params[key] = prop.default;
|
|
2368
|
+
confidence += 0.1;
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
const totalParams = Object.keys(skill.parameters.properties).length;
|
|
2372
|
+
confidence = totalParams > 0 ? confidence / totalParams : 0;
|
|
2373
|
+
return {
|
|
2374
|
+
params,
|
|
2375
|
+
confidence,
|
|
2376
|
+
missing,
|
|
2377
|
+
invalid,
|
|
2378
|
+
suggestions
|
|
2379
|
+
};
|
|
2380
|
+
}
|
|
2381
|
+
/**
|
|
2382
|
+
* Convert ParameterProperty to ParameterSchema
|
|
2383
|
+
*/
|
|
2384
|
+
convertPropertyToSchema(prop) {
|
|
2385
|
+
const type = prop.type;
|
|
2386
|
+
return {
|
|
2387
|
+
type,
|
|
2388
|
+
description: prop.description,
|
|
2389
|
+
enum: prop.enum,
|
|
2390
|
+
default: prop.default
|
|
2391
|
+
};
|
|
2392
|
+
}
|
|
2393
|
+
/**
|
|
2394
|
+
* Extract a single value using patterns
|
|
2395
|
+
*/
|
|
2396
|
+
extractValueWithPatterns(input, key, schema) {
|
|
2397
|
+
const patterns = [
|
|
2398
|
+
// "key: value" or "key = value"
|
|
2399
|
+
new RegExp(`${key}[:=]\\s*([^,;\\n]+)`, "i"),
|
|
2400
|
+
// "key is value"
|
|
2401
|
+
new RegExp(`${key}\\s+is\\s+([^,;\\n]+)`, "i"),
|
|
2402
|
+
// "with key value" or "using key value"
|
|
2403
|
+
new RegExp(`(?:with|using)\\s+${key}\\s+([^,;\\n]+)`, "i"),
|
|
2404
|
+
// "key value" (positional)
|
|
2405
|
+
new RegExp(`${key}\\s+([^,;\\n]+)`, "i")
|
|
2406
|
+
];
|
|
2407
|
+
for (const pattern of patterns) {
|
|
2408
|
+
const match = input.match(pattern);
|
|
2409
|
+
if (match) {
|
|
2410
|
+
const rawValue = match[1].trim();
|
|
2411
|
+
return this.coerceValue(rawValue, schema);
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
if (schema.type === "array" && schema.items) {
|
|
2415
|
+
return this.extractArrayValue(input, key, schema.items);
|
|
2416
|
+
}
|
|
2417
|
+
if (schema.type === "boolean") {
|
|
2418
|
+
const boolPattern = new RegExp(`\\b${key}\\b`, "i");
|
|
2419
|
+
if (boolPattern.test(input)) {
|
|
2420
|
+
const negativePattern = new RegExp(`(no\\s+${key}|without\\s+${key}|disable\\s+${key})`, "i");
|
|
2421
|
+
return !negativePattern.test(input);
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
return void 0;
|
|
2425
|
+
}
|
|
2426
|
+
/**
|
|
2427
|
+
* Extract array values
|
|
2428
|
+
*/
|
|
2429
|
+
extractArrayValue(input, key, itemSchema) {
|
|
2430
|
+
const patterns = [
|
|
2431
|
+
new RegExp(`${key}[:=]\\s*\\[([^\\]]+)\\]`, "i"),
|
|
2432
|
+
new RegExp(`${key}[:=]\\s*([^,;\\n]+)`, "i")
|
|
2433
|
+
];
|
|
2434
|
+
for (const pattern of patterns) {
|
|
2435
|
+
const match = input.match(pattern);
|
|
2436
|
+
if (match) {
|
|
2437
|
+
const items = match[1].split(/[,;]/).map((s) => s.trim());
|
|
2438
|
+
return items.map((item) => this.coerceValue(item, itemSchema));
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
return void 0;
|
|
2442
|
+
}
|
|
2443
|
+
/**
|
|
2444
|
+
* Coerce value to correct type
|
|
2445
|
+
*/
|
|
2446
|
+
coerceValue(rawValue, schema) {
|
|
2447
|
+
switch (schema.type) {
|
|
2448
|
+
case "number": {
|
|
2449
|
+
const num = parseFloat(rawValue);
|
|
2450
|
+
return isNaN(num) ? rawValue : num;
|
|
2451
|
+
}
|
|
2452
|
+
case "boolean":
|
|
2453
|
+
return ["true", "yes", "1", "on"].includes(rawValue.toLowerCase());
|
|
2454
|
+
case "array": {
|
|
2455
|
+
try {
|
|
2456
|
+
const parsed = JSON.parse(rawValue);
|
|
2457
|
+
if (Array.isArray(parsed)) return parsed;
|
|
2458
|
+
} catch (e3) {
|
|
2459
|
+
return rawValue.split(/[,;]/).map((s) => s.trim());
|
|
2460
|
+
}
|
|
2461
|
+
return [rawValue];
|
|
2462
|
+
}
|
|
2463
|
+
case "object":
|
|
2464
|
+
try {
|
|
2465
|
+
return JSON.parse(rawValue);
|
|
2466
|
+
} catch (e4) {
|
|
2467
|
+
return rawValue;
|
|
2468
|
+
}
|
|
2469
|
+
case "string":
|
|
2470
|
+
default:
|
|
2471
|
+
if (schema.enum) {
|
|
2472
|
+
const match = schema.enum.find(
|
|
2473
|
+
(e) => String(e).toLowerCase() === rawValue.toLowerCase()
|
|
2474
|
+
);
|
|
2475
|
+
if (match !== void 0) return match;
|
|
2476
|
+
}
|
|
2477
|
+
return rawValue;
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
/**
|
|
2481
|
+
* Validate extracted value
|
|
2482
|
+
*/
|
|
2483
|
+
validateValue(value, schema) {
|
|
2484
|
+
if (schema.enum && !schema.enum.includes(value)) {
|
|
2485
|
+
return {
|
|
2486
|
+
valid: false,
|
|
2487
|
+
reason: `Value must be one of: ${schema.enum.join(", ")}`
|
|
2488
|
+
};
|
|
2489
|
+
}
|
|
2490
|
+
if (schema.pattern && typeof value === "string") {
|
|
2491
|
+
const regex = new RegExp(schema.pattern);
|
|
2492
|
+
if (!regex.test(value)) {
|
|
2493
|
+
return {
|
|
2494
|
+
valid: false,
|
|
2495
|
+
reason: `Value does not match required pattern`
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
if (schema.type === "number" && typeof value === "number") {
|
|
2500
|
+
if (schema.min !== void 0 && value < schema.min) {
|
|
2501
|
+
return {
|
|
2502
|
+
valid: false,
|
|
2503
|
+
reason: `Value must be at least ${schema.min}`
|
|
2504
|
+
};
|
|
2505
|
+
}
|
|
2506
|
+
if (schema.max !== void 0 && value > schema.max) {
|
|
2507
|
+
return {
|
|
2508
|
+
valid: false,
|
|
2509
|
+
reason: `Value must be at most ${schema.max}`
|
|
2510
|
+
};
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
if (schema.type === "array" && Array.isArray(value)) {
|
|
2514
|
+
if (schema.min !== void 0 && value.length < schema.min) {
|
|
2515
|
+
return {
|
|
2516
|
+
valid: false,
|
|
2517
|
+
reason: `Array must have at least ${schema.min} items`
|
|
2518
|
+
};
|
|
2519
|
+
}
|
|
2520
|
+
if (schema.max !== void 0 && value.length > schema.max) {
|
|
2521
|
+
return {
|
|
2522
|
+
valid: false,
|
|
2523
|
+
reason: `Array must have at most ${schema.max} items`
|
|
2524
|
+
};
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
return { valid: true };
|
|
2528
|
+
}
|
|
2529
|
+
/**
|
|
2530
|
+
* Extract parameters from context
|
|
2531
|
+
*/
|
|
2532
|
+
extractFromContext(skill, context) {
|
|
2533
|
+
const params = {};
|
|
2534
|
+
const missing = [];
|
|
2535
|
+
const invalid = [];
|
|
2536
|
+
const suggestions = [];
|
|
2537
|
+
let confidence = 0;
|
|
2538
|
+
for (const key of Object.keys(skill.parameters.properties)) {
|
|
2539
|
+
const prop = skill.parameters.properties[key];
|
|
2540
|
+
if (_optionalChain([context, 'access', _93 => _93.previousParams, 'optionalAccess', _94 => _94[key]]) !== void 0) {
|
|
2541
|
+
params[key] = context.previousParams[key];
|
|
2542
|
+
confidence += 0.2;
|
|
2543
|
+
continue;
|
|
2544
|
+
}
|
|
2545
|
+
if (_optionalChain([context, 'access', _95 => _95.userPreferences, 'optionalAccess', _96 => _96[key]]) !== void 0) {
|
|
2546
|
+
params[key] = context.userPreferences[key];
|
|
2547
|
+
confidence += 0.15;
|
|
2548
|
+
continue;
|
|
2549
|
+
}
|
|
2550
|
+
if (_optionalChain([context, 'access', _97 => _97.extractedEntities, 'optionalAccess', _98 => _98[key]]) !== void 0) {
|
|
2551
|
+
params[key] = context.extractedEntities[key];
|
|
2552
|
+
confidence += 0.25;
|
|
2553
|
+
continue;
|
|
2554
|
+
}
|
|
2555
|
+
if (prop.default !== void 0) {
|
|
2556
|
+
params[key] = prop.default;
|
|
2557
|
+
confidence += 0.1;
|
|
2558
|
+
} else if (_optionalChain([skill, 'access', _99 => _99.parameters, 'access', _100 => _100.required, 'optionalAccess', _101 => _101.includes, 'call', _102 => _102(key)])) {
|
|
2559
|
+
missing.push(key);
|
|
2560
|
+
suggestions.push({
|
|
2561
|
+
param: key,
|
|
2562
|
+
suggestion: `Please provide ${prop.description}`
|
|
2563
|
+
});
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
const totalParams = Object.keys(skill.parameters.properties).length;
|
|
2567
|
+
confidence = totalParams > 0 ? confidence / totalParams : 0;
|
|
2568
|
+
return {
|
|
2569
|
+
params,
|
|
2570
|
+
confidence,
|
|
2571
|
+
missing,
|
|
2572
|
+
invalid,
|
|
2573
|
+
suggestions
|
|
2574
|
+
};
|
|
2575
|
+
}
|
|
2576
|
+
/**
|
|
2577
|
+
* Extract parameters using LLM
|
|
2578
|
+
*/
|
|
2579
|
+
async extractWithLLM(input, skill, llmProvider) {
|
|
2580
|
+
const prompt = this.buildExtractionPrompt(input, skill);
|
|
2581
|
+
try {
|
|
2582
|
+
const response = await llmProvider.complete(prompt);
|
|
2583
|
+
const parsed = JSON.parse(response.content);
|
|
2584
|
+
return {
|
|
2585
|
+
params: parsed.params || {},
|
|
2586
|
+
confidence: parsed.confidence || 0.8,
|
|
2587
|
+
missing: parsed.missing || [],
|
|
2588
|
+
invalid: parsed.invalid || [],
|
|
2589
|
+
suggestions: parsed.suggestions || []
|
|
2590
|
+
};
|
|
2591
|
+
} catch (e5) {
|
|
2592
|
+
return {
|
|
2593
|
+
params: {},
|
|
2594
|
+
confidence: 0,
|
|
2595
|
+
missing: skill.parameters.required || [],
|
|
2596
|
+
invalid: [],
|
|
2597
|
+
suggestions: []
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
/**
|
|
2602
|
+
* Build LLM extraction prompt
|
|
2603
|
+
*/
|
|
2604
|
+
buildExtractionPrompt(input, skill) {
|
|
2605
|
+
const params = Object.entries(skill.parameters.properties).map(([key, prop]) => {
|
|
2606
|
+
const required = _optionalChain([skill, 'access', _103 => _103.parameters, 'access', _104 => _104.required, 'optionalAccess', _105 => _105.includes, 'call', _106 => _106(key)]) ? " (required)" : "";
|
|
2607
|
+
const type = prop.type ? ` [${prop.type}]` : "";
|
|
2608
|
+
const enum_ = prop.enum ? ` enum: [${prop.enum.join(", ")}]` : "";
|
|
2609
|
+
return `- ${key}${type}${required}: ${prop.description}${enum_}`;
|
|
2610
|
+
}).join("\n");
|
|
2611
|
+
return `Extract parameters from the user input for the skill "${skill.name}".
|
|
2612
|
+
|
|
2613
|
+
Skill description: ${skill.description}
|
|
2614
|
+
|
|
2615
|
+
Parameters:
|
|
2616
|
+
${params}
|
|
2617
|
+
|
|
2618
|
+
User input: "${input}"
|
|
2619
|
+
|
|
2620
|
+
Return a JSON object with this structure:
|
|
2621
|
+
{
|
|
2622
|
+
"params": { "paramName": "extractedValue", ... },
|
|
2623
|
+
"confidence": 0.0-1.0,
|
|
2624
|
+
"missing": ["paramName", ...],
|
|
2625
|
+
"invalid": [{"param": "name", "reason": "why invalid"}],
|
|
2626
|
+
"suggestions": [{"param": "name", "suggestion": "helpful suggestion"}]
|
|
2627
|
+
}`;
|
|
2628
|
+
}
|
|
2629
|
+
/**
|
|
2630
|
+
* Merge extraction results from multiple strategies
|
|
2631
|
+
*/
|
|
2632
|
+
mergeResults(results, skill) {
|
|
2633
|
+
const merged = {};
|
|
2634
|
+
const missing = /* @__PURE__ */ new Set();
|
|
2635
|
+
const invalid = [];
|
|
2636
|
+
const suggestions = [];
|
|
2637
|
+
let totalConfidence = 0;
|
|
2638
|
+
const weights = results.map((r) => r.confidence);
|
|
2639
|
+
for (const key of Object.keys(skill.parameters.properties)) {
|
|
2640
|
+
const prop = skill.parameters.properties[key];
|
|
2641
|
+
const values = [];
|
|
2642
|
+
for (let i = 0; i < results.length; i++) {
|
|
2643
|
+
const result = results[i];
|
|
2644
|
+
if (key in result.params) {
|
|
2645
|
+
values.push({ value: result.params[key], weight: weights[i] });
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
if (values.length > 0) {
|
|
2649
|
+
values.sort((a, b) => b.weight - a.weight);
|
|
2650
|
+
merged[key] = values[0].value;
|
|
2651
|
+
totalConfidence += values[0].weight;
|
|
2652
|
+
} else if (_optionalChain([skill, 'access', _107 => _107.parameters, 'access', _108 => _108.required, 'optionalAccess', _109 => _109.includes, 'call', _110 => _110(key)])) {
|
|
2653
|
+
missing.add(key);
|
|
2654
|
+
} else if (prop.default !== void 0) {
|
|
2655
|
+
merged[key] = prop.default;
|
|
2656
|
+
totalConfidence += 0.1;
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
for (const result of results) {
|
|
2660
|
+
result.missing.forEach((m) => missing.add(m));
|
|
2661
|
+
invalid.push(...result.invalid);
|
|
2662
|
+
suggestions.push(...result.suggestions);
|
|
2663
|
+
}
|
|
2664
|
+
const totalParams = Object.keys(skill.parameters.properties).length;
|
|
2665
|
+
const avgConfidence = totalParams > 0 ? totalConfidence / totalParams : 0;
|
|
2666
|
+
return {
|
|
2667
|
+
params: merged,
|
|
2668
|
+
confidence: avgConfidence,
|
|
2669
|
+
missing: Array.from(missing),
|
|
2670
|
+
invalid,
|
|
2671
|
+
suggestions
|
|
2672
|
+
};
|
|
2673
|
+
}
|
|
2674
|
+
/**
|
|
2675
|
+
* Generate helpful suggestion for invalid parameter
|
|
2676
|
+
*/
|
|
2677
|
+
generateSuggestion(schema, reason) {
|
|
2678
|
+
if (schema.enum) {
|
|
2679
|
+
return `Please use one of: ${schema.enum.join(", ")}`;
|
|
2680
|
+
}
|
|
2681
|
+
if (schema.pattern) {
|
|
2682
|
+
return `Value must match pattern: ${schema.pattern}`;
|
|
2683
|
+
}
|
|
2684
|
+
if (schema.min !== void 0 || schema.max !== void 0) {
|
|
2685
|
+
const range = `${_nullishCoalesce(schema.min, () => ( "min"))} to ${_nullishCoalesce(schema.max, () => ( "max"))}`;
|
|
2686
|
+
return `Value must be within range ${range}`;
|
|
2687
|
+
}
|
|
2688
|
+
return reason || `Please provide valid ${schema.type}`;
|
|
2689
|
+
}
|
|
2690
|
+
/**
|
|
2691
|
+
* Validate all parameters against schema
|
|
2692
|
+
*/
|
|
2693
|
+
validate(params, skill) {
|
|
2694
|
+
const missing = [];
|
|
2695
|
+
const invalid = [];
|
|
2696
|
+
for (const key of Object.keys(skill.parameters.properties)) {
|
|
2697
|
+
const prop = skill.parameters.properties[key];
|
|
2698
|
+
if (!(key in params)) {
|
|
2699
|
+
if (_optionalChain([skill, 'access', _111 => _111.parameters, 'access', _112 => _112.required, 'optionalAccess', _113 => _113.includes, 'call', _114 => _114(key)])) {
|
|
2700
|
+
missing.push(key);
|
|
2701
|
+
}
|
|
2702
|
+
continue;
|
|
2703
|
+
}
|
|
2704
|
+
const schema = this.convertPropertyToSchema(prop);
|
|
2705
|
+
const validation = this.validateValue(params[key], schema);
|
|
2706
|
+
if (!validation.valid) {
|
|
2707
|
+
invalid.push({ param: key, reason: validation.reason || "Invalid value" });
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
return {
|
|
2711
|
+
params,
|
|
2712
|
+
confidence: 1,
|
|
2713
|
+
missing,
|
|
2714
|
+
invalid,
|
|
2715
|
+
suggestions: invalid.map((inv) => ({
|
|
2716
|
+
param: inv.param,
|
|
2717
|
+
suggestion: this.generateSuggestion(
|
|
2718
|
+
this.convertPropertyToSchema(skill.parameters.properties[inv.param]),
|
|
2719
|
+
inv.reason
|
|
2720
|
+
)
|
|
2721
|
+
}))
|
|
2722
|
+
};
|
|
2723
|
+
}
|
|
2724
|
+
};
|
|
2725
|
+
|
|
2726
|
+
// src/core/execution-engine.ts
|
|
2727
|
+
var ExecutionEngine = (_class11 = class {
|
|
2728
|
+
|
|
2729
|
+
__init26() {this.activeExecutions = /* @__PURE__ */ new Map()}
|
|
2730
|
+
__init27() {this.circuitBreakers = /* @__PURE__ */ new Map()}
|
|
2731
|
+
__init28() {this.metrics = {
|
|
2732
|
+
totalTime: 0,
|
|
2733
|
+
totalTokens: 0,
|
|
2734
|
+
llmCalls: 0,
|
|
2735
|
+
skillCalls: 0,
|
|
2736
|
+
toolCalls: 0,
|
|
2737
|
+
cacheHits: 0,
|
|
2738
|
+
cacheMisses: 0,
|
|
2739
|
+
retryCount: 0
|
|
2740
|
+
}}
|
|
2741
|
+
constructor(config = {}) {;_class11.prototype.__init26.call(this);_class11.prototype.__init27.call(this);_class11.prototype.__init28.call(this);
|
|
2742
|
+
this.config = {
|
|
2743
|
+
defaultTimeout: _nullishCoalesce(config.defaultTimeout, () => ( 3e4)),
|
|
2744
|
+
defaultRetryPolicy: _nullishCoalesce(config.defaultRetryPolicy, () => ( {
|
|
2745
|
+
maxRetries: 3,
|
|
2746
|
+
backoffStrategy: "exponential",
|
|
2747
|
+
baseDelay: 1e3,
|
|
2748
|
+
maxDelay: 3e4,
|
|
2749
|
+
retryableErrors: ["ETIMEDOUT", "ECONNRESET", "EAI_AGAIN"]
|
|
2750
|
+
})),
|
|
2751
|
+
enableTracing: _nullishCoalesce(config.enableTracing, () => ( true)),
|
|
2752
|
+
enableMetrics: _nullishCoalesce(config.enableMetrics, () => ( true)),
|
|
2753
|
+
maxConcurrentExecutions: _nullishCoalesce(config.maxConcurrentExecutions, () => ( 10)),
|
|
2754
|
+
observers: _nullishCoalesce(config.observers, () => ( []))
|
|
2755
|
+
};
|
|
2756
|
+
}
|
|
2757
|
+
async execute(plan, context = {}, resilience) {
|
|
2758
|
+
const executionId = this.generateId();
|
|
2759
|
+
const fullContext = {
|
|
2760
|
+
executionId,
|
|
2761
|
+
sessionId: _nullishCoalesce(context.sessionId, () => ( this.generateId())),
|
|
2762
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2763
|
+
metadata: _nullishCoalesce(context.metadata, () => ( {})),
|
|
2764
|
+
...context
|
|
2765
|
+
};
|
|
2766
|
+
if (this.activeExecutions.size >= this.config.maxConcurrentExecutions) {
|
|
2767
|
+
throw new Error("Maximum concurrent executions reached");
|
|
2768
|
+
}
|
|
2769
|
+
const abortController = new AbortController();
|
|
2770
|
+
this.activeExecutions.set(executionId, abortController);
|
|
2771
|
+
const startTime = Date.now();
|
|
2772
|
+
const trace = {
|
|
2773
|
+
phases: [],
|
|
2774
|
+
decisions: [],
|
|
2775
|
+
llmCalls: []
|
|
2776
|
+
};
|
|
2777
|
+
try {
|
|
2778
|
+
this.notifyObservers("onExecutionStart", fullContext);
|
|
2779
|
+
await this.executePhase("initialization", fullContext, trace, async () => {
|
|
2780
|
+
this.validatePlan(plan);
|
|
2781
|
+
});
|
|
2782
|
+
const stepResults = await this.executePhase("execution", fullContext, trace, async () => {
|
|
2783
|
+
return this.executeSteps(plan.steps, fullContext, abortController.signal, resilience);
|
|
2784
|
+
});
|
|
2785
|
+
const finalOutput = await this.executePhase(
|
|
2786
|
+
"result_processing",
|
|
2787
|
+
fullContext,
|
|
2788
|
+
trace,
|
|
2789
|
+
async () => {
|
|
2790
|
+
return this.processResults(stepResults);
|
|
2791
|
+
}
|
|
2792
|
+
);
|
|
2793
|
+
const result = {
|
|
2794
|
+
executionId,
|
|
2795
|
+
status: this.determineFinalStatus(stepResults),
|
|
2796
|
+
plan,
|
|
2797
|
+
stepResults,
|
|
2798
|
+
finalOutput,
|
|
2799
|
+
metrics: { ...this.metrics },
|
|
2800
|
+
errors: stepResults.filter((s) => s.error).map((s) => s.error),
|
|
2801
|
+
trace
|
|
2802
|
+
};
|
|
2803
|
+
this.metrics.totalTime = Date.now() - startTime;
|
|
2804
|
+
this.notifyObservers("onExecutionEnd", result, fullContext);
|
|
2805
|
+
return result;
|
|
2806
|
+
} catch (error) {
|
|
2807
|
+
const executionError = {
|
|
2808
|
+
stepId: "engine",
|
|
2809
|
+
code: "EXECUTION_FAILED",
|
|
2810
|
+
message: error instanceof Error ? error.message : String(error),
|
|
2811
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
2812
|
+
recoverable: false
|
|
2813
|
+
};
|
|
2814
|
+
this.notifyObservers("onError", executionError, fullContext);
|
|
2815
|
+
return {
|
|
2816
|
+
executionId,
|
|
2817
|
+
status: "failed",
|
|
2818
|
+
plan,
|
|
2819
|
+
stepResults: [],
|
|
2820
|
+
finalOutput: null,
|
|
2821
|
+
metrics: { ...this.metrics },
|
|
2822
|
+
errors: [executionError],
|
|
2823
|
+
trace
|
|
2824
|
+
};
|
|
2825
|
+
} finally {
|
|
2826
|
+
this.activeExecutions.delete(executionId);
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
async executeSteps(steps, context, signal, resilience) {
|
|
2830
|
+
const results = [];
|
|
2831
|
+
const executedSteps = /* @__PURE__ */ new Set();
|
|
2832
|
+
while (executedSteps.size < steps.length) {
|
|
2833
|
+
const readySteps = steps.filter(
|
|
2834
|
+
(step) => !executedSteps.has(step.id) && (_nullishCoalesce(step.dependencies, () => ( []))).every((dep) => executedSteps.has(dep))
|
|
2835
|
+
);
|
|
2836
|
+
if (readySteps.length === 0) {
|
|
2837
|
+
const remainingSteps = steps.filter((s) => !executedSteps.has(s.id));
|
|
2838
|
+
if (remainingSteps.length > 0) {
|
|
2839
|
+
throw new Error(
|
|
2840
|
+
`Circular dependency detected: ${remainingSteps.map((s) => s.id).join(", ")}`
|
|
2841
|
+
);
|
|
2842
|
+
}
|
|
2843
|
+
break;
|
|
2844
|
+
}
|
|
2845
|
+
const stepPromises = readySteps.map(
|
|
2846
|
+
(step) => this.executeStepWithResilience(step, context, signal, resilience)
|
|
2847
|
+
);
|
|
2848
|
+
const stepResults = await Promise.all(stepPromises);
|
|
2849
|
+
for (const result of stepResults) {
|
|
2850
|
+
results.push(result);
|
|
2851
|
+
executedSteps.add(result.stepId);
|
|
2852
|
+
if (result.status === "failed" && result.error) {
|
|
2853
|
+
const step = steps.find((s) => s.id === result.stepId);
|
|
2854
|
+
if (_optionalChain([step, 'optionalAccess', _115 => _115.onError]) === "fail") {
|
|
2855
|
+
return results;
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
return results;
|
|
2861
|
+
}
|
|
2862
|
+
async executeStepWithResilience(step, context, signal, resilience) {
|
|
2863
|
+
const startTime = Date.now();
|
|
2864
|
+
const retryPolicy = _nullishCoalesce(_optionalChain([resilience, 'optionalAccess', _116 => _116.retryPolicy]), () => ( this.config.defaultRetryPolicy));
|
|
2865
|
+
const timeout = _nullishCoalesce(_nullishCoalesce(step.timeout, () => ( _optionalChain([resilience, 'optionalAccess', _117 => _117.timeout]))), () => ( this.config.defaultTimeout));
|
|
2866
|
+
this.notifyObservers("onStepStart", step, context);
|
|
2867
|
+
let lastError;
|
|
2868
|
+
for (let attempt = 0; attempt <= retryPolicy.maxRetries; attempt++) {
|
|
2869
|
+
try {
|
|
2870
|
+
if (signal.aborted) {
|
|
2871
|
+
throw new Error("Execution aborted");
|
|
2872
|
+
}
|
|
2873
|
+
if (_optionalChain([resilience, 'optionalAccess', _118 => _118.circuitBreaker])) {
|
|
2874
|
+
const cb = this.getCircuitBreaker(step.target, resilience.circuitBreaker);
|
|
2875
|
+
if (!cb.canExecute()) {
|
|
2876
|
+
throw new Error(`Circuit breaker open for ${step.target}`);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
const result = await this.executeWithTimeout(
|
|
2880
|
+
() => this.executeStep(step, context),
|
|
2881
|
+
timeout
|
|
2882
|
+
);
|
|
2883
|
+
if (_optionalChain([resilience, 'optionalAccess', _119 => _119.circuitBreaker])) {
|
|
2884
|
+
const cb = this.getCircuitBreaker(step.target, resilience.circuitBreaker);
|
|
2885
|
+
cb.recordSuccess();
|
|
2886
|
+
}
|
|
2887
|
+
const stepResult2 = {
|
|
2888
|
+
stepId: step.id,
|
|
2889
|
+
status: "completed",
|
|
2890
|
+
output: result,
|
|
2891
|
+
executionTime: Date.now() - startTime,
|
|
2892
|
+
tokensUsed: 0,
|
|
2893
|
+
startTime: new Date(startTime),
|
|
2894
|
+
endTime: /* @__PURE__ */ new Date()
|
|
2895
|
+
};
|
|
2896
|
+
this.notifyObservers("onStepEnd", step, stepResult2, context);
|
|
2897
|
+
return stepResult2;
|
|
2898
|
+
} catch (error) {
|
|
2899
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
2900
|
+
if (_optionalChain([resilience, 'optionalAccess', _120 => _120.circuitBreaker])) {
|
|
2901
|
+
const cb = this.getCircuitBreaker(step.target, resilience.circuitBreaker);
|
|
2902
|
+
cb.recordFailure();
|
|
2903
|
+
}
|
|
2904
|
+
const isRetryable = this.isRetryableError(lastError, retryPolicy);
|
|
2905
|
+
if (!isRetryable || attempt === retryPolicy.maxRetries) {
|
|
2906
|
+
break;
|
|
2907
|
+
}
|
|
2908
|
+
const delay = this.calculateBackoff(attempt, retryPolicy);
|
|
2909
|
+
_optionalChain([retryPolicy, 'access', _121 => _121.onRetry, 'optionalCall', _122 => _122(attempt + 1, lastError, delay)]);
|
|
2910
|
+
this.metrics.retryCount++;
|
|
2911
|
+
await this.sleep(delay);
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
const stepResult = {
|
|
2915
|
+
stepId: step.id,
|
|
2916
|
+
status: "failed",
|
|
2917
|
+
error: {
|
|
2918
|
+
stepId: step.id,
|
|
2919
|
+
code: "STEP_EXECUTION_FAILED",
|
|
2920
|
+
message: _nullishCoalesce(_optionalChain([lastError, 'optionalAccess', _123 => _123.message]), () => ( "Unknown error")),
|
|
2921
|
+
stack: _optionalChain([lastError, 'optionalAccess', _124 => _124.stack]),
|
|
2922
|
+
recoverable: false
|
|
2923
|
+
},
|
|
2924
|
+
executionTime: Date.now() - startTime,
|
|
2925
|
+
tokensUsed: 0,
|
|
2926
|
+
startTime: new Date(startTime),
|
|
2927
|
+
endTime: /* @__PURE__ */ new Date()
|
|
2928
|
+
};
|
|
2929
|
+
this.notifyObservers("onStepEnd", step, stepResult, context);
|
|
2930
|
+
return stepResult;
|
|
2931
|
+
}
|
|
2932
|
+
async executeStep(step, _context) {
|
|
2933
|
+
return {
|
|
2934
|
+
stepId: step.id,
|
|
2935
|
+
type: step.type,
|
|
2936
|
+
target: step.target,
|
|
2937
|
+
parameters: step.parameters
|
|
2938
|
+
};
|
|
2939
|
+
}
|
|
2940
|
+
async executeWithTimeout(fn, timeout) {
|
|
2941
|
+
return Promise.race([
|
|
2942
|
+
fn(),
|
|
2943
|
+
new Promise(
|
|
2944
|
+
(_, reject) => setTimeout(() => reject(new Error(`Timeout after ${timeout}ms`)), timeout)
|
|
2945
|
+
)
|
|
2946
|
+
]);
|
|
2947
|
+
}
|
|
2948
|
+
async executePhase(phase, context, trace, fn) {
|
|
2949
|
+
this.notifyObservers("onPhaseStart", phase, context);
|
|
2950
|
+
const startTime = Date.now();
|
|
2951
|
+
try {
|
|
2952
|
+
const result = await fn();
|
|
2953
|
+
const duration = Date.now() - startTime;
|
|
2954
|
+
trace.phases.push({
|
|
2955
|
+
phase,
|
|
2956
|
+
startTime: new Date(startTime),
|
|
2957
|
+
endTime: /* @__PURE__ */ new Date(),
|
|
2958
|
+
duration
|
|
2959
|
+
});
|
|
2960
|
+
this.notifyObservers("onPhaseEnd", phase, duration, context);
|
|
2961
|
+
return result;
|
|
2962
|
+
} catch (error) {
|
|
2963
|
+
const duration = Date.now() - startTime;
|
|
2964
|
+
trace.phases.push({
|
|
2965
|
+
phase,
|
|
2966
|
+
startTime: new Date(startTime),
|
|
2967
|
+
endTime: /* @__PURE__ */ new Date(),
|
|
2968
|
+
duration,
|
|
2969
|
+
metadata: { error: error instanceof Error ? error.message : String(error) }
|
|
2970
|
+
});
|
|
2971
|
+
this.notifyObservers("onPhaseEnd", phase, duration, context);
|
|
2972
|
+
throw error;
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
validatePlan(plan) {
|
|
2976
|
+
const stepIds = new Set(plan.steps.map((s) => s.id));
|
|
2977
|
+
if (stepIds.size !== plan.steps.length) {
|
|
2978
|
+
throw new Error("Duplicate step IDs in plan");
|
|
2979
|
+
}
|
|
2980
|
+
for (const step of plan.steps) {
|
|
2981
|
+
for (const dep of _nullishCoalesce(step.dependencies, () => ( []))) {
|
|
2982
|
+
if (!stepIds.has(dep)) {
|
|
2983
|
+
throw new Error(`Step ${step.id} depends on unknown step ${dep}`);
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
processResults(stepResults) {
|
|
2989
|
+
const successfulResults = stepResults.filter((r) => r.status === "completed");
|
|
2990
|
+
if (successfulResults.length === 0) {
|
|
2991
|
+
return null;
|
|
2992
|
+
}
|
|
2993
|
+
if (successfulResults.length === 1) {
|
|
2994
|
+
return successfulResults[0].output;
|
|
2995
|
+
}
|
|
2996
|
+
return successfulResults.map((r) => r.output);
|
|
2997
|
+
}
|
|
2998
|
+
determineFinalStatus(stepResults) {
|
|
2999
|
+
if (stepResults.every((r) => r.status === "completed")) {
|
|
3000
|
+
return "completed";
|
|
3001
|
+
}
|
|
3002
|
+
if (stepResults.some((r) => r.status === "failed")) {
|
|
3003
|
+
return "failed";
|
|
3004
|
+
}
|
|
3005
|
+
return "completed";
|
|
3006
|
+
}
|
|
3007
|
+
calculateBackoff(attempt, policy) {
|
|
3008
|
+
const { backoffStrategy, baseDelay, maxDelay } = policy;
|
|
3009
|
+
let delay;
|
|
3010
|
+
switch (backoffStrategy) {
|
|
3011
|
+
case "fixed":
|
|
3012
|
+
delay = baseDelay;
|
|
3013
|
+
break;
|
|
3014
|
+
case "linear":
|
|
3015
|
+
delay = baseDelay * (attempt + 1);
|
|
3016
|
+
break;
|
|
3017
|
+
case "exponential":
|
|
3018
|
+
default:
|
|
3019
|
+
delay = baseDelay * Math.pow(2, attempt);
|
|
3020
|
+
break;
|
|
3021
|
+
}
|
|
3022
|
+
const jitter = Math.random() * 0.1 * delay;
|
|
3023
|
+
delay += jitter;
|
|
3024
|
+
return Math.min(delay, maxDelay);
|
|
3025
|
+
}
|
|
3026
|
+
isRetryableError(error, policy) {
|
|
3027
|
+
const errorCode = error.code;
|
|
3028
|
+
if (errorCode && policy.retryableErrors.includes(errorCode)) {
|
|
3029
|
+
return true;
|
|
3030
|
+
}
|
|
3031
|
+
if (error.message.includes("timeout") || error.message.includes("Timeout")) {
|
|
3032
|
+
return true;
|
|
3033
|
+
}
|
|
3034
|
+
return false;
|
|
3035
|
+
}
|
|
3036
|
+
getCircuitBreaker(name, config) {
|
|
3037
|
+
if (!this.circuitBreakers.has(name)) {
|
|
3038
|
+
this.circuitBreakers.set(name, new CircuitBreaker(config));
|
|
3039
|
+
}
|
|
3040
|
+
return this.circuitBreakers.get(name);
|
|
3041
|
+
}
|
|
3042
|
+
cancelExecution(executionId) {
|
|
3043
|
+
const controller = this.activeExecutions.get(executionId);
|
|
3044
|
+
if (controller) {
|
|
3045
|
+
controller.abort();
|
|
3046
|
+
this.activeExecutions.delete(executionId);
|
|
3047
|
+
return true;
|
|
3048
|
+
}
|
|
3049
|
+
return false;
|
|
3050
|
+
}
|
|
3051
|
+
getMetrics() {
|
|
3052
|
+
return { ...this.metrics };
|
|
3053
|
+
}
|
|
3054
|
+
resetMetrics() {
|
|
3055
|
+
this.metrics = {
|
|
3056
|
+
totalTime: 0,
|
|
3057
|
+
totalTokens: 0,
|
|
3058
|
+
llmCalls: 0,
|
|
3059
|
+
skillCalls: 0,
|
|
3060
|
+
toolCalls: 0,
|
|
3061
|
+
cacheHits: 0,
|
|
3062
|
+
cacheMisses: 0,
|
|
3063
|
+
retryCount: 0
|
|
3064
|
+
};
|
|
3065
|
+
}
|
|
3066
|
+
addObserver(observer) {
|
|
3067
|
+
this.config.observers.push(observer);
|
|
3068
|
+
}
|
|
3069
|
+
removeObserver(observer) {
|
|
3070
|
+
const index = this.config.observers.indexOf(observer);
|
|
3071
|
+
if (index > -1) {
|
|
3072
|
+
this.config.observers.splice(index, 1);
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
notifyObservers(event, ...args) {
|
|
3076
|
+
for (const observer of this.config.observers) {
|
|
3077
|
+
try {
|
|
3078
|
+
const handler = observer[event];
|
|
3079
|
+
if (typeof handler === "function") {
|
|
3080
|
+
handler.apply(observer, args);
|
|
3081
|
+
}
|
|
3082
|
+
} catch (e6) {
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
generateId() {
|
|
3087
|
+
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
3088
|
+
}
|
|
3089
|
+
sleep(ms) {
|
|
3090
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3091
|
+
}
|
|
3092
|
+
}, _class11);
|
|
3093
|
+
var CircuitBreaker = (_class12 = class {
|
|
3094
|
+
constructor(config) {;_class12.prototype.__init29.call(this);_class12.prototype.__init30.call(this);_class12.prototype.__init31.call(this);
|
|
3095
|
+
this.config = config;
|
|
3096
|
+
}
|
|
3097
|
+
__init29() {this.state = "closed"}
|
|
3098
|
+
__init30() {this.failureCount = 0}
|
|
3099
|
+
__init31() {this.successCount = 0}
|
|
3100
|
+
|
|
3101
|
+
canExecute() {
|
|
3102
|
+
if (this.state === "closed") {
|
|
3103
|
+
return true;
|
|
3104
|
+
}
|
|
3105
|
+
if (this.state === "open") {
|
|
3106
|
+
if (Date.now() - (_nullishCoalesce(this.lastFailureTime, () => ( 0))) > this.config.resetTimeout) {
|
|
3107
|
+
this.state = "half-open";
|
|
3108
|
+
this.successCount = 0;
|
|
3109
|
+
return true;
|
|
3110
|
+
}
|
|
3111
|
+
return false;
|
|
3112
|
+
}
|
|
3113
|
+
return this.successCount < this.config.halfOpenMaxCalls;
|
|
3114
|
+
}
|
|
3115
|
+
recordSuccess() {
|
|
3116
|
+
if (this.state === "half-open") {
|
|
3117
|
+
this.successCount++;
|
|
3118
|
+
if (this.successCount >= this.config.halfOpenMaxCalls) {
|
|
3119
|
+
this.state = "closed";
|
|
3120
|
+
this.failureCount = 0;
|
|
3121
|
+
}
|
|
3122
|
+
} else {
|
|
3123
|
+
this.failureCount = 0;
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
recordFailure() {
|
|
3127
|
+
this.failureCount++;
|
|
3128
|
+
this.lastFailureTime = Date.now();
|
|
3129
|
+
if (this.state === "half-open" || this.failureCount >= this.config.failureThreshold) {
|
|
3130
|
+
this.state = "open";
|
|
3131
|
+
}
|
|
3132
|
+
}
|
|
3133
|
+
}, _class12);
|
|
3134
|
+
|
|
3135
|
+
// src/plugins/manager.ts
|
|
3136
|
+
var PluginManager = (_class13 = class {
|
|
3137
|
+
constructor(agent, config = {}) {;_class13.prototype.__init32.call(this);_class13.prototype.__init33.call(this);
|
|
3138
|
+
this.agent = agent;
|
|
3139
|
+
this.config = config;
|
|
3140
|
+
}
|
|
3141
|
+
__init32() {this.plugins = /* @__PURE__ */ new Map()}
|
|
3142
|
+
__init33() {this.contexts = /* @__PURE__ */ new Map()}
|
|
3143
|
+
async load(plugin, config = {}) {
|
|
3144
|
+
if (this.config.allowedPlugins && !this.config.allowedPlugins.includes(plugin.name)) {
|
|
3145
|
+
throw new Error(`Plugin '${plugin.name}' is not in the allowed list`);
|
|
3146
|
+
}
|
|
3147
|
+
const context = {
|
|
3148
|
+
agent: this.agent,
|
|
3149
|
+
registerSkill: (skill) => this.agent.registerSkill(skill),
|
|
3150
|
+
registerTool: (tool) => this.agent.registerTool(tool),
|
|
3151
|
+
registerMCPResource: (resource) => this.agent.registerMCPResource(resource),
|
|
3152
|
+
registerMCPTool: (tool) => this.agent.registerMCPTool(tool),
|
|
3153
|
+
getLLMProvider: () => this.agent.llmProvider,
|
|
3154
|
+
config
|
|
3155
|
+
};
|
|
3156
|
+
await plugin.initialize(context);
|
|
3157
|
+
this.plugins.set(plugin.name, plugin);
|
|
3158
|
+
this.contexts.set(plugin.name, context);
|
|
3159
|
+
}
|
|
3160
|
+
async unload(name) {
|
|
3161
|
+
const plugin = this.plugins.get(name);
|
|
3162
|
+
if (!plugin) {
|
|
3163
|
+
throw new Error(`Plugin '${name}' not found`);
|
|
3164
|
+
}
|
|
3165
|
+
await _optionalChain([plugin, 'access', _125 => _125.destroy, 'optionalCall', _126 => _126()]);
|
|
3166
|
+
this.plugins.delete(name);
|
|
3167
|
+
this.contexts.delete(name);
|
|
3168
|
+
}
|
|
3169
|
+
get(name) {
|
|
3170
|
+
return this.plugins.get(name);
|
|
3171
|
+
}
|
|
3172
|
+
getContext(name) {
|
|
3173
|
+
return this.contexts.get(name);
|
|
3174
|
+
}
|
|
3175
|
+
list() {
|
|
3176
|
+
return Array.from(this.plugins.values());
|
|
3177
|
+
}
|
|
3178
|
+
listNames() {
|
|
3179
|
+
return Array.from(this.plugins.keys());
|
|
3180
|
+
}
|
|
3181
|
+
isLoaded(name) {
|
|
3182
|
+
return this.plugins.has(name);
|
|
3183
|
+
}
|
|
3184
|
+
async reload(name) {
|
|
3185
|
+
const plugin = this.plugins.get(name);
|
|
3186
|
+
if (!plugin) {
|
|
3187
|
+
throw new Error(`Plugin '${name}' not found`);
|
|
3188
|
+
}
|
|
3189
|
+
const context = this.contexts.get(name);
|
|
3190
|
+
if (!context) {
|
|
3191
|
+
throw new Error(`Context for plugin '${name}' not found`);
|
|
3192
|
+
}
|
|
3193
|
+
await _optionalChain([plugin, 'access', _127 => _127.destroy, 'optionalCall', _128 => _128()]);
|
|
3194
|
+
await plugin.initialize(context);
|
|
3195
|
+
}
|
|
3196
|
+
async unloadAll() {
|
|
3197
|
+
for (const [name] of this.plugins) {
|
|
3198
|
+
await this.unload(name);
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
getStats() {
|
|
3202
|
+
return {
|
|
3203
|
+
total: this.plugins.size,
|
|
3204
|
+
withDestroy: this.list().filter((p) => p.destroy !== void 0).length
|
|
3205
|
+
};
|
|
3206
|
+
}
|
|
3207
|
+
}, _class13);
|
|
3208
|
+
var PluginLoader = (_class14 = class {constructor() { _class14.prototype.__init34.call(this); }
|
|
3209
|
+
__init34() {this.factories = /* @__PURE__ */ new Map()}
|
|
3210
|
+
registerFactory(type, factory) {
|
|
3211
|
+
this.factories.set(type, factory);
|
|
3212
|
+
}
|
|
3213
|
+
async loadFromSource(type, source, config = {}) {
|
|
3214
|
+
const factory = this.factories.get(type);
|
|
3215
|
+
if (!factory) {
|
|
3216
|
+
throw new Error(`Unknown plugin type: ${type}`);
|
|
3217
|
+
}
|
|
3218
|
+
const pluginConfig = await this.loadConfig(source);
|
|
3219
|
+
return factory.create({ ...pluginConfig, ...config });
|
|
3220
|
+
}
|
|
3221
|
+
async loadConfig(source) {
|
|
3222
|
+
if (source.startsWith("http")) {
|
|
3223
|
+
const response = await fetch(source);
|
|
3224
|
+
return response.json();
|
|
3225
|
+
}
|
|
3226
|
+
throw new Error(
|
|
3227
|
+
"Loading config from file path is not supported. Use a URL (http/https) or pass config object directly."
|
|
3228
|
+
);
|
|
3229
|
+
}
|
|
3230
|
+
}, _class14);
|
|
3231
|
+
|
|
3232
|
+
// src/index.ts
|
|
3233
|
+
var VERSION = "1.0.0";
|
|
3234
|
+
var isBrowser = typeof window !== "undefined";
|
|
3235
|
+
var isNode = typeof window === "undefined";
|
|
3236
|
+
|
|
3237
|
+
|
|
3238
|
+
|
|
3239
|
+
|
|
3240
|
+
|
|
3241
|
+
|
|
3242
|
+
|
|
3243
|
+
|
|
3244
|
+
|
|
3245
|
+
|
|
3246
|
+
|
|
3247
|
+
|
|
3248
|
+
|
|
3249
|
+
|
|
3250
|
+
|
|
3251
|
+
|
|
3252
|
+
|
|
3253
|
+
|
|
3254
|
+
|
|
3255
|
+
|
|
3256
|
+
|
|
3257
|
+
|
|
3258
|
+
|
|
3259
|
+
|
|
3260
|
+
|
|
3261
|
+
|
|
3262
|
+
|
|
3263
|
+
|
|
3264
|
+
|
|
3265
|
+
|
|
3266
|
+
|
|
3267
|
+
|
|
3268
|
+
|
|
3269
|
+
|
|
3270
|
+
|
|
3271
|
+
|
|
3272
|
+
|
|
3273
|
+
|
|
3274
|
+
|
|
3275
|
+
|
|
3276
|
+
|
|
3277
|
+
|
|
3278
|
+
|
|
3279
|
+
|
|
3280
|
+
|
|
3281
|
+
|
|
3282
|
+
|
|
3283
|
+
|
|
3284
|
+
|
|
3285
|
+
|
|
3286
|
+
|
|
3287
|
+
|
|
3288
|
+
|
|
3289
|
+
|
|
3290
|
+
|
|
3291
|
+
|
|
3292
|
+
exports.AdvancedDecisionEngine = AdvancedDecisionEngine; exports.Agent = Agent; exports.AnthropicProvider = _chunkMTFOABGCcjs.AnthropicProvider; exports.BrowserStorageAdapter = _chunkJF33ZOMBcjs.BrowserStorageAdapter; exports.DecisionEngine = DecisionEngine; exports.DeepSeekProvider = _chunkMTFOABGCcjs.DeepSeekProvider; exports.DoubaoProvider = _chunkMTFOABGCcjs.DoubaoProvider; exports.DynamicSkillLoader = DynamicSkillLoader; exports.EnhancedSkillExecutor = _chunkYDHQCPSNcjs.EnhancedSkillExecutor; exports.EvaluationEngine = EvaluationEngine; exports.ExactMatchEvaluator = ExactMatchEvaluator; exports.ExecutionEngine = ExecutionEngine; exports.GeminiProvider = _chunkMTFOABGCcjs.GeminiProvider; exports.LLMManager = _chunkMTFOABGCcjs.LLMManager; exports.LLMProviderRegistry = _chunkMTFOABGCcjs.LLMProviderRegistry; exports.MCPClient = _chunkIYG37UN3cjs.MCPClient; exports.MCPServer = _chunkIYG37UN3cjs.MCPServer; exports.MiniMaxProvider = _chunkMTFOABGCcjs.MiniMaxProvider; exports.MoonshotProvider = _chunkMTFOABGCcjs.MoonshotProvider; exports.NodeStorageAdapter = _chunkJF33ZOMBcjs.NodeStorageAdapter; exports.OpenAIProvider = _chunkMTFOABGCcjs.OpenAIProvider; exports.ParameterExtractor = ParameterExtractor; exports.PluginLoader = PluginLoader; exports.PluginManager = PluginManager; exports.QwenProvider = _chunkMTFOABGCcjs.QwenProvider; exports.SchemaValidator = SchemaValidator; exports.SemanticEvaluator = SemanticEvaluator; exports.SimpleEmbeddingProvider = SimpleEmbeddingProvider; exports.SkillRegistry = _chunkYDHQCPSNcjs.SkillRegistry; exports.SkillResourceManager = _chunkYDHQCPSNcjs.SkillResourceManager; exports.SkillScriptExecutor = _chunkYDHQCPSNcjs.SkillScriptExecutor; exports.SmartAgent = SmartAgent; exports.TokenOptimizer = TokenOptimizer; exports.ToolRegistry = _chunkKXXS33G3cjs.ToolRegistry; exports.VERSION = VERSION; exports.ZhipuProvider = _chunkMTFOABGCcjs.ZhipuProvider; exports.builtInSkills = _chunkYDHQCPSNcjs.builtInSkills; exports.builtInSkillsMap = _chunkYDHQCPSNcjs.builtInSkillsMap; exports.builtInTools = _chunkKXXS33G3cjs.builtInTools; exports.createSkillFromManifest = _chunkYDHQCPSNcjs.createSkillFromManifest; exports.createStorage = _chunkJF33ZOMBcjs.createStorage; exports.echoSkill = _chunkYDHQCPSNcjs.echoSkill; exports.fileReadTool = _chunkKXXS33G3cjs.fileReadTool; exports.fileWriteTool = _chunkKXXS33G3cjs.fileWriteTool; exports.getDefaultStorage = _chunkJF33ZOMBcjs.getDefaultStorage; exports.globalProviderRegistry = _chunkMTFOABGCcjs.globalProviderRegistry; exports.httpRequestTool = _chunkKXXS33G3cjs.httpRequestTool; exports.isBrowser = isBrowser; exports.isNode = isNode; exports.listSkillsSkill = _chunkYDHQCPSNcjs.listSkillsSkill; exports.loadSkillFromDirectory = _chunkYDHQCPSNcjs.loadSkillFromDirectory; exports.mathSkill = _chunkYDHQCPSNcjs.mathSkill; exports.parseSkillMd = _chunkYDHQCPSNcjs.parseSkillMd; exports.resetDefaultStorage = _chunkJF33ZOMBcjs.resetDefaultStorage; exports.validateManifest = _chunkYDHQCPSNcjs.validateManifest;
|
|
3293
|
+
//# sourceMappingURL=index.cjs.map
|