atlas-pipeline-mcp 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/.env.example +21 -0
- package/LICENSE +21 -0
- package/README.md +175 -0
- package/dist/mcp.d.ts +21 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +404 -0
- package/dist/mcp.js.map +1 -0
- package/dist/pipeline.d.ts +39 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +355 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/providers/index.d.ts +14 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +13 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/llm-provider.d.ts +71 -0
- package/dist/providers/llm-provider.d.ts.map +1 -0
- package/dist/providers/llm-provider.js +357 -0
- package/dist/providers/llm-provider.js.map +1 -0
- package/dist/server.d.ts +27 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +312 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/context.d.ts +23 -0
- package/dist/tools/context.d.ts.map +1 -0
- package/dist/tools/context.js +363 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/critique.d.ts +40 -0
- package/dist/tools/critique.d.ts.map +1 -0
- package/dist/tools/critique.js +315 -0
- package/dist/tools/critique.js.map +1 -0
- package/dist/tools/decompose.d.ts +34 -0
- package/dist/tools/decompose.d.ts.map +1 -0
- package/dist/tools/decompose.js +328 -0
- package/dist/tools/decompose.js.map +1 -0
- package/dist/tools/git.d.ts +66 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +333 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/intent.d.ts +24 -0
- package/dist/tools/intent.d.ts.map +1 -0
- package/dist/tools/intent.js +245 -0
- package/dist/tools/intent.js.map +1 -0
- package/dist/tools/ollama.d.ts +104 -0
- package/dist/tools/ollama.d.ts.map +1 -0
- package/dist/tools/ollama.js +299 -0
- package/dist/tools/ollama.js.map +1 -0
- package/dist/tools/optimize.d.ts +64 -0
- package/dist/tools/optimize.d.ts.map +1 -0
- package/dist/tools/optimize.js +302 -0
- package/dist/tools/optimize.js.map +1 -0
- package/dist/tools/variants.d.ts +49 -0
- package/dist/tools/variants.d.ts.map +1 -0
- package/dist/tools/variants.js +252 -0
- package/dist/tools/variants.js.map +1 -0
- package/dist/types.d.ts +447 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +25 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +117 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +279 -0
- package/dist/utils.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atlas Server - Git Context Tool
|
|
3
|
+
*
|
|
4
|
+
* Provides git repository context including:
|
|
5
|
+
* - Current branch and status
|
|
6
|
+
* - Recent commit history
|
|
7
|
+
* - Uncommitted changes
|
|
8
|
+
* - File history and blame information
|
|
9
|
+
*/
|
|
10
|
+
import { simpleGit } from 'simple-git';
|
|
11
|
+
import { logger, getErrorMessage } from '../utils.js';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Configuration
|
|
14
|
+
// ============================================================================
|
|
15
|
+
const DEFAULT_COMMIT_LIMIT = 10;
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Git Context
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Get comprehensive git context for a repository
|
|
21
|
+
*/
|
|
22
|
+
export async function getGitContext(repoPath, commitLimit = DEFAULT_COMMIT_LIMIT) {
|
|
23
|
+
try {
|
|
24
|
+
const git = simpleGit(repoPath);
|
|
25
|
+
// Check if this is a git repository
|
|
26
|
+
const isRepo = await git.checkIsRepo();
|
|
27
|
+
if (!isRepo) {
|
|
28
|
+
logger.debug({ repoPath }, 'Not a git repository');
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
// Gather all context in parallel
|
|
32
|
+
const [branch, status, log, remotes] = await Promise.all([
|
|
33
|
+
git.branch(),
|
|
34
|
+
git.status(),
|
|
35
|
+
git.log({ maxCount: commitLimit }),
|
|
36
|
+
git.getRemotes(true),
|
|
37
|
+
]);
|
|
38
|
+
const context = {
|
|
39
|
+
currentBranch: branch.current,
|
|
40
|
+
recentCommits: formatCommits(log),
|
|
41
|
+
uncommittedChanges: formatChanges(status),
|
|
42
|
+
remoteUrl: remotes[0]?.refs?.fetch,
|
|
43
|
+
isDirty: !status.isClean(),
|
|
44
|
+
};
|
|
45
|
+
logger.debug({
|
|
46
|
+
branch: context.currentBranch,
|
|
47
|
+
commits: context.recentCommits.length,
|
|
48
|
+
changes: context.uncommittedChanges.length,
|
|
49
|
+
isDirty: context.isDirty,
|
|
50
|
+
}, 'Git context retrieved');
|
|
51
|
+
return context;
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
logger.error({ error: getErrorMessage(error), repoPath }, 'Failed to get git context');
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the diff for uncommitted changes
|
|
60
|
+
*/
|
|
61
|
+
export async function getUncommittedDiff(repoPath) {
|
|
62
|
+
try {
|
|
63
|
+
const git = simpleGit(repoPath);
|
|
64
|
+
const diff = await git.diff();
|
|
65
|
+
return diff || null;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
logger.error({ error: getErrorMessage(error) }, 'Failed to get uncommitted diff');
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the diff for a specific commit
|
|
74
|
+
*/
|
|
75
|
+
export async function getCommitDiff(repoPath, commitHash) {
|
|
76
|
+
try {
|
|
77
|
+
const git = simpleGit(repoPath);
|
|
78
|
+
const diff = await git.show([commitHash, '--pretty=format:', '--patch']);
|
|
79
|
+
return diff || null;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
logger.error({ error: getErrorMessage(error), commitHash }, 'Failed to get commit diff');
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get blame information for a file
|
|
88
|
+
*/
|
|
89
|
+
export async function getFileBlame(repoPath, filePath) {
|
|
90
|
+
try {
|
|
91
|
+
const git = simpleGit(repoPath);
|
|
92
|
+
const blame = await git.raw(['blame', '--line-porcelain', filePath]);
|
|
93
|
+
return parseBlame(blame);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
logger.error({ error: getErrorMessage(error), filePath }, 'Failed to get file blame');
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get file history (commits that modified a file)
|
|
102
|
+
*/
|
|
103
|
+
export async function getFileHistory(repoPath, filePath, limit = 10) {
|
|
104
|
+
try {
|
|
105
|
+
const git = simpleGit(repoPath);
|
|
106
|
+
const log = await git.log({
|
|
107
|
+
file: filePath,
|
|
108
|
+
maxCount: limit,
|
|
109
|
+
});
|
|
110
|
+
return formatCommits(log);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
logger.error({ error: getErrorMessage(error), filePath }, 'Failed to get file history');
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get list of files changed between two refs
|
|
119
|
+
*/
|
|
120
|
+
export async function getChangedFiles(repoPath, fromRef, toRef = 'HEAD') {
|
|
121
|
+
try {
|
|
122
|
+
const git = simpleGit(repoPath);
|
|
123
|
+
const result = await git.raw(['diff', '--name-only', fromRef, toRef]);
|
|
124
|
+
return result.split('\n').filter(Boolean);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
logger.error({ error: getErrorMessage(error), fromRef, toRef }, 'Failed to get changed files');
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get the current HEAD commit hash
|
|
133
|
+
*/
|
|
134
|
+
export async function getHeadCommit(repoPath) {
|
|
135
|
+
try {
|
|
136
|
+
const git = simpleGit(repoPath);
|
|
137
|
+
const result = await git.revparse(['HEAD']);
|
|
138
|
+
return result.trim();
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
logger.error({ error: getErrorMessage(error) }, 'Failed to get HEAD commit');
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* List all branches (local and remote)
|
|
147
|
+
*/
|
|
148
|
+
export async function listBranches(repoPath) {
|
|
149
|
+
try {
|
|
150
|
+
const git = simpleGit(repoPath);
|
|
151
|
+
const branches = await git.branch(['-a']);
|
|
152
|
+
return {
|
|
153
|
+
current: branches.current,
|
|
154
|
+
local: branches.all.filter((b) => !b.startsWith('remotes/')),
|
|
155
|
+
remote: branches.all
|
|
156
|
+
.filter((b) => b.startsWith('remotes/'))
|
|
157
|
+
.map((b) => b.replace(/^remotes\//, '')),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
logger.error({ error: getErrorMessage(error) }, 'Failed to list branches');
|
|
162
|
+
return { current: '', local: [], remote: [] };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// Formatting Functions
|
|
167
|
+
// ============================================================================
|
|
168
|
+
/**
|
|
169
|
+
* Format git log entries to our GitCommit type
|
|
170
|
+
*/
|
|
171
|
+
function formatCommits(log) {
|
|
172
|
+
return log.all.map((entry) => ({
|
|
173
|
+
hash: entry.hash.substring(0, 7),
|
|
174
|
+
message: entry.message,
|
|
175
|
+
author: entry.author_name,
|
|
176
|
+
date: entry.date,
|
|
177
|
+
filesChanged: 0, // Would need additional call to get this
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Format git status to our GitChange type
|
|
182
|
+
*/
|
|
183
|
+
function formatChanges(status) {
|
|
184
|
+
const changes = [];
|
|
185
|
+
// Staged changes
|
|
186
|
+
for (const file of status.staged) {
|
|
187
|
+
changes.push({
|
|
188
|
+
path: file,
|
|
189
|
+
type: getChangeType(status, file, true),
|
|
190
|
+
staged: true,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// Unstaged changes (modified)
|
|
194
|
+
for (const file of status.modified) {
|
|
195
|
+
if (!status.staged.includes(file)) {
|
|
196
|
+
changes.push({
|
|
197
|
+
path: file,
|
|
198
|
+
type: 'modified',
|
|
199
|
+
staged: false,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Untracked files
|
|
204
|
+
for (const file of status.not_added) {
|
|
205
|
+
changes.push({
|
|
206
|
+
path: file,
|
|
207
|
+
type: 'added',
|
|
208
|
+
staged: false,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
// Deleted files
|
|
212
|
+
for (const file of status.deleted) {
|
|
213
|
+
if (!status.staged.includes(file)) {
|
|
214
|
+
changes.push({
|
|
215
|
+
path: file,
|
|
216
|
+
type: 'deleted',
|
|
217
|
+
staged: false,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return changes;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Determine change type from status
|
|
225
|
+
*/
|
|
226
|
+
function getChangeType(status, file, _staged) {
|
|
227
|
+
if (status.created.includes(file) || status.not_added.includes(file)) {
|
|
228
|
+
return 'added';
|
|
229
|
+
}
|
|
230
|
+
if (status.deleted.includes(file)) {
|
|
231
|
+
return 'deleted';
|
|
232
|
+
}
|
|
233
|
+
if (status.renamed.some((r) => r.to === file)) {
|
|
234
|
+
return 'renamed';
|
|
235
|
+
}
|
|
236
|
+
return 'modified';
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Parse git blame porcelain output
|
|
240
|
+
*/
|
|
241
|
+
function parseBlame(blameOutput) {
|
|
242
|
+
const lines = blameOutput.split('\n');
|
|
243
|
+
const blameInfo = [];
|
|
244
|
+
let currentHash = '';
|
|
245
|
+
let currentAuthor = '';
|
|
246
|
+
let currentDate = '';
|
|
247
|
+
let lineNumber = 0;
|
|
248
|
+
for (const line of lines) {
|
|
249
|
+
// Commit hash line (40 hex chars followed by line numbers)
|
|
250
|
+
const hashMatch = line.match(/^([a-f0-9]{40})\s+(\d+)\s+(\d+)/);
|
|
251
|
+
if (hashMatch) {
|
|
252
|
+
currentHash = hashMatch[1]?.substring(0, 7) ?? '';
|
|
253
|
+
lineNumber = parseInt(hashMatch[3] ?? '0', 10);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
// Author line
|
|
257
|
+
if (line.startsWith('author ')) {
|
|
258
|
+
currentAuthor = line.substring(7);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
// Author time line
|
|
262
|
+
if (line.startsWith('author-time ')) {
|
|
263
|
+
const timestamp = parseInt(line.substring(12), 10);
|
|
264
|
+
currentDate = new Date(timestamp * 1000).toISOString();
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
// Content line (starts with tab)
|
|
268
|
+
if (line.startsWith('\t')) {
|
|
269
|
+
blameInfo.push({
|
|
270
|
+
lineNumber,
|
|
271
|
+
commitHash: currentHash,
|
|
272
|
+
author: currentAuthor,
|
|
273
|
+
date: currentDate,
|
|
274
|
+
content: line.substring(1),
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return blameInfo;
|
|
279
|
+
}
|
|
280
|
+
// ============================================================================
|
|
281
|
+
// Git Operations (for future use)
|
|
282
|
+
// ============================================================================
|
|
283
|
+
/**
|
|
284
|
+
* Create a new branch
|
|
285
|
+
*/
|
|
286
|
+
export async function createBranch(repoPath, branchName, startPoint) {
|
|
287
|
+
try {
|
|
288
|
+
const git = simpleGit(repoPath);
|
|
289
|
+
if (startPoint) {
|
|
290
|
+
await git.checkoutBranch(branchName, startPoint);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
await git.checkoutLocalBranch(branchName);
|
|
294
|
+
}
|
|
295
|
+
logger.info({ branchName }, 'Branch created');
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
logger.error({ error: getErrorMessage(error), branchName }, 'Failed to create branch');
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Stage files for commit
|
|
305
|
+
*/
|
|
306
|
+
export async function stageFiles(repoPath, files) {
|
|
307
|
+
try {
|
|
308
|
+
const git = simpleGit(repoPath);
|
|
309
|
+
await git.add(files);
|
|
310
|
+
logger.info({ fileCount: files.length }, 'Files staged');
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
logger.error({ error: getErrorMessage(error) }, 'Failed to stage files');
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Create a commit
|
|
320
|
+
*/
|
|
321
|
+
export async function createCommit(repoPath, message) {
|
|
322
|
+
try {
|
|
323
|
+
const git = simpleGit(repoPath);
|
|
324
|
+
const result = await git.commit(message);
|
|
325
|
+
logger.info({ commit: result.commit }, 'Commit created');
|
|
326
|
+
return result.commit;
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
logger.error({ error: getErrorMessage(error) }, 'Failed to create commit');
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/tools/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atlas Server - Intent Analysis Tool
|
|
3
|
+
*
|
|
4
|
+
* Analyzes user queries to determine:
|
|
5
|
+
* - Primary intent (what the user wants to accomplish)
|
|
6
|
+
* - Entities (languages, frameworks, concepts mentioned)
|
|
7
|
+
* - Whether clarification is needed
|
|
8
|
+
* - Confidence level of the analysis
|
|
9
|
+
*/
|
|
10
|
+
import type { IntentAnalysis, IntentType, ExtractedEntity } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Keywords that indicate specific intent types
|
|
13
|
+
*/
|
|
14
|
+
declare const INTENT_KEYWORDS: Record<IntentType, string[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Common programming entities for extraction
|
|
17
|
+
*/
|
|
18
|
+
declare const ENTITY_PATTERNS: Record<ExtractedEntity['type'], RegExp[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Analyze a user query to determine intent
|
|
21
|
+
*/
|
|
22
|
+
export declare function analyzeIntent(query: string): Promise<IntentAnalysis>;
|
|
23
|
+
export { INTENT_KEYWORDS, ENTITY_PATTERNS };
|
|
24
|
+
//# sourceMappingURL=intent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent.d.ts","sourceRoot":"","sources":["../../src/tools/intent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,eAAe,EAChB,MAAM,aAAa,CAAC;AAQrB;;GAEG;AACH,QAAA,MAAM,eAAe,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,CAWjD,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAoB9D,CAAC;AAMF;;GAEG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAuB1E;AAwND,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atlas Server - Intent Analysis Tool
|
|
3
|
+
*
|
|
4
|
+
* Analyzes user queries to determine:
|
|
5
|
+
* - Primary intent (what the user wants to accomplish)
|
|
6
|
+
* - Entities (languages, frameworks, concepts mentioned)
|
|
7
|
+
* - Whether clarification is needed
|
|
8
|
+
* - Confidence level of the analysis
|
|
9
|
+
*/
|
|
10
|
+
import { getOllamaClient, PromptTemplates } from './ollama.js';
|
|
11
|
+
import { logger } from '../utils.js';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Intent Classification
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Keywords that indicate specific intent types
|
|
17
|
+
*/
|
|
18
|
+
const INTENT_KEYWORDS = {
|
|
19
|
+
code_generation: ['create', 'write', 'generate', 'implement', 'build', 'make', 'add'],
|
|
20
|
+
code_review: ['review', 'check', 'analyze', 'audit', 'inspect', 'evaluate'],
|
|
21
|
+
debugging: ['fix', 'debug', 'error', 'bug', 'issue', 'problem', 'broken', 'not working'],
|
|
22
|
+
refactoring: ['refactor', 'improve', 'clean', 'restructure', 'reorganize', 'optimize'],
|
|
23
|
+
explanation: ['explain', 'what is', 'how does', 'why', 'understand', 'describe'],
|
|
24
|
+
documentation: ['document', 'docs', 'readme', 'comment', 'jsdoc', 'docstring'],
|
|
25
|
+
testing: ['test', 'spec', 'unit test', 'integration test', 'coverage', 'mock'],
|
|
26
|
+
architecture: ['architecture', 'design', 'structure', 'pattern', 'organize', 'system'],
|
|
27
|
+
general_question: ['?', 'can you', 'is it', 'should i', 'what if'],
|
|
28
|
+
unknown: [],
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Common programming entities for extraction
|
|
32
|
+
*/
|
|
33
|
+
const ENTITY_PATTERNS = {
|
|
34
|
+
language: [
|
|
35
|
+
/\b(typescript|javascript|python|rust|go|java|c\+\+|ruby|php|swift|kotlin)\b/gi,
|
|
36
|
+
],
|
|
37
|
+
framework: [
|
|
38
|
+
/\b(react|vue|angular|next\.?js|express|fastify|django|flask|spring|rails)\b/gi,
|
|
39
|
+
],
|
|
40
|
+
library: [
|
|
41
|
+
/\b(axios|lodash|moment|dayjs|zod|prisma|mongoose|sequelize|redux|mobx)\b/gi,
|
|
42
|
+
],
|
|
43
|
+
file: [
|
|
44
|
+
/\b[\w-]+\.(ts|js|tsx|jsx|py|rs|go|java|rb|php|swift|kt|json|yaml|yml|md)\b/gi,
|
|
45
|
+
],
|
|
46
|
+
function: [
|
|
47
|
+
/\b(function|method|handler|callback|hook)\s+(\w+)/gi,
|
|
48
|
+
/\b(\w+)\s*\(/g,
|
|
49
|
+
],
|
|
50
|
+
concept: [
|
|
51
|
+
/\b(api|rest|graphql|authentication|authorization|middleware|routing|state management)\b/gi,
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// Analysis Functions
|
|
56
|
+
// ============================================================================
|
|
57
|
+
/**
|
|
58
|
+
* Analyze a user query to determine intent
|
|
59
|
+
*/
|
|
60
|
+
export async function analyzeIntent(query) {
|
|
61
|
+
logger.debug({ queryLength: query.length }, 'Starting intent analysis');
|
|
62
|
+
// First, do quick heuristic analysis
|
|
63
|
+
const heuristicResult = heuristicAnalysis(query);
|
|
64
|
+
// If confidence is high enough, skip LLM call
|
|
65
|
+
if (heuristicResult.confidence >= 0.85) {
|
|
66
|
+
logger.debug({ intent: heuristicResult.primaryIntent, confidence: heuristicResult.confidence }, 'Using heuristic analysis result');
|
|
67
|
+
return heuristicResult;
|
|
68
|
+
}
|
|
69
|
+
// Use LLM for deeper analysis
|
|
70
|
+
try {
|
|
71
|
+
const llmResult = await llmIntentAnalysis(query, heuristicResult);
|
|
72
|
+
return llmResult;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
logger.warn({ error }, 'LLM analysis failed, using heuristic result');
|
|
76
|
+
return heuristicResult;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Fast heuristic-based intent analysis
|
|
81
|
+
*/
|
|
82
|
+
function heuristicAnalysis(query) {
|
|
83
|
+
const normalizedQuery = query.toLowerCase();
|
|
84
|
+
// Determine primary intent from keywords
|
|
85
|
+
let primaryIntent = 'unknown';
|
|
86
|
+
let maxScore = 0;
|
|
87
|
+
for (const [intent, keywords] of Object.entries(INTENT_KEYWORDS)) {
|
|
88
|
+
const score = keywords.filter((kw) => normalizedQuery.includes(kw)).length;
|
|
89
|
+
if (score > maxScore) {
|
|
90
|
+
maxScore = score;
|
|
91
|
+
primaryIntent = intent;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Extract entities
|
|
95
|
+
const entities = extractEntities(query);
|
|
96
|
+
// Calculate confidence based on matches
|
|
97
|
+
const hasEntities = entities.length > 0;
|
|
98
|
+
const hasKeywordMatch = maxScore > 0;
|
|
99
|
+
const confidence = calculateConfidence(hasKeywordMatch, hasEntities, maxScore);
|
|
100
|
+
// Extract keywords from query
|
|
101
|
+
const keywords = extractKeywords(query);
|
|
102
|
+
// Determine if clarification is needed
|
|
103
|
+
const requiresClarification = primaryIntent === 'unknown' ||
|
|
104
|
+
confidence < 0.5 ||
|
|
105
|
+
query.length < 10;
|
|
106
|
+
const clarifyingQuestions = requiresClarification
|
|
107
|
+
? generateClarifyingQuestions(primaryIntent, entities)
|
|
108
|
+
: undefined;
|
|
109
|
+
return {
|
|
110
|
+
primaryIntent,
|
|
111
|
+
confidence,
|
|
112
|
+
entities,
|
|
113
|
+
keywords,
|
|
114
|
+
requiresClarification,
|
|
115
|
+
clarifyingQuestions,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* LLM-enhanced intent analysis for complex queries
|
|
120
|
+
*/
|
|
121
|
+
async function llmIntentAnalysis(query, heuristicResult) {
|
|
122
|
+
const client = getOllamaClient();
|
|
123
|
+
const prompt = `Analyze this developer query and extract intent information.
|
|
124
|
+
|
|
125
|
+
Query: "${query}"
|
|
126
|
+
|
|
127
|
+
Heuristic analysis suggests:
|
|
128
|
+
- Primary intent: ${heuristicResult.primaryIntent}
|
|
129
|
+
- Confidence: ${heuristicResult.confidence}
|
|
130
|
+
- Entities found: ${heuristicResult.entities.map((e) => e.value).join(', ') || 'none'}
|
|
131
|
+
|
|
132
|
+
Provide a JSON response with:
|
|
133
|
+
{
|
|
134
|
+
"primaryIntent": "one of: code_generation, code_review, debugging, refactoring, explanation, documentation, testing, architecture, general_question",
|
|
135
|
+
"confidence": 0.0 to 1.0,
|
|
136
|
+
"keywords": ["key", "words", "from", "query"],
|
|
137
|
+
"requiresClarification": true/false,
|
|
138
|
+
"clarifyingQuestions": ["question 1", "question 2"] // only if requiresClarification is true
|
|
139
|
+
}`;
|
|
140
|
+
const response = await client.generateJson(prompt, {
|
|
141
|
+
systemPrompt: PromptTemplates.intentAnalysis,
|
|
142
|
+
temperature: 0.3,
|
|
143
|
+
});
|
|
144
|
+
if (response.data) {
|
|
145
|
+
return {
|
|
146
|
+
primaryIntent: response.data.primaryIntent,
|
|
147
|
+
confidence: Math.min(1, Math.max(0, response.data.confidence)),
|
|
148
|
+
entities: heuristicResult.entities, // Keep heuristic entities
|
|
149
|
+
keywords: response.data.keywords || heuristicResult.keywords,
|
|
150
|
+
requiresClarification: response.data.requiresClarification,
|
|
151
|
+
clarifyingQuestions: response.data.clarifyingQuestions,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// Fallback to heuristic if parsing failed
|
|
155
|
+
return heuristicResult;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Extract entities from query text
|
|
159
|
+
*/
|
|
160
|
+
function extractEntities(query) {
|
|
161
|
+
const entities = [];
|
|
162
|
+
for (const [type, patterns] of Object.entries(ENTITY_PATTERNS)) {
|
|
163
|
+
for (const pattern of patterns) {
|
|
164
|
+
// Reset regex state
|
|
165
|
+
pattern.lastIndex = 0;
|
|
166
|
+
let match;
|
|
167
|
+
while ((match = pattern.exec(query)) !== null) {
|
|
168
|
+
const value = match[1] ?? match[0];
|
|
169
|
+
// Avoid duplicates
|
|
170
|
+
if (!entities.some((e) => e.value.toLowerCase() === value.toLowerCase())) {
|
|
171
|
+
entities.push({
|
|
172
|
+
type: type,
|
|
173
|
+
value,
|
|
174
|
+
position: {
|
|
175
|
+
start: match.index,
|
|
176
|
+
end: match.index + match[0].length,
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return entities;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Extract significant keywords from query
|
|
187
|
+
*/
|
|
188
|
+
function extractKeywords(query) {
|
|
189
|
+
const stopWords = new Set([
|
|
190
|
+
'a', 'an', 'the', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
191
|
+
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
|
|
192
|
+
'should', 'may', 'might', 'must', 'shall', 'can', 'need', 'to', 'of',
|
|
193
|
+
'in', 'for', 'on', 'with', 'at', 'by', 'from', 'up', 'about', 'into',
|
|
194
|
+
'through', 'during', 'before', 'after', 'above', 'below', 'between',
|
|
195
|
+
'under', 'again', 'further', 'then', 'once', 'here', 'there', 'when',
|
|
196
|
+
'where', 'why', 'how', 'all', 'each', 'few', 'more', 'most', 'other',
|
|
197
|
+
'some', 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than',
|
|
198
|
+
'too', 'very', 'just', 'and', 'but', 'if', 'or', 'because', 'as', 'until',
|
|
199
|
+
'while', 'although', 'i', 'me', 'my', 'we', 'our', 'you', 'your', 'it', 'its',
|
|
200
|
+
'this', 'that', 'these', 'those', 'what', 'which', 'who', 'whom', 'please',
|
|
201
|
+
]);
|
|
202
|
+
return query
|
|
203
|
+
.toLowerCase()
|
|
204
|
+
.replace(/[^\w\s]/g, ' ')
|
|
205
|
+
.split(/\s+/)
|
|
206
|
+
.filter((word) => word.length > 2 && !stopWords.has(word))
|
|
207
|
+
.slice(0, 10);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Calculate confidence score
|
|
211
|
+
*/
|
|
212
|
+
function calculateConfidence(hasKeywordMatch, hasEntities, keywordScore) {
|
|
213
|
+
let confidence = 0.3; // Base confidence
|
|
214
|
+
if (hasKeywordMatch) {
|
|
215
|
+
confidence += 0.3 + Math.min(0.2, keywordScore * 0.1);
|
|
216
|
+
}
|
|
217
|
+
if (hasEntities) {
|
|
218
|
+
confidence += 0.2;
|
|
219
|
+
}
|
|
220
|
+
return Math.min(1, confidence);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Generate clarifying questions based on intent
|
|
224
|
+
*/
|
|
225
|
+
function generateClarifyingQuestions(intent, entities) {
|
|
226
|
+
const questions = [];
|
|
227
|
+
if (intent === 'unknown') {
|
|
228
|
+
questions.push('What would you like me to help you with?');
|
|
229
|
+
}
|
|
230
|
+
if (!entities.some((e) => e.type === 'language')) {
|
|
231
|
+
questions.push('Which programming language are you working with?');
|
|
232
|
+
}
|
|
233
|
+
if (intent === 'code_generation' && !entities.some((e) => e.type === 'framework')) {
|
|
234
|
+
questions.push('Are you using any specific framework or library?');
|
|
235
|
+
}
|
|
236
|
+
if (intent === 'debugging') {
|
|
237
|
+
questions.push('Can you share the error message or unexpected behavior?');
|
|
238
|
+
}
|
|
239
|
+
return questions.slice(0, 3);
|
|
240
|
+
}
|
|
241
|
+
// ============================================================================
|
|
242
|
+
// Exports
|
|
243
|
+
// ============================================================================
|
|
244
|
+
export { INTENT_KEYWORDS, ENTITY_PATTERNS };
|
|
245
|
+
//# sourceMappingURL=intent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent.js","sourceRoot":"","sources":["../../src/tools/intent.ts"],"names":[],"mappings":"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"}
|