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