Files
tsdoc/ts/classes.aidoc.ts

155 lines
5.5 KiB
TypeScript

import * as plugins from './plugins.js';
import * as aiDocsClasses from './aidocs_classes/index.js';
export class AiDoc {
private openaiToken: string;
public smartconfigKV: plugins.smartconfig.KeyValueStore;
public qenvInstance: plugins.qenv.Qenv;
public aidocInteract: plugins.smartinteract.SmartInteract;
public model: plugins.smartai.LanguageModelV3;
argvArg: any;
constructor(argvArg?: any) {
this.argvArg = argvArg;
}
private printSanitizedToken() {
// Check if the token length is greater than the sum of startLength and endLength
let printToken: string;
if (this.openaiToken.length > 6) {
// Extract the beginning and end parts of the token
const start = this.openaiToken.substring(0, 3);
const end = this.openaiToken.substring(this.openaiToken.length - 3);
printToken = `${start}...${end}`;
} else {
// If the token is not long enough, return it as is
printToken = this.openaiToken;
}
console.log(`OpenAI Token on record: ${printToken}`);
}
public async start() {
// lets care about prerequisites
this.aidocInteract = new plugins.smartinteract.SmartInteract();
this.qenvInstance = new plugins.qenv.Qenv();
if (!(await this.qenvInstance.getEnvVarOnDemand('OPENAI_TOKEN'))) {
// Migrate old KV store path to new path if needed
const homeDir = plugins.smartpath.get.home();
const oldKvPath = plugins.path.join(homeDir, '.smartconfig/kv/tsdoc.json');
const newKvDir = plugins.path.join(homeDir, '.smartconfig/kv/@git.zone');
const newKvPath = plugins.path.join(newKvDir, 'tsdoc.json');
if (
await plugins.fsInstance.file(oldKvPath).exists() &&
!(await plugins.fsInstance.file(newKvPath).exists())
) {
console.log('Migrating tsdoc KeyValueStore to @git.zone/tsdoc...');
await plugins.fsInstance.directory(newKvDir).recursive().create();
await plugins.fsInstance.file(oldKvPath).copy(newKvPath);
await plugins.fsInstance.file(oldKvPath).delete();
console.log('Migration complete: tsdoc.json -> @git.zone/tsdoc.json');
}
this.smartconfigKV = new plugins.smartconfig.KeyValueStore({
typeArg: 'userHomeDir',
identityArg: '@git.zone/tsdoc',
mandatoryKeys: ['OPENAI_TOKEN'],
});
const missingKeys = await this.smartconfigKV.getMissingMandatoryKeys();
if (missingKeys.length > 0) {
// lets try argv
if (this.argvArg?.OPENAI_TOKEN) {
this.openaiToken = this.argvArg.OPENAI_TOKEN;
} else {
// lets try smartinteract
// wait for a second until OpenAI fixes punycode problem...
await plugins.smartdelay.delayFor(1000);
const answerObject = await this.aidocInteract.askQuestion({
type: 'input',
message: `Please provide your OpenAI token. This will be persisted in your home directory.`,
name: 'OPENAI_TOKEN',
default: '',
});
this.openaiToken = answerObject.value;
}
this.printSanitizedToken();
await this.smartconfigKV.writeKey('OPENAI_TOKEN', this.openaiToken);
}
}
if (!this.openaiToken && this.smartconfigKV) {
this.openaiToken = await this.smartconfigKV.readKey('OPENAI_TOKEN');
}
// Create model using getModel()
this.model = plugins.smartai.getModel({
provider: 'openai',
model: 'gpt-5.4',
apiKey: this.openaiToken,
});
}
public async stop() {
// No lifecycle management needed with getModel() API
}
public getOpenaiToken(): string {
return this.openaiToken;
}
public async buildReadme(projectDirArg: string) {
const readmeInstance = new aiDocsClasses.Readme(this, projectDirArg);
return await readmeInstance.build();
}
public async buildDescription(projectDirArg: string) {
const descriptionInstance = new aiDocsClasses.Description(this, projectDirArg);
return await descriptionInstance.build();
}
public async buildNextCommitObject(projectDirArg: string) {
const commitInstance = new aiDocsClasses.Commit(this, projectDirArg);
return await commitInstance.buildNextCommitObject();
}
public async getProjectContext(projectDirArg: string) {
const projectContextInstance = new aiDocsClasses.ProjectContext(projectDirArg);
return await projectContextInstance.gatherFiles();
}
/**
* Get the context with token count information
* @param projectDirArg The path to the project directory
* @returns An object containing the context string and its token count
*/
public async getProjectContextWithTokenCount(projectDirArg: string) {
const projectContextInstance = new aiDocsClasses.ProjectContext(projectDirArg);
await projectContextInstance.update();
return projectContextInstance.getContextWithTokenCount();
}
/**
* Get just the token count for a project's context
* @param projectDirArg The path to the project directory
* @returns The number of tokens in the project context
*/
public async getProjectContextTokenCount(projectDirArg: string) {
const projectContextInstance = new aiDocsClasses.ProjectContext(projectDirArg);
await projectContextInstance.update();
return projectContextInstance.getTokenCount();
}
/**
* Estimate token count in a text string
* @param text The text to estimate tokens for
* @returns Estimated number of tokens
*/
public countTokens(text: string): number {
const projectContextInstance = new aiDocsClasses.ProjectContext('');
return projectContextInstance.countTokens(text);
}
}