@git.zone/tsdoc 1.6.0 → 1.7.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/cli.js +10 -25
- package/dist_ts/context/config-manager.d.ts +5 -1
- package/dist_ts/context/config-manager.js +28 -3
- package/dist_ts/context/context-cache.js +2 -1
- package/dist_ts/context/enhanced-context.d.ts +2 -15
- package/dist_ts/context/enhanced-context.js +26 -191
- package/dist_ts/context/index.d.ts +2 -2
- package/dist_ts/context/index.js +1 -1
- package/dist_ts/context/iterative-context-builder.d.ts +58 -0
- package/dist_ts/context/iterative-context-builder.js +361 -0
- package/dist_ts/context/task-context-factory.d.ts +8 -8
- package/dist_ts/context/task-context-factory.js +17 -41
- package/dist_ts/context/types.d.ts +71 -3
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/cli.ts +21 -38
- package/ts/context/config-manager.ts +35 -7
- package/ts/context/context-cache.ts +1 -0
- package/ts/context/enhanced-context.ts +29 -246
- package/ts/context/index.ts +6 -2
- package/ts/context/iterative-context-builder.ts +467 -0
- package/ts/context/task-context-factory.ts +40 -63
- package/ts/context/types.ts +76 -3
package/dist_ts/context/index.js
CHANGED
|
@@ -8,4 +8,4 @@ import { ContextAnalyzer } from './context-analyzer.js';
|
|
|
8
8
|
export {
|
|
9
9
|
// Classes
|
|
10
10
|
EnhancedContext, TaskContextFactory, ConfigManager, ContextTrimmer, LazyFileLoader, ContextCache, ContextAnalyzer, };
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jb250ZXh0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBdUJ4RCxPQUFPO0FBQ0wsVUFBVTtBQUNWLGVBQWUsRUFDZixrQkFBa0IsRUFDbEIsYUFBYSxFQUNiLGNBQWMsRUFDZCxjQUFjLEVBQ2QsWUFBWSxFQUNaLGVBQWUsR0FDaEIsQ0FBQyJ9
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { TaskType, IIterativeContextResult, IIterativeConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Iterative context builder that uses AI to intelligently select files
|
|
4
|
+
* across multiple iterations until sufficient context is gathered
|
|
5
|
+
*/
|
|
6
|
+
export declare class IterativeContextBuilder {
|
|
7
|
+
private projectRoot;
|
|
8
|
+
private lazyLoader;
|
|
9
|
+
private cache;
|
|
10
|
+
private analyzer;
|
|
11
|
+
private config;
|
|
12
|
+
private tokenBudget;
|
|
13
|
+
private openaiInstance;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new IterativeContextBuilder
|
|
16
|
+
* @param projectRoot - Root directory of the project
|
|
17
|
+
* @param config - Iterative configuration
|
|
18
|
+
*/
|
|
19
|
+
constructor(projectRoot: string, config?: Partial<IIterativeConfig>);
|
|
20
|
+
/**
|
|
21
|
+
* Initialize the builder
|
|
22
|
+
*/
|
|
23
|
+
initialize(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Build context iteratively using AI decision making
|
|
26
|
+
* @param taskType - Type of task being performed
|
|
27
|
+
* @returns Complete iterative context result
|
|
28
|
+
*/
|
|
29
|
+
buildContextIteratively(taskType: TaskType): Promise<IIterativeContextResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Scan project files based on task type
|
|
32
|
+
*/
|
|
33
|
+
private scanProjectFiles;
|
|
34
|
+
/**
|
|
35
|
+
* Get AI decision on which files to load
|
|
36
|
+
*/
|
|
37
|
+
private getFileSelectionDecision;
|
|
38
|
+
/**
|
|
39
|
+
* Build prompt for file selection
|
|
40
|
+
*/
|
|
41
|
+
private buildFileSelectionPrompt;
|
|
42
|
+
/**
|
|
43
|
+
* Evaluate if current context is sufficient
|
|
44
|
+
*/
|
|
45
|
+
private evaluateContextSufficiency;
|
|
46
|
+
/**
|
|
47
|
+
* Load a single file with caching
|
|
48
|
+
*/
|
|
49
|
+
private loadFile;
|
|
50
|
+
/**
|
|
51
|
+
* Format a file for inclusion in context
|
|
52
|
+
*/
|
|
53
|
+
private formatFileForContext;
|
|
54
|
+
/**
|
|
55
|
+
* Count tokens in text
|
|
56
|
+
*/
|
|
57
|
+
private countTokens;
|
|
58
|
+
}
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import { logger } from '../logging.js';
|
|
4
|
+
import { LazyFileLoader } from './lazy-file-loader.js';
|
|
5
|
+
import { ContextCache } from './context-cache.js';
|
|
6
|
+
import { ContextAnalyzer } from './context-analyzer.js';
|
|
7
|
+
import { ConfigManager } from './config-manager.js';
|
|
8
|
+
/**
|
|
9
|
+
* Iterative context builder that uses AI to intelligently select files
|
|
10
|
+
* across multiple iterations until sufficient context is gathered
|
|
11
|
+
*/
|
|
12
|
+
export class IterativeContextBuilder {
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new IterativeContextBuilder
|
|
15
|
+
* @param projectRoot - Root directory of the project
|
|
16
|
+
* @param config - Iterative configuration
|
|
17
|
+
*/
|
|
18
|
+
constructor(projectRoot, config) {
|
|
19
|
+
this.tokenBudget = 190000;
|
|
20
|
+
this.projectRoot = projectRoot;
|
|
21
|
+
this.lazyLoader = new LazyFileLoader(projectRoot);
|
|
22
|
+
this.cache = new ContextCache(projectRoot);
|
|
23
|
+
this.analyzer = new ContextAnalyzer(projectRoot);
|
|
24
|
+
// Default configuration
|
|
25
|
+
this.config = {
|
|
26
|
+
maxIterations: config?.maxIterations ?? 5,
|
|
27
|
+
firstPassFileLimit: config?.firstPassFileLimit ?? 10,
|
|
28
|
+
subsequentPassFileLimit: config?.subsequentPassFileLimit ?? 5,
|
|
29
|
+
temperature: config?.temperature ?? 0.3,
|
|
30
|
+
model: config?.model ?? 'gpt-4-turbo-preview',
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Initialize the builder
|
|
35
|
+
*/
|
|
36
|
+
async initialize() {
|
|
37
|
+
await this.cache.init();
|
|
38
|
+
const configManager = ConfigManager.getInstance();
|
|
39
|
+
await configManager.initialize(this.projectRoot);
|
|
40
|
+
this.tokenBudget = configManager.getMaxTokens();
|
|
41
|
+
// Initialize OpenAI instance
|
|
42
|
+
const qenvInstance = new plugins.qenv.Qenv();
|
|
43
|
+
const openaiToken = await qenvInstance.getEnvVarOnDemand('OPENAI_TOKEN');
|
|
44
|
+
if (!openaiToken) {
|
|
45
|
+
throw new Error('OPENAI_TOKEN environment variable is required for iterative context building');
|
|
46
|
+
}
|
|
47
|
+
this.openaiInstance = new plugins.smartai.OpenAiProvider({
|
|
48
|
+
openaiToken,
|
|
49
|
+
});
|
|
50
|
+
await this.openaiInstance.start();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build context iteratively using AI decision making
|
|
54
|
+
* @param taskType - Type of task being performed
|
|
55
|
+
* @returns Complete iterative context result
|
|
56
|
+
*/
|
|
57
|
+
async buildContextIteratively(taskType) {
|
|
58
|
+
const startTime = Date.now();
|
|
59
|
+
logger.log('info', '🤖 Starting iterative context building...');
|
|
60
|
+
logger.log('info', ` Task: ${taskType}, Budget: ${this.tokenBudget} tokens, Max iterations: ${this.config.maxIterations}`);
|
|
61
|
+
// Phase 1: Scan project files for metadata
|
|
62
|
+
logger.log('info', '📋 Scanning project files...');
|
|
63
|
+
const metadata = await this.scanProjectFiles(taskType);
|
|
64
|
+
const totalEstimatedTokens = metadata.reduce((sum, m) => sum + m.estimatedTokens, 0);
|
|
65
|
+
logger.log('info', ` Found ${metadata.length} files (~${totalEstimatedTokens} estimated tokens)`);
|
|
66
|
+
// Phase 2: Analyze files for initial prioritization
|
|
67
|
+
logger.log('info', '🔍 Analyzing file dependencies and importance...');
|
|
68
|
+
const analysis = await this.analyzer.analyze(metadata, taskType, []);
|
|
69
|
+
logger.log('info', ` Analysis complete in ${analysis.analysisDuration}ms`);
|
|
70
|
+
// Track state across iterations
|
|
71
|
+
const iterations = [];
|
|
72
|
+
let totalTokensUsed = 0;
|
|
73
|
+
let apiCallCount = 0;
|
|
74
|
+
let loadedContent = '';
|
|
75
|
+
const includedFiles = [];
|
|
76
|
+
// Phase 3: Iterative file selection and loading
|
|
77
|
+
for (let iteration = 1; iteration <= this.config.maxIterations; iteration++) {
|
|
78
|
+
const iterationStart = Date.now();
|
|
79
|
+
logger.log('info', `\n🤔 Iteration ${iteration}/${this.config.maxIterations}: Asking AI which files to examine...`);
|
|
80
|
+
const remainingBudget = this.tokenBudget - totalTokensUsed;
|
|
81
|
+
logger.log('info', ` Token budget remaining: ${remainingBudget}/${this.tokenBudget} (${Math.round((remainingBudget / this.tokenBudget) * 100)}%)`);
|
|
82
|
+
// Get AI decision on which files to load
|
|
83
|
+
const decision = await this.getFileSelectionDecision(metadata, analysis.files.slice(0, 30), // Top 30 files by importance
|
|
84
|
+
taskType, iteration, totalTokensUsed, remainingBudget, loadedContent);
|
|
85
|
+
apiCallCount++;
|
|
86
|
+
logger.log('info', ` AI reasoning: ${decision.reasoning}`);
|
|
87
|
+
logger.log('info', ` AI requested ${decision.filesToLoad.length} files`);
|
|
88
|
+
// Load requested files
|
|
89
|
+
const iterationFiles = [];
|
|
90
|
+
let iterationTokens = 0;
|
|
91
|
+
if (decision.filesToLoad.length > 0) {
|
|
92
|
+
logger.log('info', '📥 Loading requested files...');
|
|
93
|
+
for (const filePath of decision.filesToLoad) {
|
|
94
|
+
try {
|
|
95
|
+
const fileInfo = await this.loadFile(filePath);
|
|
96
|
+
if (totalTokensUsed + fileInfo.tokenCount <= this.tokenBudget) {
|
|
97
|
+
const formattedFile = this.formatFileForContext(fileInfo);
|
|
98
|
+
loadedContent += formattedFile;
|
|
99
|
+
includedFiles.push(fileInfo);
|
|
100
|
+
iterationFiles.push(fileInfo);
|
|
101
|
+
iterationTokens += fileInfo.tokenCount;
|
|
102
|
+
totalTokensUsed += fileInfo.tokenCount;
|
|
103
|
+
logger.log('info', ` ✓ ${fileInfo.relativePath} (${fileInfo.tokenCount} tokens)`);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
logger.log('warn', ` ✗ ${fileInfo.relativePath} - would exceed budget, skipping`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
logger.log('warn', ` ✗ Failed to load ${filePath}: ${error.message}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Record iteration state
|
|
115
|
+
const iterationDuration = Date.now() - iterationStart;
|
|
116
|
+
iterations.push({
|
|
117
|
+
iteration,
|
|
118
|
+
filesLoaded: iterationFiles,
|
|
119
|
+
tokensUsed: iterationTokens,
|
|
120
|
+
totalTokensUsed,
|
|
121
|
+
decision,
|
|
122
|
+
duration: iterationDuration,
|
|
123
|
+
});
|
|
124
|
+
logger.log('info', ` Iteration ${iteration} complete: ${iterationFiles.length} files loaded, ${iterationTokens} tokens used`);
|
|
125
|
+
// Check if we should continue
|
|
126
|
+
if (totalTokensUsed >= this.tokenBudget * 0.95) {
|
|
127
|
+
logger.log('warn', '⚠️ Approaching token budget limit, stopping iterations');
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
// Ask AI if context is sufficient
|
|
131
|
+
if (iteration < this.config.maxIterations) {
|
|
132
|
+
logger.log('info', '🤔 Asking AI if context is sufficient...');
|
|
133
|
+
const sufficiencyDecision = await this.evaluateContextSufficiency(loadedContent, taskType, iteration, totalTokensUsed, remainingBudget - iterationTokens);
|
|
134
|
+
apiCallCount++;
|
|
135
|
+
logger.log('info', ` AI decision: ${sufficiencyDecision.sufficient ? '✅ SUFFICIENT' : '⏭️ NEEDS MORE'}`);
|
|
136
|
+
logger.log('info', ` Reasoning: ${sufficiencyDecision.reasoning}`);
|
|
137
|
+
if (sufficiencyDecision.sufficient) {
|
|
138
|
+
logger.log('ok', '✅ Context building complete - AI determined context is sufficient');
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const totalDuration = Date.now() - startTime;
|
|
144
|
+
logger.log('ok', `\n✅ Iterative context building complete!`);
|
|
145
|
+
logger.log('info', ` Files included: ${includedFiles.length}`);
|
|
146
|
+
logger.log('info', ` Token usage: ${totalTokensUsed}/${this.tokenBudget} (${Math.round((totalTokensUsed / this.tokenBudget) * 100)}%)`);
|
|
147
|
+
logger.log('info', ` Iterations: ${iterations.length}, API calls: ${apiCallCount}`);
|
|
148
|
+
logger.log('info', ` Total duration: ${(totalDuration / 1000).toFixed(2)}s`);
|
|
149
|
+
return {
|
|
150
|
+
context: loadedContent,
|
|
151
|
+
tokenCount: totalTokensUsed,
|
|
152
|
+
includedFiles,
|
|
153
|
+
trimmedFiles: [],
|
|
154
|
+
excludedFiles: [],
|
|
155
|
+
tokenSavings: 0,
|
|
156
|
+
iterationCount: iterations.length,
|
|
157
|
+
iterations,
|
|
158
|
+
apiCallCount,
|
|
159
|
+
totalDuration,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Scan project files based on task type
|
|
164
|
+
*/
|
|
165
|
+
async scanProjectFiles(taskType) {
|
|
166
|
+
const configManager = ConfigManager.getInstance();
|
|
167
|
+
const taskConfig = configManager.getTaskConfig(taskType);
|
|
168
|
+
const includeGlobs = taskConfig?.includePaths?.map(p => `${p}/**/*.ts`) || [
|
|
169
|
+
'ts/**/*.ts',
|
|
170
|
+
'ts*/**/*.ts'
|
|
171
|
+
];
|
|
172
|
+
const configGlobs = [
|
|
173
|
+
'package.json',
|
|
174
|
+
'readme.md',
|
|
175
|
+
'readme.hints.md',
|
|
176
|
+
'npmextra.json'
|
|
177
|
+
];
|
|
178
|
+
return await this.lazyLoader.scanFiles([...configGlobs, ...includeGlobs]);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get AI decision on which files to load
|
|
182
|
+
*/
|
|
183
|
+
async getFileSelectionDecision(allMetadata, analyzedFiles, taskType, iteration, tokensUsed, remainingBudget, loadedContent) {
|
|
184
|
+
const isFirstIteration = iteration === 1;
|
|
185
|
+
const fileLimit = isFirstIteration
|
|
186
|
+
? this.config.firstPassFileLimit
|
|
187
|
+
: this.config.subsequentPassFileLimit;
|
|
188
|
+
const systemPrompt = this.buildFileSelectionPrompt(allMetadata, analyzedFiles, taskType, iteration, tokensUsed, remainingBudget, loadedContent, fileLimit);
|
|
189
|
+
const response = await this.openaiInstance.chat({
|
|
190
|
+
systemMessage: `You are an AI assistant that helps select the most relevant files for code analysis.
|
|
191
|
+
You must respond ONLY with valid JSON that can be parsed with JSON.parse().
|
|
192
|
+
Do not wrap the JSON in markdown code blocks or add any other text.`,
|
|
193
|
+
userMessage: systemPrompt,
|
|
194
|
+
messageHistory: [],
|
|
195
|
+
});
|
|
196
|
+
// Parse JSON response, handling potential markdown formatting
|
|
197
|
+
const content = response.message.replace('```json', '').replace('```', '').trim();
|
|
198
|
+
const parsed = JSON.parse(content);
|
|
199
|
+
return {
|
|
200
|
+
reasoning: parsed.reasoning || 'No reasoning provided',
|
|
201
|
+
filesToLoad: parsed.files_to_load || [],
|
|
202
|
+
estimatedTokensNeeded: parsed.estimated_tokens_needed,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Build prompt for file selection
|
|
207
|
+
*/
|
|
208
|
+
buildFileSelectionPrompt(metadata, analyzedFiles, taskType, iteration, tokensUsed, remainingBudget, loadedContent, fileLimit) {
|
|
209
|
+
const taskDescriptions = {
|
|
210
|
+
readme: 'generating a comprehensive README that explains the project\'s purpose, features, and API',
|
|
211
|
+
commit: 'analyzing code changes to generate an intelligent commit message',
|
|
212
|
+
description: 'generating a concise project description for package.json',
|
|
213
|
+
};
|
|
214
|
+
const alreadyLoadedFiles = loadedContent
|
|
215
|
+
? loadedContent.split('\n======').slice(1).map(section => {
|
|
216
|
+
const match = section.match(/START OF FILE (.+?) ======/);
|
|
217
|
+
return match ? match[1] : '';
|
|
218
|
+
}).filter(Boolean)
|
|
219
|
+
: [];
|
|
220
|
+
const availableFiles = metadata
|
|
221
|
+
.filter(m => !alreadyLoadedFiles.includes(m.relativePath))
|
|
222
|
+
.map(m => {
|
|
223
|
+
const analysis = analyzedFiles.find(a => a.path === m.path);
|
|
224
|
+
return `- ${m.relativePath} (${m.size} bytes, ~${m.estimatedTokens} tokens${analysis ? `, importance: ${analysis.importanceScore.toFixed(2)}` : ''})`;
|
|
225
|
+
})
|
|
226
|
+
.join('\n');
|
|
227
|
+
return `You are building context for ${taskDescriptions[taskType]} in a TypeScript project.
|
|
228
|
+
|
|
229
|
+
ITERATION: ${iteration}
|
|
230
|
+
TOKENS USED: ${tokensUsed}/${tokensUsed + remainingBudget} (${Math.round((tokensUsed / (tokensUsed + remainingBudget)) * 100)}%)
|
|
231
|
+
REMAINING BUDGET: ${remainingBudget} tokens
|
|
232
|
+
|
|
233
|
+
${alreadyLoadedFiles.length > 0 ? `FILES ALREADY LOADED:\n${alreadyLoadedFiles.map(f => `- ${f}`).join('\n')}\n\n` : ''}AVAILABLE FILES (not yet loaded):
|
|
234
|
+
${availableFiles}
|
|
235
|
+
|
|
236
|
+
Your task: Select up to ${fileLimit} files that will give you the MOST understanding for this ${taskType} task.
|
|
237
|
+
|
|
238
|
+
${iteration === 1 ? `This is the FIRST iteration. Focus on:
|
|
239
|
+
- Main entry points (index.ts, main exports)
|
|
240
|
+
- Core classes and interfaces
|
|
241
|
+
- Package configuration
|
|
242
|
+
` : `This is iteration ${iteration}. You've already seen some files. Now focus on:
|
|
243
|
+
- Files that complement what you've already loaded
|
|
244
|
+
- Dependencies of already-loaded files
|
|
245
|
+
- Missing pieces for complete understanding
|
|
246
|
+
`}
|
|
247
|
+
|
|
248
|
+
Consider:
|
|
249
|
+
1. File importance scores (if provided)
|
|
250
|
+
2. File paths (ts/index.ts is likely more important than ts/internal/utils.ts)
|
|
251
|
+
3. Token efficiency (prefer smaller files if they provide good information)
|
|
252
|
+
4. Remaining budget (${remainingBudget} tokens)
|
|
253
|
+
|
|
254
|
+
Respond in JSON format:
|
|
255
|
+
{
|
|
256
|
+
"reasoning": "Brief explanation of why you're selecting these files",
|
|
257
|
+
"files_to_load": ["path/to/file1.ts", "path/to/file2.ts"],
|
|
258
|
+
"estimated_tokens_needed": 15000
|
|
259
|
+
}`;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Evaluate if current context is sufficient
|
|
263
|
+
*/
|
|
264
|
+
async evaluateContextSufficiency(loadedContent, taskType, iteration, tokensUsed, remainingBudget) {
|
|
265
|
+
const prompt = `You have been building context for a ${taskType} task across ${iteration} iterations.
|
|
266
|
+
|
|
267
|
+
CURRENT STATE:
|
|
268
|
+
- Tokens used: ${tokensUsed}
|
|
269
|
+
- Remaining budget: ${remainingBudget}
|
|
270
|
+
- Files loaded: ${loadedContent.split('\n======').length - 1}
|
|
271
|
+
|
|
272
|
+
CONTEXT SO FAR:
|
|
273
|
+
${loadedContent.substring(0, 3000)}... (truncated for brevity)
|
|
274
|
+
|
|
275
|
+
Question: Do you have SUFFICIENT context to successfully complete the ${taskType} task?
|
|
276
|
+
|
|
277
|
+
Consider:
|
|
278
|
+
- For README: Do you understand the project's purpose, main features, API surface, and usage patterns?
|
|
279
|
+
- For commit: Do you understand what changed and why?
|
|
280
|
+
- For description: Do you understand the project's core value proposition?
|
|
281
|
+
|
|
282
|
+
Respond in JSON format:
|
|
283
|
+
{
|
|
284
|
+
"sufficient": true or false,
|
|
285
|
+
"reasoning": "Detailed explanation of your decision"
|
|
286
|
+
}`;
|
|
287
|
+
const response = await this.openaiInstance.chat({
|
|
288
|
+
systemMessage: `You are an AI assistant that evaluates whether gathered context is sufficient for a task.
|
|
289
|
+
You must respond ONLY with valid JSON that can be parsed with JSON.parse().
|
|
290
|
+
Do not wrap the JSON in markdown code blocks or add any other text.`,
|
|
291
|
+
userMessage: prompt,
|
|
292
|
+
messageHistory: [],
|
|
293
|
+
});
|
|
294
|
+
// Parse JSON response, handling potential markdown formatting
|
|
295
|
+
const content = response.message.replace('```json', '').replace('```', '').trim();
|
|
296
|
+
const parsed = JSON.parse(content);
|
|
297
|
+
return {
|
|
298
|
+
sufficient: parsed.sufficient || false,
|
|
299
|
+
reasoning: parsed.reasoning || 'No reasoning provided',
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Load a single file with caching
|
|
304
|
+
*/
|
|
305
|
+
async loadFile(filePath) {
|
|
306
|
+
// Try cache first
|
|
307
|
+
const cached = await this.cache.get(filePath);
|
|
308
|
+
if (cached) {
|
|
309
|
+
return {
|
|
310
|
+
path: filePath,
|
|
311
|
+
relativePath: plugins.path.relative(this.projectRoot, filePath),
|
|
312
|
+
contents: cached.contents,
|
|
313
|
+
tokenCount: cached.tokenCount,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
// Load from disk
|
|
317
|
+
const contents = await plugins.smartfile.fs.toStringSync(filePath);
|
|
318
|
+
const tokenCount = this.countTokens(contents);
|
|
319
|
+
const relativePath = plugins.path.relative(this.projectRoot, filePath);
|
|
320
|
+
// Cache it
|
|
321
|
+
const stats = await fs.promises.stat(filePath);
|
|
322
|
+
await this.cache.set({
|
|
323
|
+
path: filePath,
|
|
324
|
+
contents,
|
|
325
|
+
tokenCount,
|
|
326
|
+
mtime: Math.floor(stats.mtimeMs),
|
|
327
|
+
cachedAt: Date.now(),
|
|
328
|
+
});
|
|
329
|
+
return {
|
|
330
|
+
path: filePath,
|
|
331
|
+
relativePath,
|
|
332
|
+
contents,
|
|
333
|
+
tokenCount,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Format a file for inclusion in context
|
|
338
|
+
*/
|
|
339
|
+
formatFileForContext(file) {
|
|
340
|
+
return `
|
|
341
|
+
====== START OF FILE ${file.relativePath} ======
|
|
342
|
+
|
|
343
|
+
${file.contents}
|
|
344
|
+
|
|
345
|
+
====== END OF FILE ${file.relativePath} ======
|
|
346
|
+
`;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Count tokens in text
|
|
350
|
+
*/
|
|
351
|
+
countTokens(text) {
|
|
352
|
+
try {
|
|
353
|
+
const tokens = plugins.gptTokenizer.encode(text);
|
|
354
|
+
return tokens.length;
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
return Math.ceil(text.length / 4);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0aXZlLWNvbnRleHQtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2NvbnRleHQvaXRlcmF0aXZlLWNvbnRleHQtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBV3ZDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVwRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sdUJBQXVCO0lBU2xDOzs7O09BSUc7SUFDSCxZQUFZLFdBQW1CLEVBQUUsTUFBa0M7UUFSM0QsZ0JBQVcsR0FBVyxNQUFNLENBQUM7UUFTbkMsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFakQsd0JBQXdCO1FBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUc7WUFDWixhQUFhLEVBQUUsTUFBTSxFQUFFLGFBQWEsSUFBSSxDQUFDO1lBQ3pDLGtCQUFrQixFQUFFLE1BQU0sRUFBRSxrQkFBa0IsSUFBSSxFQUFFO1lBQ3BELHVCQUF1QixFQUFFLE1BQU0sRUFBRSx1QkFBdUIs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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IIterativeContextResult, TaskType } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Factory class for creating task-specific context
|
|
3
|
+
* Factory class for creating task-specific context using iterative context building
|
|
4
4
|
*/
|
|
5
5
|
export declare class TaskContextFactory {
|
|
6
6
|
private projectDir;
|
|
@@ -17,22 +17,22 @@ export declare class TaskContextFactory {
|
|
|
17
17
|
/**
|
|
18
18
|
* Create context for README generation
|
|
19
19
|
*/
|
|
20
|
-
createContextForReadme(): Promise<
|
|
20
|
+
createContextForReadme(): Promise<IIterativeContextResult>;
|
|
21
21
|
/**
|
|
22
22
|
* Create context for description generation
|
|
23
23
|
*/
|
|
24
|
-
createContextForDescription(): Promise<
|
|
24
|
+
createContextForDescription(): Promise<IIterativeContextResult>;
|
|
25
25
|
/**
|
|
26
26
|
* Create context for commit message generation
|
|
27
|
-
* @param gitDiff Optional git diff to include
|
|
27
|
+
* @param gitDiff Optional git diff to include (currently not used in iterative mode)
|
|
28
28
|
*/
|
|
29
|
-
createContextForCommit(gitDiff?: string): Promise<
|
|
29
|
+
createContextForCommit(gitDiff?: string): Promise<IIterativeContextResult>;
|
|
30
30
|
/**
|
|
31
31
|
* Create context for any task type
|
|
32
32
|
* @param taskType The task type to create context for
|
|
33
|
-
* @param additionalContent Optional additional content
|
|
33
|
+
* @param additionalContent Optional additional content (currently not used)
|
|
34
34
|
*/
|
|
35
|
-
createContextForTask(taskType: TaskType, additionalContent?: string): Promise<
|
|
35
|
+
createContextForTask(taskType: TaskType, additionalContent?: string): Promise<IIterativeContextResult>;
|
|
36
36
|
/**
|
|
37
37
|
* Get token stats for all task types
|
|
38
38
|
*/
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as plugins from '../plugins.js';
|
|
2
|
-
import {
|
|
2
|
+
import { IterativeContextBuilder } from './iterative-context-builder.js';
|
|
3
3
|
import { ConfigManager } from './config-manager.js';
|
|
4
4
|
/**
|
|
5
|
-
* Factory class for creating task-specific context
|
|
5
|
+
* Factory class for creating task-specific context using iterative context building
|
|
6
6
|
*/
|
|
7
7
|
export class TaskContextFactory {
|
|
8
8
|
/**
|
|
@@ -23,54 +23,32 @@ export class TaskContextFactory {
|
|
|
23
23
|
* Create context for README generation
|
|
24
24
|
*/
|
|
25
25
|
async createContextForReadme() {
|
|
26
|
-
const
|
|
27
|
-
await
|
|
28
|
-
|
|
29
|
-
const taskConfig = this.configManager.getTaskConfig('readme');
|
|
30
|
-
if (taskConfig.mode) {
|
|
31
|
-
contextBuilder.setContextMode(taskConfig.mode);
|
|
32
|
-
}
|
|
33
|
-
// Build the context for README task
|
|
34
|
-
return await contextBuilder.buildContext('readme');
|
|
26
|
+
const iterativeBuilder = new IterativeContextBuilder(this.projectDir, this.configManager.getIterativeConfig());
|
|
27
|
+
await iterativeBuilder.initialize();
|
|
28
|
+
return await iterativeBuilder.buildContextIteratively('readme');
|
|
35
29
|
}
|
|
36
30
|
/**
|
|
37
31
|
* Create context for description generation
|
|
38
32
|
*/
|
|
39
33
|
async createContextForDescription() {
|
|
40
|
-
const
|
|
41
|
-
await
|
|
42
|
-
|
|
43
|
-
const taskConfig = this.configManager.getTaskConfig('description');
|
|
44
|
-
if (taskConfig.mode) {
|
|
45
|
-
contextBuilder.setContextMode(taskConfig.mode);
|
|
46
|
-
}
|
|
47
|
-
// Build the context for description task
|
|
48
|
-
return await contextBuilder.buildContext('description');
|
|
34
|
+
const iterativeBuilder = new IterativeContextBuilder(this.projectDir, this.configManager.getIterativeConfig());
|
|
35
|
+
await iterativeBuilder.initialize();
|
|
36
|
+
return await iterativeBuilder.buildContextIteratively('description');
|
|
49
37
|
}
|
|
50
38
|
/**
|
|
51
39
|
* Create context for commit message generation
|
|
52
|
-
* @param gitDiff Optional git diff to include
|
|
40
|
+
* @param gitDiff Optional git diff to include (currently not used in iterative mode)
|
|
53
41
|
*/
|
|
54
42
|
async createContextForCommit(gitDiff) {
|
|
55
|
-
const
|
|
56
|
-
await
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
if (taskConfig.mode) {
|
|
60
|
-
contextBuilder.setContextMode(taskConfig.mode);
|
|
61
|
-
}
|
|
62
|
-
// Build the context for commit task
|
|
63
|
-
const contextResult = await contextBuilder.buildContext('commit');
|
|
64
|
-
// If git diff is provided, add it to the context
|
|
65
|
-
if (gitDiff) {
|
|
66
|
-
contextBuilder.updateWithGitDiff(gitDiff);
|
|
67
|
-
}
|
|
68
|
-
return contextBuilder.getContextResult();
|
|
43
|
+
const iterativeBuilder = new IterativeContextBuilder(this.projectDir, this.configManager.getIterativeConfig());
|
|
44
|
+
await iterativeBuilder.initialize();
|
|
45
|
+
// Note: git diff could be incorporated into the iterative prompts if needed
|
|
46
|
+
return await iterativeBuilder.buildContextIteratively('commit');
|
|
69
47
|
}
|
|
70
48
|
/**
|
|
71
49
|
* Create context for any task type
|
|
72
50
|
* @param taskType The task type to create context for
|
|
73
|
-
* @param additionalContent Optional additional content
|
|
51
|
+
* @param additionalContent Optional additional content (currently not used)
|
|
74
52
|
*/
|
|
75
53
|
async createContextForTask(taskType, additionalContent) {
|
|
76
54
|
switch (taskType) {
|
|
@@ -81,10 +59,8 @@ export class TaskContextFactory {
|
|
|
81
59
|
case 'commit':
|
|
82
60
|
return this.createContextForCommit(additionalContent);
|
|
83
61
|
default:
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
await contextBuilder.initialize();
|
|
87
|
-
return await contextBuilder.buildContext();
|
|
62
|
+
// Default to readme for unknown task types
|
|
63
|
+
return this.createContextForReadme();
|
|
88
64
|
}
|
|
89
65
|
}
|
|
90
66
|
/**
|
|
@@ -106,4 +82,4 @@ export class TaskContextFactory {
|
|
|
106
82
|
return stats;
|
|
107
83
|
}
|
|
108
84
|
}
|
|
109
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay1jb250ZXh0LWZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jb250ZXh0L3Rhc2stY29udGV4dC1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUdwRDs7R0FFRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7SUFJN0I7OztPQUdHO0lBQ0gsWUFBWSxhQUFxQjtRQUMvQixJQUFJLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQztRQUNoQyxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsVUFBVTtRQUNyQixNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsc0JBQXNCO1FBQ2pDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSx1QkFBdUIsQ0FDbEQsSUFBSSxDQUFDLFVBQVUsRUFDZixJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQ3hDLENBQUM7UUFDRixNQUFNLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sTUFBTSxnQkFBZ0IsQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsMkJBQTJCO1FBQ3RDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSx1QkFBdUIsQ0FDbEQsSUFBSSxDQUFDLFVBQVUsRUFDZixJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQ3hDLENBQUM7UUFDRixNQUFNLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sTUFBTSxnQkFBZ0IsQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLHNCQUFzQixDQUFDLE9BQWdCO1FBQ2xELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSx1QkFBdUIsQ0FDbEQsSUFBSSxDQUFDLFVBQVUsRUFDZixJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQ3hDLENBQUM7UUFDRixNQUFNLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3BDLDRFQUE0RTtRQUM1RSxPQUFPLE1BQU0sZ0JBQWdCLENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsb0JBQW9CLENBQy9CLFFBQWtCLEVBQ2xCLGlCQUEwQjtRQUUxQixRQUFRLFFBQVEsRUFBRSxDQUFDO1lBQ2pCLEtBQUssUUFBUTtnQkFDWCxPQUFPLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1lBQ3ZDLEtBQUssYUFBYTtnQkFDaEIsT0FBTyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztZQUM1QyxLQUFLLFFBQVE7Z0JBQ1gsT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUN4RDtnQkFDRSwyQ0FBMkM7Z0JBQzNDLE9BQU8sSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDekMsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxhQUFhO1FBT3hCLE1BQU0sU0FBUyxHQUFlLENBQUMsUUFBUSxFQUFFLGFBQWEsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNsRSxNQUFNLEtBQUssR0FBMEIsRUFBUyxDQUFDO1FBRS9DLEtBQUssTUFBTSxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7WUFDakMsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDekQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHO2dCQUNoQixVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVU7Z0JBQzdCLE9BQU8sRUFBRSxNQUFNLENBQUMsWUFBWTtnQkFDNUIsYUFBYSxFQUFFLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTTtnQkFDMUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsTUFBTTtnQkFDeEMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTTthQUMzQyxDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztDQUNGIn0=
|