From ebc3d760af2c7df8d21edfcf7da0ac3ae46507f4 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Mon, 3 Nov 2025 13:37:16 +0000 Subject: [PATCH] feat(context): Wire OpenAI provider through task context factory and add git-diff support to iterative context builder --- changelog.md | 8 ++++ ts/00_commitinfo_data.ts | 2 +- ts/aidocs_classes/commit.ts | 5 ++- ts/aidocs_classes/description.ts | 5 ++- ts/aidocs_classes/readme.ts | 5 ++- ts/context/iterative-context-builder.ts | 50 +++++++++++++++++++------ ts/context/task-context-factory.ts | 19 ++++++---- 7 files changed, 72 insertions(+), 22 deletions(-) diff --git a/changelog.md b/changelog.md index f3656b6..86a4476 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 2025-11-03 - 1.8.0 - feat(context) +Wire OpenAI provider through task context factory and add git-diff support to iterative context builder + +- Pass AiDoc.openaiInstance through TaskContextFactory into IterativeContextBuilder to reuse the same OpenAI provider and avoid reinitialization. +- IterativeContextBuilder now accepts an optional OpenAiProvider and an additionalContext string; when provided, git diffs (or other extra context) are prepended to the AI context and token counts are updated. +- createContextForCommit now forwards the git diff into the iterative builder so commit-specific context includes the diff. +- Updated aidocs_classes (commit, description, readme) to supply the existing openaiInstance when creating the TaskContextFactory. + ## 2025-11-03 - 1.7.0 - feat(IterativeContextBuilder) Add iterative AI-driven context builder and integrate into task factory; add tests and iterative configuration diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 2243a39..380d5a5 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@git.zone/tsdoc', - version: '1.7.0', + version: '1.8.0', description: 'A comprehensive TypeScript documentation tool that leverages AI to generate and enhance project documentation, including dynamic README creation, API docs via TypeDoc, and smart commit message generation.' } diff --git a/ts/aidocs_classes/commit.ts b/ts/aidocs_classes/commit.ts index 2629ac2..57ec826 100644 --- a/ts/aidocs_classes/commit.ts +++ b/ts/aidocs_classes/commit.ts @@ -32,7 +32,10 @@ export class Commit { 'package-lock.json', ]); // Use the new TaskContextFactory for optimized context - const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(this.projectDir); + const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory( + this.projectDir, + this.aiDocsRef.openaiInstance + ); await taskContextFactory.initialize(); // Generate context specifically for commit task diff --git a/ts/aidocs_classes/description.ts b/ts/aidocs_classes/description.ts index d6d7b62..b44949f 100644 --- a/ts/aidocs_classes/description.ts +++ b/ts/aidocs_classes/description.ts @@ -19,7 +19,10 @@ export class Description { public async build() { // Use the new TaskContextFactory for optimized context - const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(this.projectDir); + const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory( + this.projectDir, + this.aiDocsRef.openaiInstance + ); await taskContextFactory.initialize(); // Generate context specifically for description task diff --git a/ts/aidocs_classes/readme.ts b/ts/aidocs_classes/readme.ts index 6c9c4b9..b31f8cd 100644 --- a/ts/aidocs_classes/readme.ts +++ b/ts/aidocs_classes/readme.ts @@ -18,7 +18,10 @@ export class Readme { let finalReadmeString = ``; // Use the new TaskContextFactory for optimized context - const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(this.projectDir); + const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory( + this.projectDir, + this.aiDocsRef.openaiInstance + ); await taskContextFactory.initialize(); // Generate context specifically for readme task diff --git a/ts/context/iterative-context-builder.ts b/ts/context/iterative-context-builder.ts index cf7df0d..06874ec 100644 --- a/ts/context/iterative-context-builder.ts +++ b/ts/context/iterative-context-builder.ts @@ -28,17 +28,24 @@ export class IterativeContextBuilder { private config: Required; private tokenBudget: number = 190000; private openaiInstance: plugins.smartai.OpenAiProvider; + private externalOpenaiInstance?: plugins.smartai.OpenAiProvider; /** * Creates a new IterativeContextBuilder * @param projectRoot - Root directory of the project * @param config - Iterative configuration + * @param openaiInstance - Optional pre-configured OpenAI provider instance */ - constructor(projectRoot: string, config?: Partial) { + constructor( + projectRoot: string, + config?: Partial, + openaiInstance?: plugins.smartai.OpenAiProvider + ) { this.projectRoot = projectRoot; this.lazyLoader = new LazyFileLoader(projectRoot); this.cache = new ContextCache(projectRoot); this.analyzer = new ContextAnalyzer(projectRoot); + this.externalOpenaiInstance = openaiInstance; // Default configuration this.config = { @@ -60,24 +67,30 @@ export class IterativeContextBuilder { await configManager.initialize(this.projectRoot); this.tokenBudget = configManager.getMaxTokens(); - // Initialize OpenAI instance - const qenvInstance = new plugins.qenv.Qenv(); - const openaiToken = await qenvInstance.getEnvVarOnDemand('OPENAI_TOKEN'); - if (!openaiToken) { - throw new Error('OPENAI_TOKEN environment variable is required for iterative context building'); + // Use external OpenAI instance if provided, otherwise create a new one + if (this.externalOpenaiInstance) { + this.openaiInstance = this.externalOpenaiInstance; + } else { + // Initialize OpenAI instance from environment + const qenvInstance = new plugins.qenv.Qenv(); + const openaiToken = await qenvInstance.getEnvVarOnDemand('OPENAI_TOKEN'); + if (!openaiToken) { + throw new Error('OPENAI_TOKEN environment variable is required for iterative context building'); + } + this.openaiInstance = new plugins.smartai.OpenAiProvider({ + openaiToken, + }); + await this.openaiInstance.start(); } - this.openaiInstance = new plugins.smartai.OpenAiProvider({ - openaiToken, - }); - await this.openaiInstance.start(); } /** * Build context iteratively using AI decision making * @param taskType - Type of task being performed + * @param additionalContext - Optional additional context (e.g., git diff for commit tasks) * @returns Complete iterative context result */ - public async buildContextIteratively(taskType: TaskType): Promise { + public async buildContextIteratively(taskType: TaskType, additionalContext?: string): Promise { const startTime = Date.now(); logger.log('info', '🤖 Starting iterative context building...'); logger.log('info', ` Task: ${taskType}, Budget: ${this.tokenBudget} tokens, Max iterations: ${this.config.maxIterations}`); @@ -100,6 +113,21 @@ export class IterativeContextBuilder { let loadedContent = ''; const includedFiles: IFileInfo[] = []; + // If additional context (e.g., git diff) is provided, prepend it + if (additionalContext) { + const diffSection = ` +====== GIT DIFF ====== + +${additionalContext} + +====== END OF GIT DIFF ====== +`; + loadedContent = diffSection; + const diffTokens = this.countTokens(diffSection); + totalTokensUsed += diffTokens; + logger.log('info', `📝 Added git diff to context (${diffTokens} tokens)`); + } + // Phase 3: Iterative file selection and loading for (let iteration = 1; iteration <= this.config.maxIterations; iteration++) { const iterationStart = Date.now(); diff --git a/ts/context/task-context-factory.ts b/ts/context/task-context-factory.ts index 2435112..2e1b9ae 100644 --- a/ts/context/task-context-factory.ts +++ b/ts/context/task-context-factory.ts @@ -9,14 +9,17 @@ import type { IIterativeContextResult, TaskType } from './types.js'; export class TaskContextFactory { private projectDir: string; private configManager: ConfigManager; + private openaiInstance?: any; // OpenAI provider instance /** * Create a new TaskContextFactory * @param projectDirArg The project directory + * @param openaiInstance Optional pre-configured OpenAI provider instance */ - constructor(projectDirArg: string) { + constructor(projectDirArg: string, openaiInstance?: any) { this.projectDir = projectDirArg; this.configManager = ConfigManager.getInstance(); + this.openaiInstance = openaiInstance; } /** @@ -32,7 +35,8 @@ export class TaskContextFactory { public async createContextForReadme(): Promise { const iterativeBuilder = new IterativeContextBuilder( this.projectDir, - this.configManager.getIterativeConfig() + this.configManager.getIterativeConfig(), + this.openaiInstance ); await iterativeBuilder.initialize(); return await iterativeBuilder.buildContextIteratively('readme'); @@ -44,7 +48,8 @@ export class TaskContextFactory { public async createContextForDescription(): Promise { const iterativeBuilder = new IterativeContextBuilder( this.projectDir, - this.configManager.getIterativeConfig() + this.configManager.getIterativeConfig(), + this.openaiInstance ); await iterativeBuilder.initialize(); return await iterativeBuilder.buildContextIteratively('description'); @@ -52,16 +57,16 @@ export class TaskContextFactory { /** * Create context for commit message generation - * @param gitDiff Optional git diff to include (currently not used in iterative mode) + * @param gitDiff Optional git diff to include in the context */ public async createContextForCommit(gitDiff?: string): Promise { const iterativeBuilder = new IterativeContextBuilder( this.projectDir, - this.configManager.getIterativeConfig() + this.configManager.getIterativeConfig(), + this.openaiInstance ); await iterativeBuilder.initialize(); - // Note: git diff could be incorporated into the iterative prompts if needed - return await iterativeBuilder.buildContextIteratively('commit'); + return await iterativeBuilder.buildContextIteratively('commit', gitDiff); } /**