Compare commits

..

4 Commits

Author SHA1 Message Date
0a3080518f 1.8.1
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-03 17:50:09 +00:00
d0a4ddbb4b fix(git diff): improve git diff 2025-11-03 17:49:35 +00:00
481339d3cb 1.8.0
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-03 13:37:16 +00:00
ebc3d760af feat(context): Wire OpenAI provider through task context factory and add git-diff support to iterative context builder 2025-11-03 13:37:16 +00:00
11 changed files with 91 additions and 34 deletions

View File

@@ -1,5 +1,13 @@
# Changelog # 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) ## 2025-11-03 - 1.7.0 - feat(IterativeContextBuilder)
Add iterative AI-driven context builder and integrate into task factory; add tests and iterative configuration Add iterative AI-driven context builder and integrate into task factory; add tests and iterative configuration

View File

@@ -1,6 +1,6 @@
{ {
"name": "@git.zone/tsdoc", "name": "@git.zone/tsdoc",
"version": "1.7.0", "version": "1.8.1",
"private": false, "private": false,
"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.", "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.",
"type": "module", "type": "module",

View File

@@ -33,7 +33,10 @@ tap.test('should build commit object', async () => {
expect(commitObject).toHaveProperty('recommendedNextVersionLevel'); expect(commitObject).toHaveProperty('recommendedNextVersionLevel');
expect(commitObject).toHaveProperty('recommendedNextVersionScope'); expect(commitObject).toHaveProperty('recommendedNextVersionScope');
expect(commitObject).toHaveProperty('recommendedNextVersionMessage'); expect(commitObject).toHaveProperty('recommendedNextVersionMessage');
});
}) tap.test('should stop AIdocs', async () => {
await aidocs.stop();
});
tap.start(); tap.start();

View File

@@ -1,8 +0,0 @@
import { expect, tap } from '@push.rocks/tapbundle';
import * as tsdoc from '../ts/index.js';
tap.test('first test', async () => {
console.log('test');
});
tap.start();

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@git.zone/tsdoc', 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.' 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.'
} }

View File

