Skip to content

Commit b5440d4

Browse files
committed
Enhance AI Query Script with Commander and Content Type Filtering #7229
1 parent 15ab126 commit b5440d4

2 files changed

Lines changed: 66 additions & 23 deletions

File tree

AGENTS.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ You must **NEVER** make guesses, assumptions, or "hallucinate" answers about the
3939
### The Query Command
4040
Your most important tool is the local AI knowledge base. To use it, execute the following shell command:
4141
```bash
42-
npm run ai:query -- -q "Your question here"
42+
npm run ai:query -- -q "Your question here" -t <type>
4343
```
44+
- The `-t` or `--type` flag is optional and allows you to filter results by content type.
45+
- Supported types are: `all` (default), `blog`, `guide`, `src`, `example`.
4446

4547
### How to Interpret Query Results
4648
The query tool will return a ranked list of source file paths based on relevance. The output will look like this:
@@ -69,10 +71,22 @@ When you need to understand a new concept or feature area:
6971
- `npm run ai:query -- -q "form validation patterns"`
7072
- `npm run ai:query -- -q "how are stores implemented?"`
7173

72-
#### 2. Implementation Pattern (Query Before Coding)
74+
#### 2. Targeted Content-Type Searching
75+
Use the `--type` (`-t`) flag to focus your search on specific types of content. This is a powerful way to get more relevant results.
76+
77+
- **To find conceptual explanations:**
78+
- `npm run ai:query -- -q "state management" -t guide`
79+
- **To find concrete usage examples:**
80+
- `npm run ai:query -- -q "Button component" -t example`
81+
- **To dive deep into implementation details:**
82+
- `npm run ai:query -- -q "afterSet hook" -t src`
83+
84+
**Strategy:** If a broad query returns too many source files and not enough conceptual documents, re-run the query with `-t guide`. Conversely, if you have read the guides but need to see the actual implementation, re-run with `-t src`.
85+
86+
#### 3. Implementation Pattern (Query Before Coding)
7387
Before writing or modifying any code, **always** query the knowledge base first to:
74-
- Look for existing similar implementations.
75-
- Understand framework conventions for the task you are performing.
88+
- Look for existing similar implementations (try `-t src` or `-t example`).
89+
- Understand framework conventions for the task you are performing (try `-t guide`).
7690
- Identify common patterns used in the relevant area of the codebase.
7791

7892
### When Queries Fail to Find Information
@@ -127,4 +141,4 @@ Integrate the query tool into your development process.
127141
## 5. Session Maintenance
128142
Your initialization is a snapshot in time. The codebase can change. If you pull new changes from the repository, you should consider re-running your initialization steps (reading `structure.json`, `Neo.mjs`, and `core/Base.mjs`) to ensure your understanding is up-to-date.
129143

130-
Furthermore, after pulling changes, the local knowledge base may be out of sync. You should run `npm run ai:build-kb` to re-embed the latest changes into the database.
144+
Furthermore, after pulling changes, the local knowledge base may be out of sync. You should run `npm run ai:build-kb` to re-embed the latest changes into the database.

buildScripts/ai/queryKnowledgeBase.mjs

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
import {ChromaClient} from 'chromadb';
22
import {GoogleGenerativeAI} from '@google/generative-ai';
3+
import {Command} from 'commander/esm.mjs';
34
import dotenv from 'dotenv';
45
import fs from 'fs-extra';
56
import path from 'path';
6-
import yargs from 'yargs';
7-
import {hideBin} from 'yargs/helpers';
87

98
dotenv.config({quiet: true});
109

10+
const program = new Command();
11+
12+
program
13+
.name('neo-ai-query')
14+
.version('1.0.0') // Or from package.json
15+
.option('-q, --query <value>', 'The search query for the knowledge base')
16+
.option('-t, --type <value>', 'The content type to query for', 'all')
17+
.parse(process.argv);
18+
19+
const opts = program.opts();
20+
1121
/**
1222
* This script is the final stage in the AI knowledge base pipeline: **Query**.
1323
*
@@ -31,14 +41,15 @@ dotenv.config({quiet: true});
3141
* @class QueryKnowledgeBase
3242
*/
3343
class QueryKnowledgeBase {
34-
static async run(query) {
44+
static async run(query, type) {
3545
if (!query) {
3646
console.error('Error: A query string must be provided.');
37-
console.log('Usage: npm run ai:query -- --query "your search query"');
47+
console.log('Usage: npm run ai:query -- -q "your search query"');
3848
return;
3949
}
4050

41-
console.log(`Querying for: "${query}"...`);
51+
console.log(`Querying for: "${query}" (type: ${type})...
52+
`);
4253

4354
// 1. Connect to ChromaDB and get query results
4455
const dbClient = new ChromaClient();
@@ -62,10 +73,29 @@ class QueryKnowledgeBase {
6273
const queryEmbedding = await model.embedContent(query);
6374
const results = await collection.query({
6475
queryEmbeddings: [queryEmbedding.embedding.values],
65-
nResults : 50
76+
nResults : 100 // Increased to get a wider net for filtering
6677
});
6778

68-
// 2. Process results with the enhanced scoring algorithm
79+
// 2. Filter results by content type if specified
80+
if (type && type !== 'all') {
81+
results.metadatas[0] = results.metadatas[0].filter(metadata => {
82+
const source = metadata.source || '';
83+
switch (type) {
84+
case 'blog':
85+
return source.includes('/learn/blog/');
86+
case 'guide':
87+
return source.includes('/learn/guides/');
88+
case 'src':
89+
return source.includes('/src/');
90+
case 'example':
91+
return source.includes('/examples/');
92+
default:
93+
return true;
94+
}
95+
});
96+
}
97+
98+
// 3. Process results with the enhanced scoring algorithm
6999
if (results.metadatas?.length > 0 && results.metadatas[0].length > 0) {
70100
const sourceScores = {};
71101
const queryLower = query.toLowerCase();
@@ -114,7 +144,7 @@ class QueryKnowledgeBase {
114144
});
115145

116146
if (Object.keys(sourceScores).length === 0) {
117-
console.log('No relevant source files found.');
147+
console.log('No relevant source files found for the specified type.');
118148
return;
119149
}
120150

@@ -139,20 +169,19 @@ class QueryKnowledgeBase {
139169
finalSorted.slice(0, 25).forEach(([source, score]) => {
140170
console.log(`- ${source} (Score: ${score.toFixed(0)})`);
141171
});
142-
console.log(`\nTop result: ${finalSorted[0][0]}`);
172+
173+
if (finalSorted.length > 0) {
174+
console.log(`\nTop result: ${finalSorted[0][0]}`);
175+
} else {
176+
console.log('No relevant source files found after scoring.');
177+
}
143178
} else {
144-
console.log('No results found for your query.');
179+
console.log('No results found for your query and type.');
145180
}
146181
}
147182
}
148183

149-
const argv = yargs(hideBin(process.argv)).option('query', {
150-
alias : 'q',
151-
type : 'string',
152-
description: 'The search query for the knowledge base'
153-
}).argv;
154-
155-
QueryKnowledgeBase.run(argv.query).catch(err => {
184+
QueryKnowledgeBase.run(opts.query, opts.type).catch(err => {
156185
console.error(err);
157186
process.exit(1);
158-
});
187+
});

0 commit comments

Comments
 (0)