@n1k1t/unit-generator
Version:
Coverage based unit tests AI generator
181 lines • 6.81 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Assistant = void 0;
const events_1 = __importDefault(require("events"));
const promises_1 = __importDefault(require("fs/promises"));
const lodash_1 = __importDefault(require("lodash"));
const llm_1 = require("../llm");
const source_1 = require("./source");
const utils_1 = require("../../utils");
const strategies = __importStar(require("./strategies"));
const env_1 = __importDefault(require("../../env"));
__exportStar(require("./strategies"), exports);
__exportStar(require("./source"), exports);
__exportStar(require("./types"), exports);
class Assistant {
constructor(source, strategies, context) {
this.source = source;
this.strategies = strategies;
this.context = context;
this.status = 'PREPARING';
this.steps = [];
this.state = {
strategy: '⏱',
};
this.counter = (0, utils_1.buildCounter)(1);
this.events = new events_1.default();
this.spent = 0;
strategies.forEach((strategy) => {
strategy.on('tool', (payload) => {
this.state.action = {
type: 'tool',
status: payload.status,
message: `[${payload.iteration}] ${payload.name}`,
};
});
strategy.on('reasoning', (payload) => {
this.state.action = {
type: 'reasoning',
status: 'OK',
message: `[${payload.iteration}] ${lodash_1.default.truncate(payload.text, { length: 25 })}`,
};
});
});
}
calculateTimeSpent() {
return this.is(['PREPARING', 'COMPLETED'])
? this.spent
: (Date.now() - this.source.timestamp);
}
async clear() {
await promises_1.default.rm(this.source.temp, { recursive: true, force: true });
if (!this.source.spec.content.length) {
await this.source.spec.remove();
}
}
async run(iterations = this.context.iterations) {
if (this.source.checkHasReachedCoverage()) {
return this.complete();
}
if (this.is(['PREPARING'])) {
this.source.refresh();
this.status = 'PENDING';
}
const skipsCounter = (0, utils_1.buildCounter)();
const step = this.register({
status: 'PREPARING',
strategy: '⏱',
snapshot: this.source.compileSnapshot(),
iteration: this.counter(),
});
for await (const strategy of this.strategies) {
if (this.context.strategies?.length && !this.context.strategies.includes(strategy.name)) {
continue;
}
this.state.strategy = strategy.name;
const status = await strategy.run();
if (status === 'SKIPPED') {
skipsCounter();
continue;
}
if (status === 'DONE') {
await this.source.spec.pretty();
}
step.strategy = strategy.name;
step.status = status;
break;
}
if (skipsCounter(0) === this.context.strategies?.length) {
return this.complete();
}
return this.counter(0) <= iterations
? this.run(iterations)
: this.complete();
}
is(statuses) {
return statuses.includes(this.status);
}
on(key, listener) {
this.events.on(key, listener);
return this;
}
once(key, listener) {
this.events.once(key, listener);
return this;
}
emit(key, ...args) {
this.events.emit(key, ...args);
return this;
}
async complete() {
this.spent = this.calculateTimeSpent();
this.status = 'COMPLETED';
return this.clear();
}
register(step) {
this.steps.push(step);
this.emit('step', step);
this.state.strategy = step.strategy;
this.state.action = undefined;
return step;
}
static async build(location, options) {
const cwd = options?.cwd ?? process.cwd();
const source = await source_1.AssistantSource.build(location, options);
const router = llm_1.LlmRouter.build();
const provider = router.provide(options?.model ?? env_1.default.model);
const compiled = [
strategies.AssistantInitStrategy.build(source, { provider, target: options?.target }),
strategies.AssistantAddStrategy.build(source, { provider, target: options?.target }),
strategies.AssistantFixStrategy.build(source, { provider, target: options?.target }),
];
return new Assistant(source, compiled, {
cwd,
provider,
target: options?.target ?? env_1.default.target,
iterations: options?.iterations ?? env_1.default.iterations,
strategies: options?.strategies,
});
}
}
exports.Assistant = Assistant;
//# sourceMappingURL=index.js.map