activo 0.2.1 → 0.3.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 +79 -3
- package/dist/core/commands.d.ts +11 -0
- package/dist/core/commands.d.ts.map +1 -0
- package/dist/core/commands.js +90 -0
- package/dist/core/commands.js.map +1 -0
- package/dist/core/llm/ollama.d.ts +2 -0
- package/dist/core/llm/ollama.d.ts.map +1 -1
- package/dist/core/llm/ollama.js +26 -0
- package/dist/core/llm/ollama.js.map +1 -1
- package/dist/core/tools/ast.d.ts +81 -0
- package/dist/core/tools/ast.d.ts.map +1 -0
- package/dist/core/tools/ast.js +700 -0
- package/dist/core/tools/ast.js.map +1 -0
- package/dist/core/tools/cache.d.ts +19 -0
- package/dist/core/tools/cache.d.ts.map +1 -0
- package/dist/core/tools/cache.js +497 -0
- package/dist/core/tools/cache.js.map +1 -0
- package/dist/core/tools/cssAnalysis.d.ts +3 -0
- package/dist/core/tools/cssAnalysis.d.ts.map +1 -0
- package/dist/core/tools/cssAnalysis.js +270 -0
- package/dist/core/tools/cssAnalysis.js.map +1 -0
- package/dist/core/tools/embeddings.d.ts +8 -0
- package/dist/core/tools/embeddings.d.ts.map +1 -0
- package/dist/core/tools/embeddings.js +631 -0
- package/dist/core/tools/embeddings.js.map +1 -0
- package/dist/core/tools/frontendAst.d.ts +6 -0
- package/dist/core/tools/frontendAst.d.ts.map +1 -0
- package/dist/core/tools/frontendAst.js +680 -0
- package/dist/core/tools/frontendAst.js.map +1 -0
- package/dist/core/tools/htmlAnalysis.d.ts +3 -0
- package/dist/core/tools/htmlAnalysis.d.ts.map +1 -0
- package/dist/core/tools/htmlAnalysis.js +398 -0
- package/dist/core/tools/htmlAnalysis.js.map +1 -0
- package/dist/core/tools/index.d.ts +10 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +21 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/javaAst.d.ts +6 -0
- package/dist/core/tools/javaAst.d.ts.map +1 -0
- package/dist/core/tools/javaAst.js +678 -0
- package/dist/core/tools/javaAst.js.map +1 -0
- package/dist/core/tools/memory.d.ts +11 -0
- package/dist/core/tools/memory.d.ts.map +1 -0
- package/dist/core/tools/memory.js +551 -0
- package/dist/core/tools/memory.js.map +1 -0
- package/dist/core/tools/mybatisAnalysis.d.ts +3 -0
- package/dist/core/tools/mybatisAnalysis.d.ts.map +1 -0
- package/dist/core/tools/mybatisAnalysis.js +251 -0
- package/dist/core/tools/mybatisAnalysis.js.map +1 -0
- package/dist/core/tools/sqlAnalysis.d.ts +3 -0
- package/dist/core/tools/sqlAnalysis.d.ts.map +1 -0
- package/dist/core/tools/sqlAnalysis.js +250 -0
- package/dist/core/tools/sqlAnalysis.js.map +1 -0
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +31 -2
- package/dist/ui/App.js.map +1 -1
- package/package.json +2 -1
- package/src/core/commands.ts +118 -0
- package/src/core/llm/ollama.ts +30 -0
- package/src/core/tools/ast.ts +826 -0
- package/src/core/tools/cache.ts +570 -0
- package/src/core/tools/cssAnalysis.ts +324 -0
- package/src/core/tools/embeddings.ts +746 -0
- package/src/core/tools/frontendAst.ts +802 -0
- package/src/core/tools/htmlAnalysis.ts +466 -0
- package/src/core/tools/index.ts +21 -1
- package/src/core/tools/javaAst.ts +812 -0
- package/src/core/tools/memory.ts +655 -0
- package/src/core/tools/mybatisAnalysis.ts +322 -0
- package/src/core/tools/sqlAnalysis.ts +298 -0
- package/src/ui/App.tsx +38 -2
- package/FINAL_SIMPLIFIED_SPEC.md +0 -456
- package/TODO.md +0 -193
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import crypto from "crypto";
|
|
4
|
+
import { glob } from "glob";
|
|
5
|
+
import { OllamaClient } from "../llm/ollama.js";
|
|
6
|
+
import { loadConfig } from "../config.js";
|
|
7
|
+
// Embeddings directory
|
|
8
|
+
const EMBEDDINGS_DIR = ".activo/embeddings";
|
|
9
|
+
const DEFAULT_EMBED_MODEL = "nomic-embed-text";
|
|
10
|
+
// Get embeddings directory
|
|
11
|
+
function getEmbeddingsDir() {
|
|
12
|
+
return path.resolve(process.cwd(), EMBEDDINGS_DIR);
|
|
13
|
+
}
|
|
14
|
+
// Ensure embeddings directory exists
|
|
15
|
+
function ensureEmbeddingsDir() {
|
|
16
|
+
const dir = getEmbeddingsDir();
|
|
17
|
+
if (!fs.existsSync(dir)) {
|
|
18
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Get index path
|
|
22
|
+
function getIndexPath() {
|
|
23
|
+
return path.join(getEmbeddingsDir(), "index.json");
|
|
24
|
+
}
|
|
25
|
+
// Get embeddings data path
|
|
26
|
+
function getDataPath() {
|
|
27
|
+
return path.join(getEmbeddingsDir(), "data.json");
|
|
28
|
+
}
|
|
29
|
+
// Load index
|
|
30
|
+
function loadIndex() {
|
|
31
|
+
const indexPath = getIndexPath();
|
|
32
|
+
if (fs.existsSync(indexPath)) {
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(fs.readFileSync(indexPath, "utf-8"));
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
// Save index
|
|
43
|
+
function saveIndex(index) {
|
|
44
|
+
ensureEmbeddingsDir();
|
|
45
|
+
fs.writeFileSync(getIndexPath(), JSON.stringify(index, null, 2));
|
|
46
|
+
}
|
|
47
|
+
// Load embeddings data
|
|
48
|
+
function loadData() {
|
|
49
|
+
const dataPath = getDataPath();
|
|
50
|
+
if (fs.existsSync(dataPath)) {
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(fs.readFileSync(dataPath, "utf-8"));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
// Save embeddings data
|
|
61
|
+
function saveData(data) {
|
|
62
|
+
ensureEmbeddingsDir();
|
|
63
|
+
fs.writeFileSync(getDataPath(), JSON.stringify(data));
|
|
64
|
+
}
|
|
65
|
+
// Calculate file hash
|
|
66
|
+
function calculateHash(content) {
|
|
67
|
+
return crypto.createHash("md5").update(content).digest("hex");
|
|
68
|
+
}
|
|
69
|
+
// Split file into semantic chunks
|
|
70
|
+
function splitIntoChunks(content, filepath) {
|
|
71
|
+
const chunks = [];
|
|
72
|
+
const lines = content.split("\n");
|
|
73
|
+
const ext = path.extname(filepath).toLowerCase();
|
|
74
|
+
// For TypeScript/JavaScript, try to split by functions/classes
|
|
75
|
+
if ([".ts", ".tsx", ".js", ".jsx"].includes(ext)) {
|
|
76
|
+
let currentChunk = [];
|
|
77
|
+
let chunkStart = 0;
|
|
78
|
+
let braceCount = 0;
|
|
79
|
+
let inFunction = false;
|
|
80
|
+
let functionName = "";
|
|
81
|
+
let chunkType = "block";
|
|
82
|
+
for (let i = 0; i < lines.length; i++) {
|
|
83
|
+
const line = lines[i];
|
|
84
|
+
currentChunk.push(line);
|
|
85
|
+
// Detect function/class start
|
|
86
|
+
const funcMatch = line.match(/(?:export\s+)?(?:async\s+)?(?:function|const|let|var)\s+(\w+)\s*[=:]?\s*(?:async\s*)?\(/);
|
|
87
|
+
const classMatch = line.match(/(?:export\s+)?class\s+(\w+)/);
|
|
88
|
+
const methodMatch = line.match(/^\s*(?:async\s+)?(\w+)\s*\([^)]*\)\s*[:{]/);
|
|
89
|
+
if (!inFunction && (funcMatch || classMatch)) {
|
|
90
|
+
if (currentChunk.length > 1) {
|
|
91
|
+
// Save previous chunk
|
|
92
|
+
const prevContent = currentChunk.slice(0, -1).join("\n").trim();
|
|
93
|
+
if (prevContent) {
|
|
94
|
+
chunks.push({
|
|
95
|
+
filepath,
|
|
96
|
+
startLine: chunkStart + 1,
|
|
97
|
+
endLine: i,
|
|
98
|
+
content: prevContent,
|
|
99
|
+
type: "block",
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
chunkStart = i;
|
|
104
|
+
currentChunk = [line];
|
|
105
|
+
inFunction = true;
|
|
106
|
+
functionName = funcMatch?.[1] || classMatch?.[1] || "";
|
|
107
|
+
chunkType = classMatch ? "class" : "function";
|
|
108
|
+
}
|
|
109
|
+
// Count braces
|
|
110
|
+
braceCount += (line.match(/{/g) || []).length;
|
|
111
|
+
braceCount -= (line.match(/}/g) || []).length;
|
|
112
|
+
// End of function/class
|
|
113
|
+
if (inFunction && braceCount === 0 && currentChunk.length > 1) {
|
|
114
|
+
const chunkContent = currentChunk.join("\n").trim();
|
|
115
|
+
if (chunkContent) {
|
|
116
|
+
chunks.push({
|
|
117
|
+
filepath,
|
|
118
|
+
startLine: chunkStart + 1,
|
|
119
|
+
endLine: i + 1,
|
|
120
|
+
content: chunkContent,
|
|
121
|
+
type: chunkType,
|
|
122
|
+
name: functionName,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
currentChunk = [];
|
|
126
|
+
chunkStart = i + 1;
|
|
127
|
+
inFunction = false;
|
|
128
|
+
functionName = "";
|
|
129
|
+
chunkType = "block";
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Remaining content
|
|
133
|
+
if (currentChunk.length > 0) {
|
|
134
|
+
const remaining = currentChunk.join("\n").trim();
|
|
135
|
+
if (remaining) {
|
|
136
|
+
chunks.push({
|
|
137
|
+
filepath,
|
|
138
|
+
startLine: chunkStart + 1,
|
|
139
|
+
endLine: lines.length,
|
|
140
|
+
content: remaining,
|
|
141
|
+
type: inFunction ? chunkType : "block",
|
|
142
|
+
name: functionName || undefined,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
// For other files, split by size (around 50 lines per chunk)
|
|
149
|
+
const chunkSize = 50;
|
|
150
|
+
for (let i = 0; i < lines.length; i += chunkSize) {
|
|
151
|
+
const chunkLines = lines.slice(i, Math.min(i + chunkSize, lines.length));
|
|
152
|
+
const chunkContent = chunkLines.join("\n").trim();
|
|
153
|
+
if (chunkContent) {
|
|
154
|
+
chunks.push({
|
|
155
|
+
filepath,
|
|
156
|
+
startLine: i + 1,
|
|
157
|
+
endLine: Math.min(i + chunkSize, lines.length),
|
|
158
|
+
content: chunkContent,
|
|
159
|
+
type: "block",
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// If no chunks or only small chunks, treat whole file as one chunk
|
|
165
|
+
if (chunks.length === 0 || (chunks.length === 1 && chunks[0].content.length < 100)) {
|
|
166
|
+
return [{
|
|
167
|
+
filepath,
|
|
168
|
+
startLine: 1,
|
|
169
|
+
endLine: lines.length,
|
|
170
|
+
content: content.trim(),
|
|
171
|
+
type: "file",
|
|
172
|
+
}];
|
|
173
|
+
}
|
|
174
|
+
// Split large chunks into smaller ones (max 1500 chars per chunk)
|
|
175
|
+
const maxChunkChars = 1500;
|
|
176
|
+
const finalChunks = [];
|
|
177
|
+
for (const chunk of chunks) {
|
|
178
|
+
if (chunk.content.length <= maxChunkChars) {
|
|
179
|
+
finalChunks.push(chunk);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Split by lines
|
|
183
|
+
const chunkLines = chunk.content.split("\n");
|
|
184
|
+
let subChunk = [];
|
|
185
|
+
let subStart = chunk.startLine;
|
|
186
|
+
for (let i = 0; i < chunkLines.length; i++) {
|
|
187
|
+
subChunk.push(chunkLines[i]);
|
|
188
|
+
const subContent = subChunk.join("\n");
|
|
189
|
+
if (subContent.length >= maxChunkChars || i === chunkLines.length - 1) {
|
|
190
|
+
if (subContent.trim()) {
|
|
191
|
+
finalChunks.push({
|
|
192
|
+
filepath: chunk.filepath,
|
|
193
|
+
startLine: subStart,
|
|
194
|
+
endLine: chunk.startLine + i,
|
|
195
|
+
content: subContent.trim(),
|
|
196
|
+
type: chunk.type,
|
|
197
|
+
name: chunk.name ? `${chunk.name} (part)` : undefined,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
subChunk = [];
|
|
201
|
+
subStart = chunk.startLine + i + 1;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return finalChunks;
|
|
207
|
+
}
|
|
208
|
+
// Maximum characters for embedding (nomic-embed-text context limit)
|
|
209
|
+
const MAX_EMBED_CHARS = 2000;
|
|
210
|
+
// Prepare text for embedding (add context)
|
|
211
|
+
function prepareForEmbedding(chunk) {
|
|
212
|
+
const parts = [];
|
|
213
|
+
// Add file context
|
|
214
|
+
parts.push(`File: ${chunk.filepath}`);
|
|
215
|
+
if (chunk.name) {
|
|
216
|
+
parts.push(`${chunk.type}: ${chunk.name}`);
|
|
217
|
+
}
|
|
218
|
+
parts.push(`Lines: ${chunk.startLine}-${chunk.endLine}`);
|
|
219
|
+
parts.push("");
|
|
220
|
+
// Truncate content if too long
|
|
221
|
+
let content = chunk.content;
|
|
222
|
+
if (content.length > MAX_EMBED_CHARS) {
|
|
223
|
+
content = content.slice(0, MAX_EMBED_CHARS) + "\n... (truncated)";
|
|
224
|
+
}
|
|
225
|
+
parts.push(content);
|
|
226
|
+
return parts.join("\n");
|
|
227
|
+
}
|
|
228
|
+
// Calculate cosine similarity
|
|
229
|
+
function cosineSimilarity(a, b) {
|
|
230
|
+
if (a.length !== b.length)
|
|
231
|
+
return 0;
|
|
232
|
+
let dotProduct = 0;
|
|
233
|
+
let normA = 0;
|
|
234
|
+
let normB = 0;
|
|
235
|
+
for (let i = 0; i < a.length; i++) {
|
|
236
|
+
dotProduct += a[i] * b[i];
|
|
237
|
+
normA += a[i] * a[i];
|
|
238
|
+
normB += b[i] * b[i];
|
|
239
|
+
}
|
|
240
|
+
const magnitude = Math.sqrt(normA) * Math.sqrt(normB);
|
|
241
|
+
return magnitude === 0 ? 0 : dotProduct / magnitude;
|
|
242
|
+
}
|
|
243
|
+
// Index Codebase Tool
|
|
244
|
+
export const indexCodebaseTool = {
|
|
245
|
+
name: "index_codebase",
|
|
246
|
+
description: "Index codebase for semantic search (코드베이스 인덱싱). Creates embeddings for all code files. Run this before using semantic_search. Use when user asks: 'index', 'prepare search', '인덱싱', '검색 준비'.",
|
|
247
|
+
parameters: {
|
|
248
|
+
type: "object",
|
|
249
|
+
properties: {
|
|
250
|
+
pattern: {
|
|
251
|
+
type: "string",
|
|
252
|
+
description: "Glob pattern for files (default: **/*.{ts,js,tsx,jsx,py,go})",
|
|
253
|
+
},
|
|
254
|
+
force: {
|
|
255
|
+
type: "boolean",
|
|
256
|
+
description: "Force re-index all files (default: only changed files)",
|
|
257
|
+
},
|
|
258
|
+
model: {
|
|
259
|
+
type: "string",
|
|
260
|
+
description: "Embedding model (default: nomic-embed-text)",
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
handler: async (args) => {
|
|
265
|
+
try {
|
|
266
|
+
const pattern = args.pattern || "**/*.{ts,js,tsx,jsx,py,go,java,rs}";
|
|
267
|
+
const force = args.force || false;
|
|
268
|
+
const embedModel = args.model || DEFAULT_EMBED_MODEL;
|
|
269
|
+
const config = loadConfig();
|
|
270
|
+
const client = new OllamaClient(config.ollama);
|
|
271
|
+
// Check if embedding model is available
|
|
272
|
+
const models = await client.listModels();
|
|
273
|
+
if (!models.some((m) => m.includes(embedModel.split(":")[0]))) {
|
|
274
|
+
return {
|
|
275
|
+
success: false,
|
|
276
|
+
content: "",
|
|
277
|
+
error: `임베딩 모델 '${embedModel}'을 찾을 수 없습니다. 'ollama pull ${embedModel}'로 설치하세요.`,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
// Find files
|
|
281
|
+
const files = await glob(pattern, {
|
|
282
|
+
ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**", "**/build/**", "**/*.min.js"],
|
|
283
|
+
});
|
|
284
|
+
if (files.length === 0) {
|
|
285
|
+
return { success: true, content: "인덱싱할 파일이 없습니다." };
|
|
286
|
+
}
|
|
287
|
+
// Load existing index and data
|
|
288
|
+
const existingIndex = loadIndex();
|
|
289
|
+
const existingData = force ? [] : loadData();
|
|
290
|
+
const newIndex = {
|
|
291
|
+
version: "1.0",
|
|
292
|
+
model: embedModel,
|
|
293
|
+
createdAt: existingIndex?.createdAt || new Date().toISOString(),
|
|
294
|
+
updatedAt: new Date().toISOString(),
|
|
295
|
+
files: {},
|
|
296
|
+
totalChunks: 0,
|
|
297
|
+
};
|
|
298
|
+
const newData = [];
|
|
299
|
+
let processed = 0;
|
|
300
|
+
let skipped = 0;
|
|
301
|
+
let errors = 0;
|
|
302
|
+
const results = [];
|
|
303
|
+
results.push(`=== 코드베이스 인덱싱 ===`);
|
|
304
|
+
results.push(`모델: ${embedModel}`);
|
|
305
|
+
results.push(`파일: ${files.length}개`);
|
|
306
|
+
results.push("");
|
|
307
|
+
for (const file of files) {
|
|
308
|
+
try {
|
|
309
|
+
const content = fs.readFileSync(file, "utf-8");
|
|
310
|
+
const hash = calculateHash(content);
|
|
311
|
+
const relativePath = path.relative(process.cwd(), file);
|
|
312
|
+
// Check if file unchanged
|
|
313
|
+
if (!force && existingIndex?.files[relativePath]?.hash === hash) {
|
|
314
|
+
// Keep existing embeddings
|
|
315
|
+
const existing = existingData.filter((e) => e.chunk.filepath === relativePath);
|
|
316
|
+
newData.push(...existing);
|
|
317
|
+
newIndex.files[relativePath] = existingIndex.files[relativePath];
|
|
318
|
+
skipped++;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
// Split into chunks
|
|
322
|
+
const chunks = splitIntoChunks(content, relativePath);
|
|
323
|
+
// Generate embeddings for each chunk
|
|
324
|
+
for (const chunk of chunks) {
|
|
325
|
+
const text = prepareForEmbedding(chunk);
|
|
326
|
+
const embedding = await client.embed(text, embedModel);
|
|
327
|
+
newData.push({
|
|
328
|
+
chunk,
|
|
329
|
+
embedding,
|
|
330
|
+
hash: calculateHash(chunk.content),
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
newIndex.files[relativePath] = { hash, chunks: chunks.length };
|
|
334
|
+
processed++;
|
|
335
|
+
results.push(`✅ ${relativePath} (${chunks.length} chunks)`);
|
|
336
|
+
}
|
|
337
|
+
catch (err) {
|
|
338
|
+
errors++;
|
|
339
|
+
results.push(`❌ ${file}: ${err}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
newIndex.totalChunks = newData.length;
|
|
343
|
+
// Save index and data
|
|
344
|
+
saveIndex(newIndex);
|
|
345
|
+
saveData(newData);
|
|
346
|
+
results.push("");
|
|
347
|
+
results.push(`=== 완료 ===`);
|
|
348
|
+
results.push(`처리됨: ${processed}개 파일`);
|
|
349
|
+
results.push(`스킵됨: ${skipped}개 파일 (변경없음)`);
|
|
350
|
+
results.push(`에러: ${errors}개`);
|
|
351
|
+
results.push(`총 청크: ${newData.length}개`);
|
|
352
|
+
return { success: true, content: results.join("\n") };
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
return { success: false, content: "", error: String(error) };
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
// Semantic Search Tool
|
|
360
|
+
export const semanticSearchTool = {
|
|
361
|
+
name: "semantic_search",
|
|
362
|
+
description: "Search code by meaning/description (의미 기반 검색). Finds relevant code based on natural language query. Requires index_codebase first. Use when user asks: 'find code that', 'where is the code for', '관련 코드 찾아', '이런 코드 어디'.",
|
|
363
|
+
parameters: {
|
|
364
|
+
type: "object",
|
|
365
|
+
required: ["query"],
|
|
366
|
+
properties: {
|
|
367
|
+
query: {
|
|
368
|
+
type: "string",
|
|
369
|
+
description: "Natural language query describing what you're looking for",
|
|
370
|
+
},
|
|
371
|
+
limit: {
|
|
372
|
+
type: "number",
|
|
373
|
+
description: "Maximum number of results (default: 5)",
|
|
374
|
+
},
|
|
375
|
+
threshold: {
|
|
376
|
+
type: "number",
|
|
377
|
+
description: "Minimum similarity score 0-1 (default: 0.3)",
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
handler: async (args) => {
|
|
382
|
+
try {
|
|
383
|
+
const query = args.query;
|
|
384
|
+
const limit = args.limit || 5;
|
|
385
|
+
const threshold = args.threshold || 0.3;
|
|
386
|
+
// Load index and data
|
|
387
|
+
const index = loadIndex();
|
|
388
|
+
if (!index) {
|
|
389
|
+
return {
|
|
390
|
+
success: false,
|
|
391
|
+
content: "",
|
|
392
|
+
error: "인덱스가 없습니다. 먼저 'index_codebase'를 실행하세요.",
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
const data = loadData();
|
|
396
|
+
if (data.length === 0) {
|
|
397
|
+
return {
|
|
398
|
+
success: false,
|
|
399
|
+
content: "",
|
|
400
|
+
error: "임베딩 데이터가 없습니다. 먼저 'index_codebase'를 실행하세요.",
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
const config = loadConfig();
|
|
404
|
+
const client = new OllamaClient(config.ollama);
|
|
405
|
+
// Generate query embedding
|
|
406
|
+
const queryEmbedding = await client.embed(query, index.model);
|
|
407
|
+
// Calculate similarities
|
|
408
|
+
const results = [];
|
|
409
|
+
for (const entry of data) {
|
|
410
|
+
const similarity = cosineSimilarity(queryEmbedding, entry.embedding);
|
|
411
|
+
if (similarity >= threshold) {
|
|
412
|
+
results.push({ entry, similarity });
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// Sort by similarity
|
|
416
|
+
results.sort((a, b) => b.similarity - a.similarity);
|
|
417
|
+
const topResults = results.slice(0, limit);
|
|
418
|
+
if (topResults.length === 0) {
|
|
419
|
+
return {
|
|
420
|
+
success: true,
|
|
421
|
+
content: `"${query}"와 관련된 코드를 찾지 못했습니다. (threshold: ${threshold})`,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
const lines = [];
|
|
425
|
+
lines.push(`=== 검색 결과: "${query}" ===`);
|
|
426
|
+
lines.push(`(${topResults.length}개 결과, 유사도 >= ${threshold})`);
|
|
427
|
+
lines.push("");
|
|
428
|
+
for (let i = 0; i < topResults.length; i++) {
|
|
429
|
+
const { entry, similarity } = topResults[i];
|
|
430
|
+
const chunk = entry.chunk;
|
|
431
|
+
const score = Math.round(similarity * 100);
|
|
432
|
+
lines.push(`📍 #${i + 1} [${score}%] ${chunk.filepath}:${chunk.startLine}-${chunk.endLine}`);
|
|
433
|
+
if (chunk.name) {
|
|
434
|
+
lines.push(` ${chunk.type}: ${chunk.name}`);
|
|
435
|
+
}
|
|
436
|
+
lines.push(" ```");
|
|
437
|
+
// Show first 10 lines of content
|
|
438
|
+
const contentLines = chunk.content.split("\n").slice(0, 10);
|
|
439
|
+
contentLines.forEach((l) => lines.push(` ${l}`));
|
|
440
|
+
if (chunk.content.split("\n").length > 10) {
|
|
441
|
+
lines.push(" ...");
|
|
442
|
+
}
|
|
443
|
+
lines.push(" ```");
|
|
444
|
+
lines.push("");
|
|
445
|
+
}
|
|
446
|
+
return { success: true, content: lines.join("\n") };
|
|
447
|
+
}
|
|
448
|
+
catch (error) {
|
|
449
|
+
return { success: false, content: "", error: String(error) };
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
};
|
|
453
|
+
// Find Similar Code Tool
|
|
454
|
+
export const findSimilarCodeTool = {
|
|
455
|
+
name: "find_similar_code",
|
|
456
|
+
description: "Find code similar to a given snippet or file (유사 코드 찾기). Use when user asks: 'find similar', 'code like this', '비슷한 코드', '이런 패턴'.",
|
|
457
|
+
parameters: {
|
|
458
|
+
type: "object",
|
|
459
|
+
properties: {
|
|
460
|
+
code: {
|
|
461
|
+
type: "string",
|
|
462
|
+
description: "Code snippet to find similar code for",
|
|
463
|
+
},
|
|
464
|
+
filepath: {
|
|
465
|
+
type: "string",
|
|
466
|
+
description: "Or specify a file path to find similar files",
|
|
467
|
+
},
|
|
468
|
+
limit: {
|
|
469
|
+
type: "number",
|
|
470
|
+
description: "Maximum results (default: 5)",
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
handler: async (args) => {
|
|
475
|
+
try {
|
|
476
|
+
let codeToSearch = args.code;
|
|
477
|
+
const filepath = args.filepath;
|
|
478
|
+
const limit = args.limit || 5;
|
|
479
|
+
if (!codeToSearch && !filepath) {
|
|
480
|
+
return {
|
|
481
|
+
success: false,
|
|
482
|
+
content: "",
|
|
483
|
+
error: "code 또는 filepath 중 하나를 지정하세요.",
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
if (filepath) {
|
|
487
|
+
const fullPath = path.resolve(filepath);
|
|
488
|
+
if (!fs.existsSync(fullPath)) {
|
|
489
|
+
return { success: false, content: "", error: `파일을 찾을 수 없음: ${filepath}` };
|
|
490
|
+
}
|
|
491
|
+
codeToSearch = fs.readFileSync(fullPath, "utf-8");
|
|
492
|
+
}
|
|
493
|
+
const index = loadIndex();
|
|
494
|
+
if (!index) {
|
|
495
|
+
return {
|
|
496
|
+
success: false,
|
|
497
|
+
content: "",
|
|
498
|
+
error: "인덱스가 없습니다. 먼저 'index_codebase'를 실행하세요.",
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
const data = loadData();
|
|
502
|
+
const config = loadConfig();
|
|
503
|
+
const client = new OllamaClient(config.ollama);
|
|
504
|
+
// Generate embedding for the search code
|
|
505
|
+
const searchEmbedding = await client.embed(codeToSearch, index.model);
|
|
506
|
+
// Find similar
|
|
507
|
+
const results = [];
|
|
508
|
+
const searchFilepath = filepath ? path.relative(process.cwd(), path.resolve(filepath)) : null;
|
|
509
|
+
for (const entry of data) {
|
|
510
|
+
// Skip the same file if searching by filepath
|
|
511
|
+
if (searchFilepath && entry.chunk.filepath === searchFilepath)
|
|
512
|
+
continue;
|
|
513
|
+
const similarity = cosineSimilarity(searchEmbedding, entry.embedding);
|
|
514
|
+
if (similarity > 0.5) { // Higher threshold for similarity search
|
|
515
|
+
results.push({ entry, similarity });
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
results.sort((a, b) => b.similarity - a.similarity);
|
|
519
|
+
const topResults = results.slice(0, limit);
|
|
520
|
+
if (topResults.length === 0) {
|
|
521
|
+
return { success: true, content: "유사한 코드를 찾지 못했습니다." };
|
|
522
|
+
}
|
|
523
|
+
const lines = [];
|
|
524
|
+
lines.push(`=== 유사 코드 검색 결과 ===`);
|
|
525
|
+
lines.push("");
|
|
526
|
+
for (let i = 0; i < topResults.length; i++) {
|
|
527
|
+
const { entry, similarity } = topResults[i];
|
|
528
|
+
const chunk = entry.chunk;
|
|
529
|
+
const score = Math.round(similarity * 100);
|
|
530
|
+
lines.push(`📍 #${i + 1} [${score}%] ${chunk.filepath}:${chunk.startLine}-${chunk.endLine}`);
|
|
531
|
+
if (chunk.name) {
|
|
532
|
+
lines.push(` ${chunk.type}: ${chunk.name}`);
|
|
533
|
+
}
|
|
534
|
+
lines.push(" ```");
|
|
535
|
+
const contentLines = chunk.content.split("\n").slice(0, 8);
|
|
536
|
+
contentLines.forEach((l) => lines.push(` ${l}`));
|
|
537
|
+
if (chunk.content.split("\n").length > 8) {
|
|
538
|
+
lines.push(" ...");
|
|
539
|
+
}
|
|
540
|
+
lines.push(" ```");
|
|
541
|
+
lines.push("");
|
|
542
|
+
}
|
|
543
|
+
return { success: true, content: lines.join("\n") };
|
|
544
|
+
}
|
|
545
|
+
catch (error) {
|
|
546
|
+
return { success: false, content: "", error: String(error) };
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
};
|
|
550
|
+
// Embeddings Status Tool
|
|
551
|
+
export const embeddingsStatusTool = {
|
|
552
|
+
name: "embeddings_status",
|
|
553
|
+
description: "Show embeddings index status (임베딩 상태). Shows indexed files and statistics. Use when user asks: 'index status', 'embeddings info', '인덱스 상태'.",
|
|
554
|
+
parameters: {
|
|
555
|
+
type: "object",
|
|
556
|
+
properties: {},
|
|
557
|
+
},
|
|
558
|
+
handler: async () => {
|
|
559
|
+
try {
|
|
560
|
+
const index = loadIndex();
|
|
561
|
+
if (!index) {
|
|
562
|
+
return {
|
|
563
|
+
success: true,
|
|
564
|
+
content: "임베딩 인덱스가 없습니다. 'index_codebase'를 실행하여 생성하세요.",
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
const files = Object.keys(index.files);
|
|
568
|
+
const totalChunks = Object.values(index.files).reduce((sum, f) => sum + f.chunks, 0);
|
|
569
|
+
const lines = [];
|
|
570
|
+
lines.push(`=== 임베딩 인덱스 상태 ===`);
|
|
571
|
+
lines.push("");
|
|
572
|
+
lines.push(`📊 통계:`);
|
|
573
|
+
lines.push(` 모델: ${index.model}`);
|
|
574
|
+
lines.push(` 파일: ${files.length}개`);
|
|
575
|
+
lines.push(` 청크: ${totalChunks}개`);
|
|
576
|
+
lines.push(` 생성: ${index.createdAt.slice(0, 10)}`);
|
|
577
|
+
lines.push(` 갱신: ${index.updatedAt.slice(0, 10)}`);
|
|
578
|
+
lines.push("");
|
|
579
|
+
lines.push(`📁 인덱싱된 파일:`);
|
|
580
|
+
// Group by directory
|
|
581
|
+
const byDir = {};
|
|
582
|
+
for (const file of files) {
|
|
583
|
+
const dir = path.dirname(file) || ".";
|
|
584
|
+
if (!byDir[dir])
|
|
585
|
+
byDir[dir] = [];
|
|
586
|
+
byDir[dir].push(path.basename(file));
|
|
587
|
+
}
|
|
588
|
+
for (const [dir, fileList] of Object.entries(byDir)) {
|
|
589
|
+
lines.push(` ${dir}/`);
|
|
590
|
+
fileList.slice(0, 10).forEach((f) => lines.push(` ${f}`));
|
|
591
|
+
if (fileList.length > 10) {
|
|
592
|
+
lines.push(` ... 외 ${fileList.length - 10}개`);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return { success: true, content: lines.join("\n") };
|
|
596
|
+
}
|
|
597
|
+
catch (error) {
|
|
598
|
+
return { success: false, content: "", error: String(error) };
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
};
|
|
602
|
+
// Clear Embeddings Tool
|
|
603
|
+
export const clearEmbeddingsTool = {
|
|
604
|
+
name: "clear_embeddings",
|
|
605
|
+
description: "Clear embeddings index (임베딩 삭제). Removes all indexed data. Use when user asks: 'clear index', 'reset embeddings', '인덱스 삭제'.",
|
|
606
|
+
parameters: {
|
|
607
|
+
type: "object",
|
|
608
|
+
properties: {},
|
|
609
|
+
},
|
|
610
|
+
handler: async () => {
|
|
611
|
+
try {
|
|
612
|
+
const dir = getEmbeddingsDir();
|
|
613
|
+
if (fs.existsSync(dir)) {
|
|
614
|
+
fs.rmSync(dir, { recursive: true });
|
|
615
|
+
}
|
|
616
|
+
return { success: true, content: "임베딩 인덱스가 삭제되었습니다." };
|
|
617
|
+
}
|
|
618
|
+
catch (error) {
|
|
619
|
+
return { success: false, content: "", error: String(error) };
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
};
|
|
623
|
+
// Export all embedding tools
|
|
624
|
+
export const embeddingTools = [
|
|
625
|
+
indexCodebaseTool,
|
|
626
|
+
semanticSearchTool,
|
|
627
|
+
findSimilarCodeTool,
|
|
628
|
+
embeddingsStatusTool,
|
|
629
|
+
clearEmbeddingsTool,
|
|
630
|
+
];
|
|
631
|
+
//# sourceMappingURL=embeddings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../../src/core/tools/embeddings.ts"],"names":[],"mappings":"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"}
|