@@ -30,9 +30,20 @@ export class Commit {
const diffStringArray = await gitRepo.getUncommittedDiff([ const diffStringArray = await gitRepo.getUncommittedDiff([
'pnpm-lock.yaml', 'pnpm-lock.yaml',
'package-lock.json', 'package-lock.json',
'npm-shrinkwrap.json',
'yarn.lock',
'deno.lock',
'bun.lockb',
'.claude/*',
'.cursor/*',
'.vscode/*',
'.idea/*',
]); ]);
// Use the new TaskContextFactory for optimized context // 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(); await taskContextFactory.initialize();
// Generate context specifically for commit task // Generate context specifically for commit task

View File

@@ -19,7 +19,10 @@ export class Description {
public async build() { public async build() {
// Use the new TaskContextFactory for optimized context // 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(); await taskContextFactory.initialize();
// Generate context specifically for description task // Generate context specifically for description task

View File

@@ -18,7 +18,10 @@ export class Readme {
let finalReadmeString = ``; let finalReadmeString = ``;
// Use the new TaskContextFactory for optimized context // 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(); await taskContextFactory.initialize();
// Generate context specifically for readme task // Generate context specifically for readme task

View File

@@ -64,7 +64,7 @@ export class AiDoc {
await this.npmextraKV.writeKey('OPENAI_TOKEN', this.openaiToken); await this.npmextraKV.writeKey('OPENAI_TOKEN', this.openaiToken);
} }
} }
if (!this.openaiToken) { if (!this.openaiToken && this.npmextraKV) {
this.openaiToken = await this.npmextraKV.readKey('OPENAI_TOKEN'); this.openaiToken = await this.npmextraKV.readKey('OPENAI_TOKEN');
} }
@@ -76,7 +76,11 @@ export class AiDoc {
} }
public async stop() { public async stop() {
await this.openaiInstance.stop(); if (this.openaiInstance) {
await this.openaiInstance.stop();
}
// No explicit cleanup needed for npmextraKV or aidocInteract
// They don't keep event loop alive
} }
public async buildReadme(projectDirArg: string) { public async buildReadme(projectDirArg: string) {

View File

@@ -28,17 +28,24 @@ export class IterativeContextBuilder {
private config: Required<IIterativeConfig>; private config: Required<IIterativeConfig>;
private tokenBudget: number = 190000; private tokenBudget: number = 190000;
private openaiInstance: plugins.smartai.OpenAiProvider; private openaiInstance: plugins.smartai.OpenAiProvider;
private externalOpenaiInstance?: plugins.smartai.OpenAiProvider;
/** /**
* Creates a new IterativeContextBuilder * Creates a new IterativeContextBuilder
* @param projectRoot - Root directory of the project * @param projectRoot - Root directory of the project
* @param config - Iterative configuration * @param config - Iterative configuration
* @param openaiInstance - Optional pre-configured OpenAI provider instance
*/ */
constructor(projectRoot: string, config?: Partial<IIterativeConfig>) { constructor(
projectRoot: string,
config?: Partial<IIterativeConfig>,
openaiInstance?: plugins.smartai.OpenAiProvider
) {
this.projectRoot = projectRoot; this.projectRoot = projectRoot;
this.lazyLoader = new LazyFileLoader(projectRoot); this.lazyLoader = new LazyFileLoader(projectRoot);
this.cache = new ContextCache(projectRoot); this.cache = new ContextCache(projectRoot);
this.analyzer = new ContextAnalyzer(projectRoot); this.analyzer = new ContextAnalyzer(projectRoot);
this.externalOpenaiInstance = openaiInstance;
// Default configuration // Default configuration
this.config = { this.config = {
@@ -60,24 +67,30 @@ export class IterativeContextBuilder {
await configManager.initialize(this.projectRoot); await configManager.initialize(this.projectRoot);
this.tokenBudget = configManager.getMaxTokens(); this.tokenBudget = configManager.getMaxTokens();
// Initialize OpenAI instance // Use external OpenAI instance if provided, otherwise create a new one
const qenvInstance = new plugins.qenv.Qenv(); if (this.externalOpenaiInstance) {
const openaiToken = await qenvInstance.getEnvVarOnDemand('OPENAI_TOKEN'); this.openaiInstance = this.externalOpenaiInstance;
if (!openaiToken) { } else {
throw new Error('OPENAI_TOKEN environment variable is required for iterative context building'); // 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 * Build context iteratively using AI decision making
* @param taskType - Type of task being performed * @param taskType - Type of task being performed
* @param additionalContext - Optional additional context (e.g., git diff for commit tasks)
* @returns Complete iterative context result * @returns Complete iterative context result
*/ */
public async buildContextIteratively(taskType: TaskType): Promise<IIterativeContextResult> { public async buildContextIteratively(taskType: TaskType, additionalContext?: string): Promise<IIterativeContextResult> {
const startTime = Date.now(); const startTime = Date.now();
logger.log('info', '🤖 Starting iterative context building...'); logger.log('info', '🤖 Starting iterative context building...');
logger.log('info', ` Task: ${taskType}, Budget: ${this.tokenBudget} tokens, Max iterations: ${this.config.maxIterations}`); logger.log('info', ` Task: ${taskType}, Budget: ${this.tokenBudget} tokens, Max iterations: ${this.config.maxIterations}`);
@@ -100,6 +113,21 @@ export class IterativeContextBuilder {
let loadedContent = ''; let loadedContent = '';
const includedFiles: IFileInfo[] = []; 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 // Phase 3: Iterative file selection and loading
for (let iteration = 1; iteration <= this.config.maxIterations; iteration++) { for (let iteration = 1; iteration <= this.config.maxIterations; iteration++) {
const iterationStart = Date.now(); const iterationStart = Date.now();

View File

@@ -9,14 +9,17 @@ import type { IIterativeContextResult, TaskType } from './types.js';
export class TaskContextFactory { export class TaskContextFactory {
private projectDir: string; private projectDir: string;
private configManager: ConfigManager; private configManager: ConfigManager;
private openaiInstance?: any; // OpenAI provider instance
/** /**
* Create a new TaskContextFactory * Create a new TaskContextFactory
* @param projectDirArg The project directory * @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.projectDir = projectDirArg;
this.configManager = ConfigManager.getInstance(); this.configManager = ConfigManager.getInstance();
this.openaiInstance = openaiInstance;
} }
/** /**
@@ -32,7 +35,8 @@ export class TaskContextFactory {
public async createContextForReadme(): Promise<IIterativeContextResult> { public async createContextForReadme(): Promise<IIterativeContextResult> {
const iterativeBuilder = new IterativeContextBuilder( const iterativeBuilder = new IterativeContextBuilder(
this.projectDir, this.projectDir,
this.configManager.getIterativeConfig() this.configManager.getIterativeConfig(),
this.openaiInstance
); );
await iterativeBuilder.initialize(); await iterativeBuilder.initialize();
return await iterativeBuilder.buildContextIteratively('readme'); return await iterativeBuilder.buildContextIteratively('readme');
@@ -44,7 +48,8 @@ export class TaskContextFactory {
public async createContextForDescription(): Promise<IIterativeContextResult> { public async createContextForDescription(): Promise<IIterativeContextResult> {
const iterativeBuilder = new IterativeContextBuilder( const iterativeBuilder = new IterativeContextBuilder(
this.projectDir, this.projectDir,
this.configManager.getIterativeConfig() this.configManager.getIterativeConfig(),
this.openaiInstance
); );
await iterativeBuilder.initialize(); await iterativeBuilder.initialize();
return await iterativeBuilder.buildContextIteratively('description'); return await iterativeBuilder.buildContextIteratively('description');
@@ -52,16 +57,16 @@ export class TaskContextFactory {
/** /**
* Create context for commit message generation * 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<IIterativeContextResult> { public async createContextForCommit(gitDiff?: string): Promise<IIterativeContextResult> {
const iterativeBuilder = new IterativeContextBuilder( const iterativeBuilder = new IterativeContextBuilder(
this.projectDir, this.projectDir,
this.configManager.getIterativeConfig() this.configManager.getIterativeConfig(),
this.openaiInstance
); );
await iterativeBuilder.initialize(); await iterativeBuilder.initialize();
// Note: git diff could be incorporated into the iterative prompts if needed return await iterativeBuilder.buildContextIteratively('commit', gitDiff);
return await iterativeBuilder.buildContextIteratively('commit');
} }
/** /**