skyloom 1.7.0 → 1.9.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/config/skills/api_integrator/SKILL.md +15 -0
- package/config/skills/arch_designer/SKILL.md +13 -0
- package/config/skills/ci_cd_manager/SKILL.md +14 -0
- package/config/skills/code_analysis/SKILL.md +13 -0
- package/config/skills/code_generator/SKILL.md +12 -0
- package/config/skills/code_reviewer/SKILL.md +13 -0
- package/config/skills/content_writer/SKILL.md +14 -0
- package/config/skills/data_transformer/SKILL.md +15 -0
- package/config/skills/document_analysis/SKILL.md +13 -0
- package/config/skills/emotional_companion/SKILL.md +15 -0
- package/config/skills/performance_checker/SKILL.md +14 -0
- package/config/skills/security_auditor/SKILL.md +14 -0
- package/config/skills/self_evolve/SKILL.md +13 -0
- package/config/skills/sys_operator/SKILL.md +15 -0
- package/config/skills/task_planner/SKILL.md +14 -0
- package/config/skills/web_research/SKILL.md +14 -0
- package/config/skills/workflow_designer/SKILL.md +13 -0
- package/dist/cli/main.js +15 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +35 -0
- package/dist/core/agent.js.map +1 -1
- package/dist/core/evolve.d.ts +43 -0
- package/dist/core/evolve.d.ts.map +1 -0
- package/dist/core/evolve.js +201 -0
- package/dist/core/evolve.js.map +1 -0
- package/dist/core/graph.d.ts +49 -0
- package/dist/core/graph.d.ts.map +1 -0
- package/dist/core/graph.js +182 -0
- package/dist/core/graph.js.map +1 -0
- package/dist/core/sandbox.d.ts +24 -0
- package/dist/core/sandbox.d.ts.map +1 -0
- package/dist/core/sandbox.js +158 -0
- package/dist/core/sandbox.js.map +1 -0
- package/dist/core/vector.d.ts +43 -0
- package/dist/core/vector.d.ts.map +1 -0
- package/dist/core/vector.js +150 -0
- package/dist/core/vector.js.map +1 -0
- package/dist/tools/builtin.d.ts.map +1 -1
- package/dist/tools/builtin.js +3 -3
- package/dist/tools/builtin.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/main.ts +16 -0
- package/src/core/agent.ts +30 -0
- package/src/core/evolve.ts +191 -0
- package/src/core/graph.ts +156 -0
- package/src/core/sandbox.ts +142 -0
- package/src/core/vector.ts +152 -0
- package/src/tools/builtin.ts +4 -6
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 简易知识图谱 — entity-relation storage in SQLite.
|
|
4
|
+
*
|
|
5
|
+
* Lightweight triple store: (subject, predicate, object) with metadata.
|
|
6
|
+
* Used for: project info, tool preferences, dependency relationships.
|
|
7
|
+
*
|
|
8
|
+
* Schema:
|
|
9
|
+
* CREATE TABLE triples (subj, pred, obj, agent, ts, meta)
|
|
10
|
+
*
|
|
11
|
+
* Queries:
|
|
12
|
+
* - Find all relations for an entity
|
|
13
|
+
* - Find all entities matching a predicate
|
|
14
|
+
* - Transitive closure (2-hop max for performance)
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.KnowledgeGraph = void 0;
|
|
51
|
+
exports.extractFacts = extractFacts;
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const config_1 = require("./config");
|
|
55
|
+
const logger_1 = require("./logger");
|
|
56
|
+
const log = (0, logger_1.getLogger)("graph");
|
|
57
|
+
class KnowledgeGraph {
|
|
58
|
+
constructor(name = "default") {
|
|
59
|
+
this.triples = [];
|
|
60
|
+
this.indexPath = path.join(config_1.USER_CONFIG_DIR, `kg_${name}.json`);
|
|
61
|
+
this.load();
|
|
62
|
+
}
|
|
63
|
+
/** Add a fact: (subject, predicate, object). */
|
|
64
|
+
add(subj, pred, obj, agent = "system", meta) {
|
|
65
|
+
// Deduplicate
|
|
66
|
+
const exists = this.triples.find(t => t.subj === subj && t.pred === pred && t.obj === obj);
|
|
67
|
+
if (exists) {
|
|
68
|
+
exists.ts = new Date().toISOString();
|
|
69
|
+
if (meta)
|
|
70
|
+
exists.meta = { ...exists.meta, ...meta };
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.triples.push({ subj, pred, obj, agent, ts: new Date().toISOString(), meta });
|
|
74
|
+
if (this.triples.length > 5000)
|
|
75
|
+
this.triples.splice(0, this.triples.length - 5000);
|
|
76
|
+
this.save();
|
|
77
|
+
}
|
|
78
|
+
/** Find all facts about an entity. */
|
|
79
|
+
about(entity, limit = 20) {
|
|
80
|
+
return this.triples.filter(t => t.subj === entity || t.obj === entity).slice(-limit);
|
|
81
|
+
}
|
|
82
|
+
/** Find all subjects matching a predicate. */
|
|
83
|
+
byPredicate(pred) {
|
|
84
|
+
return this.triples.filter(t => t.pred === pred);
|
|
85
|
+
}
|
|
86
|
+
/** Find all objects for a subject-predicate pair. */
|
|
87
|
+
find(subj, pred) {
|
|
88
|
+
return this.triples.filter(t => t.subj === subj && t.pred === pred);
|
|
89
|
+
}
|
|
90
|
+
/** Transitive expansion: 2-hop from a starting entity. */
|
|
91
|
+
expand(entity, maxDepth = 2) {
|
|
92
|
+
const seen = new Set();
|
|
93
|
+
const queue = [entity];
|
|
94
|
+
for (let depth = 0; depth < maxDepth && queue.length > 0; depth++) {
|
|
95
|
+
const current = queue.shift();
|
|
96
|
+
const facts = this.about(current, 10);
|
|
97
|
+
for (const f of facts) {
|
|
98
|
+
if (seen.has(f))
|
|
99
|
+
continue;
|
|
100
|
+
seen.add(f);
|
|
101
|
+
if (f.subj === current && !queue.includes(f.obj))
|
|
102
|
+
queue.push(f.obj);
|
|
103
|
+
if (f.obj === current && !queue.includes(f.subj))
|
|
104
|
+
queue.push(f.subj);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return Array.from(seen);
|
|
108
|
+
}
|
|
109
|
+
/** Remove a fact. */
|
|
110
|
+
remove(subj, pred, obj) {
|
|
111
|
+
this.triples = this.triples.filter(t => !(t.subj === subj && t.pred === pred && t.obj === obj));
|
|
112
|
+
this.save();
|
|
113
|
+
}
|
|
114
|
+
/** Search for entities or predicates containing a keyword. */
|
|
115
|
+
search(keyword, limit = 15) {
|
|
116
|
+
const k = keyword.toLowerCase();
|
|
117
|
+
return this.triples.filter(t => t.subj.toLowerCase().includes(k) || t.pred.toLowerCase().includes(k) || t.obj.toLowerCase().includes(k)).slice(-limit);
|
|
118
|
+
}
|
|
119
|
+
/** Format facts as readable text. */
|
|
120
|
+
format(entity) {
|
|
121
|
+
const facts = entity ? this.about(entity) : this.triples.slice(-30);
|
|
122
|
+
if (facts.length === 0)
|
|
123
|
+
return "(no facts)";
|
|
124
|
+
const bySubj = new Map();
|
|
125
|
+
for (const f of facts) {
|
|
126
|
+
if (!bySubj.has(f.subj))
|
|
127
|
+
bySubj.set(f.subj, []);
|
|
128
|
+
bySubj.get(f.subj).push(`${f.pred} → ${f.obj}`);
|
|
129
|
+
}
|
|
130
|
+
const lines = [];
|
|
131
|
+
for (const [subj, preds] of bySubj) {
|
|
132
|
+
lines.push(`**${subj}**: ${preds.join(", ")}`);
|
|
133
|
+
}
|
|
134
|
+
return lines.join("\n");
|
|
135
|
+
}
|
|
136
|
+
get size() { return this.triples.length; }
|
|
137
|
+
save() {
|
|
138
|
+
try {
|
|
139
|
+
const dir = path.dirname(this.indexPath);
|
|
140
|
+
if (!fs.existsSync(dir))
|
|
141
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
142
|
+
fs.writeFileSync(this.indexPath, JSON.stringify(this.triples.slice(-2000)), "utf-8");
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
log.warn("kg_save_failed", { error: String(e) });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
load() {
|
|
149
|
+
try {
|
|
150
|
+
if (fs.existsSync(this.indexPath)) {
|
|
151
|
+
this.triples = JSON.parse(fs.readFileSync(this.indexPath, "utf-8"));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
this.triples = [];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.KnowledgeGraph = KnowledgeGraph;
|
|
160
|
+
/* ── Auto-extract facts from conversation ── */
|
|
161
|
+
const RELATION_PATTERNS = [
|
|
162
|
+
[/(\w+) (?:是|为|属于|使用|用|用到了|采用) (.+?)(?:[。,,.\n]|$)/g, "is"],
|
|
163
|
+
[/(\w+) (?:版本|version|v) (?:是|为)? ?(\d[\d.]*)/gi, "version"],
|
|
164
|
+
[/(\w+) (?:depends|依赖|需要|requires) (\w+)/gi, "depends_on"],
|
|
165
|
+
[/(\w+) (?:config|配置) (?:为|是)? (.+?)(?:[。,,.\n]|$)/gi, "config"],
|
|
166
|
+
[/(\w+) (?:file|path|文件|路径) (?:在|为|at) (.+?)(?:[。,,.\n]|$)/gi, "located_at"],
|
|
167
|
+
];
|
|
168
|
+
function extractFacts(text, agent) {
|
|
169
|
+
const facts = [];
|
|
170
|
+
for (const [pattern, pred] of RELATION_PATTERNS) {
|
|
171
|
+
let match;
|
|
172
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
173
|
+
const subj = match[1].trim().toLowerCase();
|
|
174
|
+
const obj = match[2].trim();
|
|
175
|
+
if (subj.length >= 2 && obj.length >= 2 && subj !== obj) {
|
|
176
|
+
facts.push([subj, pred, obj]);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return facts;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/core/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 沙箱隔离模块 — Shell execution sandbox with resource limits.
|
|
3
|
+
*
|
|
4
|
+
* All `run_bash` / `shell_exec` commands are wrapped through this module
|
|
5
|
+
* to ensure: temp directory isolation, timeout enforcement, output size
|
|
6
|
+
* limits, and dangerous command detection BEFORE execution.
|
|
7
|
+
*/
|
|
8
|
+
export interface SandboxResult {
|
|
9
|
+
success: boolean;
|
|
10
|
+
stdout: string;
|
|
11
|
+
stderr: string;
|
|
12
|
+
exitCode: number;
|
|
13
|
+
killed: boolean;
|
|
14
|
+
durationMs: number;
|
|
15
|
+
sandboxDir: string;
|
|
16
|
+
checkFailed?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function runInSandbox(command: string, opts?: {
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
cwd?: string;
|
|
21
|
+
env?: Record<string, string>;
|
|
22
|
+
}): SandboxResult;
|
|
23
|
+
export declare function formatSandboxResult(r: SandboxResult): string;
|
|
24
|
+
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/core/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+DH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,GAAG,aAAa,CAyChB;AAKD,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAW5D"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 沙箱隔离模块 — Shell execution sandbox with resource limits.
|
|
4
|
+
*
|
|
5
|
+
* All `run_bash` / `shell_exec` commands are wrapped through this module
|
|
6
|
+
* to ensure: temp directory isolation, timeout enforcement, output size
|
|
7
|
+
* limits, and dangerous command detection BEFORE execution.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.runInSandbox = runInSandbox;
|
|
44
|
+
exports.formatSandboxResult = formatSandboxResult;
|
|
45
|
+
const child_process_1 = require("child_process");
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const os = __importStar(require("os"));
|
|
49
|
+
const logger_1 = require("./logger");
|
|
50
|
+
const security_1 = require("./security");
|
|
51
|
+
const log = (0, logger_1.getLogger)("sandbox");
|
|
52
|
+
/* ═══════════════════════════════════════
|
|
53
|
+
Configuration
|
|
54
|
+
═══════════════════════════════════════ */
|
|
55
|
+
const SANDBOX_DIR = path.join(os.homedir(), ".skyloom", "sandbox");
|
|
56
|
+
const DEFAULT_TIMEOUT_MS = 30000; // 30s max
|
|
57
|
+
const MAX_OUTPUT_BYTES = 1024 * 1024; // 1MB max output
|
|
58
|
+
const HARD_TIMEOUT_MS = 120000; // 2min absolute max
|
|
59
|
+
// Whitelist of safe commands that don't need sandbox
|
|
60
|
+
const SAFE_COMMANDS = new Set(["echo", "pwd", "whoami", "date", "hostname", "uname", "ls", "dir", "cat", "head", "tail", "wc", "env", "printenv"]);
|
|
61
|
+
/* ═══════════════════════════════════════
|
|
62
|
+
Sandbox lifecycle
|
|
63
|
+
═══════════════════════════════════════ */
|
|
64
|
+
function ensureSandbox() {
|
|
65
|
+
if (!fs.existsSync(SANDBOX_DIR))
|
|
66
|
+
fs.mkdirSync(SANDBOX_DIR, { recursive: true });
|
|
67
|
+
// Create named temp dir for this execution
|
|
68
|
+
const id = Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
|
|
69
|
+
const dir = path.join(SANDBOX_DIR, `job_${id}`);
|
|
70
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
71
|
+
return dir;
|
|
72
|
+
}
|
|
73
|
+
function cleanup(dir) {
|
|
74
|
+
try {
|
|
75
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
76
|
+
}
|
|
77
|
+
catch { /* ignore */ }
|
|
78
|
+
}
|
|
79
|
+
/* ═══════════════════════════════════════
|
|
80
|
+
Pre-execution check
|
|
81
|
+
═══════════════════════════════════════ */
|
|
82
|
+
function preflightCheck(command) {
|
|
83
|
+
if (!command || !command.trim())
|
|
84
|
+
return "Empty command";
|
|
85
|
+
const lower = command.toLowerCase().trim();
|
|
86
|
+
// Red-line patterns
|
|
87
|
+
for (const pattern of security_1.REDLINE_PATTERNS) {
|
|
88
|
+
if (pattern.test(lower))
|
|
89
|
+
return `REDLINE: pattern '${pattern.source.slice(0, 40)}' detected`;
|
|
90
|
+
}
|
|
91
|
+
for (const forbidden of security_1.REDLINE_COMMANDS) {
|
|
92
|
+
if (lower.includes(forbidden))
|
|
93
|
+
return `REDLINE: forbidden command '${forbidden}'`;
|
|
94
|
+
}
|
|
95
|
+
// Network exfiltration attempts
|
|
96
|
+
if (/curl.*\|.*nc\s/.test(lower) || /wget.*-O.*>/.test(lower))
|
|
97
|
+
return "BLOCKED: potential data exfiltration";
|
|
98
|
+
if (/nc\s+\S+\s+\d+/.test(lower) && /\|/.test(lower))
|
|
99
|
+
return "BLOCKED: potential reverse shell";
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
function runInSandbox(command, opts) {
|
|
103
|
+
// Pre-flight
|
|
104
|
+
const check = preflightCheck(command);
|
|
105
|
+
if (check) {
|
|
106
|
+
return { success: false, stdout: "", stderr: check, exitCode: -1, killed: false, durationMs: 0, sandboxDir: "", checkFailed: check };
|
|
107
|
+
}
|
|
108
|
+
const dir = ensureSandbox();
|
|
109
|
+
const timeout = Math.min(opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS, HARD_TIMEOUT_MS);
|
|
110
|
+
const t0 = Date.now();
|
|
111
|
+
try {
|
|
112
|
+
// For safe commands, run in-place without sandbox overhead
|
|
113
|
+
const firstWord = command.trim().split(/\s+/)[0].toLowerCase();
|
|
114
|
+
if (SAFE_COMMANDS.has(firstWord)) {
|
|
115
|
+
const result = (0, child_process_1.execSync)(command, { encoding: "utf-8", timeout, maxBuffer: MAX_OUTPUT_BYTES, cwd: opts?.cwd || dir, env: { ...process.env, ...(opts?.env || {}) } });
|
|
116
|
+
cleanup(dir);
|
|
117
|
+
return { success: true, stdout: result.slice(0, MAX_OUTPUT_BYTES), stderr: "", exitCode: 0, killed: false, durationMs: Date.now() - t0, sandboxDir: dir };
|
|
118
|
+
}
|
|
119
|
+
// Dangerous command — run in sandbox with isolation
|
|
120
|
+
const result = (0, child_process_1.execSync)(command, {
|
|
121
|
+
encoding: "utf-8",
|
|
122
|
+
timeout,
|
|
123
|
+
maxBuffer: MAX_OUTPUT_BYTES,
|
|
124
|
+
cwd: dir, // isolate to temp dir
|
|
125
|
+
env: { ...process.env, ...(opts?.env || {}), TMPDIR: dir, TEMP: dir },
|
|
126
|
+
windowsHide: true,
|
|
127
|
+
});
|
|
128
|
+
cleanup(dir);
|
|
129
|
+
return { success: true, stdout: result.slice(0, MAX_OUTPUT_BYTES), stderr: "", exitCode: 0, killed: false, durationMs: Date.now() - t0, sandboxDir: dir };
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
const durationMs = Date.now() - t0;
|
|
133
|
+
const killed = e.killed || e.signal !== undefined || durationMs >= timeout;
|
|
134
|
+
const stdout = (e.stdout || "").slice(0, MAX_OUTPUT_BYTES);
|
|
135
|
+
const stderr = (e.stderr || e.message || "").slice(0, MAX_OUTPUT_BYTES);
|
|
136
|
+
cleanup(dir);
|
|
137
|
+
return { success: false, stdout, stderr, exitCode: e.status || -1, killed, durationMs, sandboxDir: dir };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/* ═══════════════════════════════════════
|
|
141
|
+
Format result for display
|
|
142
|
+
═══════════════════════════════════════ */
|
|
143
|
+
function formatSandboxResult(r) {
|
|
144
|
+
if (r.checkFailed)
|
|
145
|
+
return `[BLOCKED] ${r.checkFailed}`;
|
|
146
|
+
const parts = [];
|
|
147
|
+
if (r.stdout)
|
|
148
|
+
parts.push(r.stdout);
|
|
149
|
+
if (r.stderr)
|
|
150
|
+
parts.push(`[stderr]\n${r.stderr}`);
|
|
151
|
+
if (r.killed)
|
|
152
|
+
parts.push(`[killed after ${r.durationMs}ms]`);
|
|
153
|
+
if (r.exitCode !== 0)
|
|
154
|
+
parts.push(`[exit code: ${r.exitCode}]`);
|
|
155
|
+
parts.push(`[sandbox: ${r.sandboxDir || "n/a"} · ${r.durationMs}ms]`);
|
|
156
|
+
return parts.join("\n");
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/core/sandbox.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EH,oCA6CC;AAKD,kDAWC;AArID,iDAA+C;AAC/C,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AACzB,qCAAqC;AACrC,yCAAgE;AAEhE,MAAM,GAAG,GAAG,IAAA,kBAAS,EAAC,SAAS,CAAC,CAAC;AAEjC;;6CAE6C;AAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AACnE,MAAM,kBAAkB,GAAG,KAAK,CAAC,CAAE,UAAU;AAC7C,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,iBAAiB;AACvD,MAAM,eAAe,GAAG,MAAM,CAAC,CAAM,oBAAoB;AACzD,qDAAqD;AACrD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;AAEnJ;;6CAE6C;AAC7C,SAAS,aAAa;IACpB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,2CAA2C;IAC3C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IAChD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,CAAC;QAAC,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;AAClF,CAAC;AAED;;6CAE6C;AAC7C,SAAS,cAAc,CAAC,OAAe;IACrC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;QAAE,OAAO,eAAe,CAAC;IAExD,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAE3C,oBAAoB;IACpB,KAAK,MAAM,OAAO,IAAI,2BAAgB,EAAE,CAAC;QACvC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,qBAAqB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC;IAC/F,CAAC;IACD,KAAK,MAAM,SAAS,IAAI,2BAAgB,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,OAAO,+BAA+B,SAAS,GAAG,CAAC;IACpF,CAAC;IAED,gCAAgC;IAChC,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,sCAAsC,CAAC;IAC7G,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,kCAAkC,CAAC;IAEhG,OAAO,IAAI,CAAC;AACd,CAAC;AAgBD,SAAgB,YAAY,CAAC,OAAe,EAAE,IAI7C;IACC,aAAa;IACb,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACvI,CAAC;IAED,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,IAAI,kBAAkB,EAAE,eAAe,CAAC,CAAC;IACjF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEtB,IAAI,CAAC;QACH,2DAA2D;QAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/D,IAAI,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACpK,OAAO,CAAC,GAAG,CAAC,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;QAC5J,CAAC;QAED,oDAAoD;QACpD,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,OAAO,EAAE;YAC/B,QAAQ,EAAE,OAAO;YACjB,OAAO;YACP,SAAS,EAAE,gBAAgB;YAC3B,GAAG,EAAE,GAAG,EAAqB,sBAAsB;YACnD,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE;YACrE,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IAE5J,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,UAAU,IAAI,OAAO,CAAC;QAC3E,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IAC3G,CAAC;AACH,CAAC;AAED;;6CAE6C;AAC7C,SAAgB,mBAAmB,CAAC,CAAgB;IAClD,IAAI,CAAC,CAAC,WAAW;QAAE,OAAO,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;IAEvD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,CAAC,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC;IAC7D,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;IAE/D,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,UAAU,IAAI,KAAK,MAAM,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC;IACtE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 向量语义搜索 — TF-IDF + Cosine similarity, zero dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Replaces n-gram Jaccard as the default semantic scorer.
|
|
5
|
+
* - IDF pre-computed from document corpus
|
|
6
|
+
* - Cosine similarity on TF-IDF vectors
|
|
7
|
+
* - CJK-aware tokenization (bigram for CJK, whitespace for ASCII)
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* const idx = new VectorIndex();
|
|
11
|
+
* idx.addDocuments(docs);
|
|
12
|
+
* const results = idx.search("deploy script", 5);
|
|
13
|
+
*/
|
|
14
|
+
interface DocVector {
|
|
15
|
+
id: string;
|
|
16
|
+
tf: Map<string, number>;
|
|
17
|
+
norm: number;
|
|
18
|
+
content: string;
|
|
19
|
+
meta?: Record<string, any>;
|
|
20
|
+
}
|
|
21
|
+
export declare class VectorIndex {
|
|
22
|
+
private docs;
|
|
23
|
+
private idf;
|
|
24
|
+
private totalDocs;
|
|
25
|
+
/** Add a document to the index. */
|
|
26
|
+
addDocument(id: string, content: string, meta?: Record<string, any>): void;
|
|
27
|
+
addDocuments(docs: Array<{
|
|
28
|
+
id: string;
|
|
29
|
+
content: string;
|
|
30
|
+
meta?: Record<string, any>;
|
|
31
|
+
}>): void;
|
|
32
|
+
private docFrequency;
|
|
33
|
+
/** Search for documents similar to query. Returns [score, doc] pairs. */
|
|
34
|
+
search(query: string, topK?: number, minScore?: number): Array<[number, DocVector]>;
|
|
35
|
+
/** Remove a document by ID. */
|
|
36
|
+
removeDocument(id: string): void;
|
|
37
|
+
get size(): number;
|
|
38
|
+
clear(): void;
|
|
39
|
+
}
|
|
40
|
+
export declare function getVectorIndex(): VectorIndex;
|
|
41
|
+
export declare function resetVectorIndex(): void;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=vector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector.d.ts","sourceRoot":"","sources":["../../src/core/vector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA+BH,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,GAAG,CAAkC;IAC7C,OAAO,CAAC,SAAS,CAAK;IAEtB,mCAAmC;IACnC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IA0B1E,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,CAAC,GAAG,IAAI;IAI5F,OAAO,CAAC,YAAY;IAMpB,yEAAyE;IACzE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU,EAAE,QAAQ,GAAE,MAAa,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAkC5F,+BAA+B;IAC/B,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKhC,IAAI,IAAI,IAAI,MAAM,CAA6B;IAE/C,KAAK,IAAI,IAAI;CACd;AAOD,wBAAgB,cAAc,IAAI,WAAW,CAG5C;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 向量语义搜索 — TF-IDF + Cosine similarity, zero dependencies.
|
|
4
|
+
*
|
|
5
|
+
* Replaces n-gram Jaccard as the default semantic scorer.
|
|
6
|
+
* - IDF pre-computed from document corpus
|
|
7
|
+
* - Cosine similarity on TF-IDF vectors
|
|
8
|
+
* - CJK-aware tokenization (bigram for CJK, whitespace for ASCII)
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* const idx = new VectorIndex();
|
|
12
|
+
* idx.addDocuments(docs);
|
|
13
|
+
* const results = idx.search("deploy script", 5);
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.VectorIndex = void 0;
|
|
17
|
+
exports.getVectorIndex = getVectorIndex;
|
|
18
|
+
exports.resetVectorIndex = resetVectorIndex;
|
|
19
|
+
/* ═══════════════════════════════════════
|
|
20
|
+
Tokenizer — CJK-aware
|
|
21
|
+
═══════════════════════════════════════ */
|
|
22
|
+
const CJK = /[一-鿿-ゟ가-]/;
|
|
23
|
+
function tokenize(text) {
|
|
24
|
+
const tokens = [];
|
|
25
|
+
let i = 0;
|
|
26
|
+
while (i < text.length) {
|
|
27
|
+
if (CJK.test(text[i])) {
|
|
28
|
+
if (i + 1 < text.length && CJK.test(text[i + 1])) {
|
|
29
|
+
tokens.push(text.slice(i, i + 2));
|
|
30
|
+
i += 2;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
tokens.push(text[i]);
|
|
34
|
+
i++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (/[A-Za-z0-9_]/.test(text[i])) {
|
|
38
|
+
let j = i;
|
|
39
|
+
while (j < text.length && /[A-Za-z0-9_]/.test(text[j]))
|
|
40
|
+
j++;
|
|
41
|
+
tokens.push(text.slice(i, j).toLowerCase());
|
|
42
|
+
i = j;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
i++;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return tokens;
|
|
49
|
+
}
|
|
50
|
+
class VectorIndex {
|
|
51
|
+
constructor() {
|
|
52
|
+
this.docs = [];
|
|
53
|
+
this.idf = new Map();
|
|
54
|
+
this.totalDocs = 0;
|
|
55
|
+
}
|
|
56
|
+
/** Add a document to the index. */
|
|
57
|
+
addDocument(id, content, meta) {
|
|
58
|
+
const tokens = tokenize(content);
|
|
59
|
+
const tf = new Map();
|
|
60
|
+
for (const t of tokens) {
|
|
61
|
+
tf.set(t, (tf.get(t) || 0) + 1);
|
|
62
|
+
}
|
|
63
|
+
// Normalize by doc length
|
|
64
|
+
const tfIdf = new Map();
|
|
65
|
+
let normSq = 0;
|
|
66
|
+
for (const [term, freq] of tf) {
|
|
67
|
+
const tfVal = freq / tokens.length;
|
|
68
|
+
const idfVal = this.idf.get(term) || 0;
|
|
69
|
+
const val = tfVal * Math.max(0.1, idfVal);
|
|
70
|
+
tfIdf.set(term, val);
|
|
71
|
+
normSq += val * val;
|
|
72
|
+
}
|
|
73
|
+
const norm = Math.sqrt(normSq);
|
|
74
|
+
this.docs.push({ id, tf: tfIdf, norm, content: content.slice(0, 500), meta });
|
|
75
|
+
this.totalDocs++;
|
|
76
|
+
// Update IDF
|
|
77
|
+
for (const term of tf.keys()) {
|
|
78
|
+
this.idf.set(term, Math.log((this.totalDocs + 1) / ((this.docFrequency(term) + 1))));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
addDocuments(docs) {
|
|
82
|
+
for (const d of docs)
|
|
83
|
+
this.addDocument(d.id, d.content, d.meta);
|
|
84
|
+
}
|
|
85
|
+
docFrequency(term) {
|
|
86
|
+
let count = 0;
|
|
87
|
+
for (const d of this.docs) {
|
|
88
|
+
if (d.tf.has(term))
|
|
89
|
+
count++;
|
|
90
|
+
}
|
|
91
|
+
return count;
|
|
92
|
+
}
|
|
93
|
+
/** Search for documents similar to query. Returns [score, doc] pairs. */
|
|
94
|
+
search(query, topK = 5, minScore = 0.01) {
|
|
95
|
+
const queryTokens = tokenize(query);
|
|
96
|
+
const queryTf = new Map();
|
|
97
|
+
for (const t of queryTokens) {
|
|
98
|
+
queryTf.set(t, (queryTf.get(t) || 0) + 1);
|
|
99
|
+
}
|
|
100
|
+
// Query vector
|
|
101
|
+
const qv = new Map();
|
|
102
|
+
let qNormSq = 0;
|
|
103
|
+
for (const [term, freq] of queryTf) {
|
|
104
|
+
const tfVal = freq / queryTokens.length;
|
|
105
|
+
const idfVal = this.idf.get(term) || 0;
|
|
106
|
+
const val = tfVal * Math.max(0.1, idfVal);
|
|
107
|
+
qv.set(term, val);
|
|
108
|
+
qNormSq += val * val;
|
|
109
|
+
}
|
|
110
|
+
const qNorm = Math.sqrt(qNormSq);
|
|
111
|
+
if (qNorm === 0)
|
|
112
|
+
return [];
|
|
113
|
+
// Cosine similarity against all docs
|
|
114
|
+
const scored = [];
|
|
115
|
+
for (const doc of this.docs) {
|
|
116
|
+
if (doc.norm === 0)
|
|
117
|
+
continue;
|
|
118
|
+
let dot = 0;
|
|
119
|
+
for (const [term, qVal] of qv) {
|
|
120
|
+
dot += qVal * (doc.tf.get(term) || 0);
|
|
121
|
+
}
|
|
122
|
+
const score = dot / (qNorm * doc.norm);
|
|
123
|
+
if (score >= minScore)
|
|
124
|
+
scored.push([score, doc]);
|
|
125
|
+
}
|
|
126
|
+
scored.sort((a, b) => b[0] - a[0]);
|
|
127
|
+
return scored.slice(0, topK);
|
|
128
|
+
}
|
|
129
|
+
/** Remove a document by ID. */
|
|
130
|
+
removeDocument(id) {
|
|
131
|
+
this.docs = this.docs.filter(d => d.id !== id);
|
|
132
|
+
this.totalDocs = this.docs.length;
|
|
133
|
+
}
|
|
134
|
+
get size() { return this.docs.length; }
|
|
135
|
+
clear() { this.docs = []; this.idf.clear(); this.totalDocs = 0; }
|
|
136
|
+
}
|
|
137
|
+
exports.VectorIndex = VectorIndex;
|
|
138
|
+
/* ═══════════════════════════════════════
|
|
139
|
+
Singleton instance for memory recall
|
|
140
|
+
═══════════════════════════════════════ */
|
|
141
|
+
let globalIndex = null;
|
|
142
|
+
function getVectorIndex() {
|
|
143
|
+
if (!globalIndex)
|
|
144
|
+
globalIndex = new VectorIndex();
|
|
145
|
+
return globalIndex;
|
|
146
|
+
}
|
|
147
|
+
function resetVectorIndex() {
|
|
148
|
+
globalIndex = new VectorIndex();
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=vector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector.js","sourceRoot":"","sources":["../../src/core/vector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../src/tools/builtin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMjD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../src/tools/builtin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMjD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAmWjE;AAID,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD"}
|
package/dist/tools/builtin.js
CHANGED
|
@@ -188,12 +188,12 @@ function registerBuiltinTools(registry) {
|
|
|
188
188
|
{ name: 'timeout', type: 'number', description: 'Timeout in milliseconds (default: 30000)', required: false },
|
|
189
189
|
],
|
|
190
190
|
handler: async (params) => {
|
|
191
|
-
const { execSync } = require('child_process');
|
|
192
191
|
const cmd = params.command;
|
|
193
192
|
const timeout = params.timeout || 30000;
|
|
194
193
|
try {
|
|
195
|
-
const
|
|
196
|
-
|
|
194
|
+
const { runInSandbox, formatSandboxResult } = require('../core/sandbox');
|
|
195
|
+
const result = runInSandbox(cmd, { timeoutMs: timeout });
|
|
196
|
+
return formatSandboxResult(result);
|
|
197
197
|
}
|
|
198
198
|
catch (e) {
|
|
199
199
|
return `Error: ${e.message || e}`;
|