@vortex-ai/cli 0.1.50 → 0.1.55
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/.turbo/turbo-build.log +7 -7
- package/dist/index.js +482 -272
- package/dist/index.mjs +482 -272
- package/package.json +1 -1
- package/src/commands/cache.ts +2 -2
- package/src/commands/review.ts +5 -5
- package/src/commands/search.ts +19 -7
- package/src/commands/solve-issue.ts +2 -1
- package/src/commands/solve.ts +7 -3
- package/src/index.ts +3 -0
package/package.json
CHANGED
package/src/commands/cache.ts
CHANGED
|
@@ -12,9 +12,9 @@ cacheCommand
|
|
|
12
12
|
const stats = await LLMCacheManager.getStats();
|
|
13
13
|
console.log("\nLLM Cache Statistics\n");
|
|
14
14
|
console.log(`Entries: ${stats.entries.toLocaleString()}`);
|
|
15
|
-
console.log(`
|
|
15
|
+
console.log(`Saved API Calls: ${stats.hits.toLocaleString()}`);
|
|
16
16
|
const storageMB = (stats.storage / 1024 / 1024).toFixed(2);
|
|
17
|
-
console.log(`Storage: ${storageMB} MB\n`);
|
|
17
|
+
console.log(`Storage Used: ${storageMB} MB\n`);
|
|
18
18
|
} catch (err) {
|
|
19
19
|
console.error("Failed to retrieve cache stats:", err);
|
|
20
20
|
}
|
package/src/commands/review.ts
CHANGED
|
@@ -80,11 +80,11 @@ export async function reviewCommand(options: any) {
|
|
|
80
80
|
|
|
81
81
|
const allChunks: any[] = [];
|
|
82
82
|
if (queries.length > 0) {
|
|
83
|
-
spinner.text = `Hybrid searching for context...`;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
spinner.text = `Hybrid searching for context (parallel)...`;
|
|
84
|
+
const allResults = await Promise.all(
|
|
85
|
+
queries.map(query => indexer.hybridSearch(query, 3))
|
|
86
|
+
);
|
|
87
|
+
allChunks.push(...allResults.flat());
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
const uniqueChunks = Array.from(
|
package/src/commands/search.ts
CHANGED
|
@@ -15,21 +15,33 @@ export async function searchCommand(options: any) {
|
|
|
15
15
|
const indexer = new Indexer();
|
|
16
16
|
|
|
17
17
|
try {
|
|
18
|
-
spinner.text = "Running hybrid search (vector + BM25 + cross-encoder)...";
|
|
19
|
-
const results = await indexer.hybridSearch(options.query, parseInt(options.limit, 10));
|
|
18
|
+
spinner.text = options.expandQuery ? "Expanding query and running parallel hybrid search..." : "Running hybrid search (vector + BM25 + cross-encoder)...";
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
let queriesToSearch = [options.query];
|
|
21
|
+
const agent = new IntelligenceAgent();
|
|
22
|
+
|
|
23
|
+
if (options.expandQuery) {
|
|
24
|
+
queriesToSearch = await agent.expandQuery(options.query);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const allResults = await Promise.all(
|
|
28
|
+
queriesToSearch.map(q => indexer.hybridSearch(q, parseInt(options.limit, 10)))
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const flatResults = allResults.flat();
|
|
32
|
+
const uniqueResults = Array.from(new Map(flatResults.map((c) => [c.id, c])).values()).sort((a, b) => b.score - a.score).slice(0, parseInt(options.limit, 10));
|
|
33
|
+
|
|
34
|
+
if (uniqueResults.length === 0) {
|
|
22
35
|
spinner.fail("No relevant code found.");
|
|
23
36
|
return;
|
|
24
37
|
}
|
|
25
38
|
|
|
26
|
-
spinner.text = `Found ${
|
|
39
|
+
spinner.text = `Found ${uniqueResults.length} relevant code chunks. Analyzing with AI engine...`;
|
|
27
40
|
|
|
28
41
|
const memoryService = new MemoryService();
|
|
29
42
|
const memories = await memoryService.recallRelevantMemories(options.query, 3);
|
|
30
43
|
|
|
31
|
-
const
|
|
32
|
-
const answer = await agent.answerQueryWithContext(options.query, results);
|
|
44
|
+
const answer = await agent.answerQueryWithContext(options.query, uniqueResults);
|
|
33
45
|
|
|
34
46
|
spinner.succeed("Analysis complete!\n");
|
|
35
47
|
|
|
@@ -47,7 +59,7 @@ export async function searchCommand(options: any) {
|
|
|
47
59
|
console.log(formatted);
|
|
48
60
|
|
|
49
61
|
console.log(chalk.cyan.dim(" Reference Material (Hybrid Retrieval)"));
|
|
50
|
-
|
|
62
|
+
uniqueResults.forEach((res: any, i: number) => {
|
|
51
63
|
const sources = res.sources ? res.sources.join("+") : "vector";
|
|
52
64
|
const scoreStr = res.score ? (res.score * 100).toFixed(1) + '%' : 'N/A';
|
|
53
65
|
console.log(chalk.gray(` │ [${i + 1}] ${res.file.replace(process.cwd(), '')} ➔ ${res.symbolPath || '(anonymous)'} (${scoreStr}) [${sources}]`));
|
|
@@ -59,7 +59,8 @@ Please fix this issue in the codebase.`;
|
|
|
59
59
|
await solveCommand(prompt, {
|
|
60
60
|
autoApprove: options.autoApprove,
|
|
61
61
|
maxSteps: options.maxSteps,
|
|
62
|
-
contextChunks: contextChunks
|
|
62
|
+
contextChunks: contextChunks,
|
|
63
|
+
verify: options.verify
|
|
63
64
|
});
|
|
64
65
|
|
|
65
66
|
} catch (err) {
|
package/src/commands/solve.ts
CHANGED
|
@@ -22,7 +22,7 @@ import { initDatabase } from "@vortex/db";
|
|
|
22
22
|
import { getGitRoot, isGitRepo } from "@vortex/git";
|
|
23
23
|
import { VectorStore, LocalEmbedder, BM25Index, HybridRetriever } from "@vortex/retrieval";
|
|
24
24
|
|
|
25
|
-
export async function solveCommand(prompt: string, options: { autoApprove?: boolean; maxSteps?: number; contextChunks?: AgentContextChunk[]; newProject?: string } = {}) {
|
|
25
|
+
export async function solveCommand(prompt: string, options: { autoApprove?: boolean; maxSteps?: number; contextChunks?: AgentContextChunk[]; newProject?: string; verify?: string | boolean } = {}) {
|
|
26
26
|
let cwd = process.cwd();
|
|
27
27
|
|
|
28
28
|
if (options.newProject) {
|
|
@@ -70,7 +70,7 @@ export async function solveCommand(prompt: string, options: { autoApprove?: bool
|
|
|
70
70
|
if (!options.contextChunks || options.contextChunks.length === 0) {
|
|
71
71
|
try {
|
|
72
72
|
const indexer = new Indexer();
|
|
73
|
-
const relevantContext = await indexer.hybridSearch(prompt,
|
|
73
|
+
const relevantContext = await indexer.hybridSearch(prompt, 15);
|
|
74
74
|
options.contextChunks = relevantContext.map((c: any) => ({
|
|
75
75
|
file: c.file,
|
|
76
76
|
symbolPath: c.symbolPath || "anonymous",
|
|
@@ -95,7 +95,10 @@ export async function solveCommand(prompt: string, options: { autoApprove?: bool
|
|
|
95
95
|
const parsedPlan = JSON.parse(executionPlanStr);
|
|
96
96
|
planSummary = parsedPlan.summary || planSummary;
|
|
97
97
|
stepCount = parsedPlan.steps ? parsedPlan.steps.length : 0;
|
|
98
|
-
executionPlan = parsedPlan.steps ? parsedPlan.steps.map((s:
|
|
98
|
+
executionPlan = parsedPlan.steps ? parsedPlan.steps.map((s: any, i: number) => {
|
|
99
|
+
if (typeof s === 'string') return `${i + 1}. ${s}`;
|
|
100
|
+
return `${i + 1}. [${(s.action || 'MODIFY').toUpperCase()}] ${s.file || 'General'}\n ${s.description}`;
|
|
101
|
+
}).join("\n\n") : executionPlanStr;
|
|
99
102
|
filesToRead = parsedPlan.filesToRead || [];
|
|
100
103
|
} catch {
|
|
101
104
|
executionPlan = executionPlanStr;
|
|
@@ -188,6 +191,7 @@ export async function solveCommand(prompt: string, options: { autoApprove?: bool
|
|
|
188
191
|
},
|
|
189
192
|
{
|
|
190
193
|
initialState,
|
|
194
|
+
verifyCommand: options.verify,
|
|
191
195
|
onToolCall: (toolName, args) => {
|
|
192
196
|
if (toolName === "write_file") {
|
|
193
197
|
spinner.text = `Writing ${args.path}...`;
|
package/src/index.ts
CHANGED
|
@@ -89,6 +89,7 @@ program
|
|
|
89
89
|
.description("Search the indexed codebase semantically and get an AI explanation")
|
|
90
90
|
.requiredOption("-q, --query <text>", "Search query")
|
|
91
91
|
.option("-l, --limit <number>", "Number of results to consider", "5")
|
|
92
|
+
.option("--expand-query", "Expand the search query using the LLM for better recall")
|
|
92
93
|
.option("--no-cache", "Disable LLM response caching")
|
|
93
94
|
.action(searchCommand);
|
|
94
95
|
|
|
@@ -121,6 +122,7 @@ program
|
|
|
121
122
|
.option("--auto-approve", "Skip interactive prompts for file writes and shell commands")
|
|
122
123
|
.option("--max-steps <number>", "Maximum number of agent loop iterations", Number, 30)
|
|
123
124
|
.option("--new-project <folder>", "Create a new project folder and initialize git before solving")
|
|
125
|
+
.option("--verify [command]", "Run a verification command after completion (e.g., 'npm run check-types'). Agent will self-correct on failure.")
|
|
124
126
|
.action((prompt, options) => solveCommand(prompt, options));
|
|
125
127
|
|
|
126
128
|
program
|
|
@@ -129,6 +131,7 @@ program
|
|
|
129
131
|
.requiredOption("--id <number>", "Issue number", Number)
|
|
130
132
|
.option("--auto-approve", "Skip interactive prompts for file writes and shell commands")
|
|
131
133
|
.option("--max-steps <number>", "Maximum number of agent loop iterations", Number, 30)
|
|
134
|
+
.option("--verify [command]", "Run a verification command after completion. Agent will self-correct on failure.")
|
|
132
135
|
.action(solveIssueCommand);
|
|
133
136
|
|
|
134
137
|
// ── AI-Powered Commands ──
|