@nomyx/assistant
Version:
A powerful assistant library and cli for your AI projects. works with Vertex AI (Claude and Gemini)
163 lines (162 loc) • 7.54 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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AIAssistant = void 0;
const events_1 = require("events");
const uuid_1 = require("uuid");
const dotenv = __importStar(require("dotenv"));
const path = __importStar(require("path"));
const PersistentState_1 = require("./PersistentState");
const RequestHistory_1 = require("./RequestHistory");
const ContextManager_1 = require("./ContextManager");
const TaskExecutor_1 = require("./TaskExecutor");
const AIProviderFactory_1 = require("./ai/AIProviderFactory");
const ProviderInitializer_1 = require("./providers/ProviderInitializer");
const ToolAndPromptLoader_1 = require("./utils/ToolAndPromptLoader");
dotenv.config();
class AIAssistant extends events_1.EventEmitter {
constructor(logger, options = {}) {
super();
this.logger = logger;
this.options = options;
this.tools = {};
this.prompts = {};
this.middlewares = [];
this.state = new PersistentState_1.PersistentState(options.statePersistenceDir, logger);
this.history = new RequestHistory_1.RequestHistory(options.maxHistoryLength || 5);
this.context = new ContextManager_1.ContextManager(logger);
this.providerInitializer = new ProviderInitializer_1.ProviderInitializer(logger);
this.toolAndPromptLoader = new ToolAndPromptLoader_1.ToolAndPromptLoader(logger);
}
async initialize() {
this.initializeProvider(this.options.providerName);
await this.initializeToolsAndPrompts(this.options.toolsPath, this.options.promptsPath);
this.logger.debug('Prompts before creating TaskExecutor:', { promptNames: Object.keys(this.prompts) });
this.taskExecutor = new TaskExecutor_1.TaskExecutor(this.provider, this.state, this.history, this.context, this.tools, this.prompts, this.logger);
this.updateWorkingDirectory(this.options.initialWorkingDirectory || process.cwd());
this.logger.info('AIAssistant initialized');
}
initializeProvider(providerName) {
const config = this.providerInitializer.initializeProvider(providerName);
const factory = new AIProviderFactory_1.AIProviderFactory(this.logger);
this.provider = factory.createProvider(config);
this.logger.info(`Initialized AI provider: ${this.provider.constructor.name} with config: ${JSON.stringify(config)}`);
}
async initializeToolsAndPrompts(toolsPath, promptsPath) {
const { tools, prompts } = await this.toolAndPromptLoader.initializeToolsAndPrompts(toolsPath, promptsPath);
this.tools = tools;
this.prompts = prompts;
}
async processRequest(input) {
const requestId = (0, uuid_1.v4)();
this.emit('requestStart', { requestId, input });
this.logger.info(`Processing request: ${requestId}`, { input });
try {
let result = await this.taskExecutor.execute(input);
// Apply middlewares
for (const middleware of this.middlewares) {
result = await middleware.process(result);
}
this.history.addEntry(input, result);
this.emit('requestComplete', { requestId, result });
this.logger.info(`Request completed: ${requestId}`);
return result;
}
catch (error) {
this.emit('requestError', { requestId, error });
this.logger.error(`Error processing request: ${requestId}`, { error });
throw error;
}
}
async *processRequestStream(input) {
const requestId = (0, uuid_1.v4)();
this.emit('requestStart', { requestId, input });
this.logger.info(`Processing streaming request: ${requestId}`, { input });
try {
const stream = this.taskExecutor.executeStream(input);
let fullResponse = '';
for await (const chunk of stream) {
fullResponse += chunk;
yield chunk;
}
// Apply middlewares to the full response
for (const middleware of this.middlewares) {
fullResponse = await middleware.process(fullResponse);
}
this.history.addEntry(input, fullResponse);
this.emit('requestComplete', { requestId, result: fullResponse });
this.logger.info(`Streaming request completed: ${requestId}`);
}
catch (error) {
this.emit('requestError', { requestId, error });
this.logger.error(`Error processing streaming request: ${requestId}`, { error });
throw error;
}
}
async *processRequestStreamWithDetails(input) {
const requestId = (0, uuid_1.v4)();
this.emit('requestStart', { requestId, input });
this.logger.info(`Processing detailed streaming request: ${requestId}`, { input });
try {
const stream = this.taskExecutor.executeStreamWithDetails(input);
let fullResponse = '';
for await (const chunk of stream) {
if (chunk.content) {
fullResponse += chunk.content;
}
yield chunk;
}
// Apply middlewares to the full response
for (const middleware of this.middlewares) {
fullResponse = await middleware.process(fullResponse);
}
this.history.addEntry(input, fullResponse);
this.emit('requestComplete', { requestId, result: fullResponse });
this.logger.info(`Detailed streaming request completed: ${requestId}`);
}
catch (error) {
this.emit('requestError', { requestId, error });
this.logger.error(`Error processing detailed streaming request: ${requestId}`, { error });
throw error;
}
}
updateWorkingDirectory(newWorkingDirectory) {
const normalizedPath = path.normalize(newWorkingDirectory);
this.context.updateContext({
currentWorkingDirectory: normalizedPath,
parentDirectory: path.dirname(normalizedPath),
directoryName: path.basename(normalizedPath)
});
this.logger.info(`Updated working directory: ${normalizedPath}`);
}
getProvider() {
return this.provider;
}
addMiddleware(middleware) {
this.middlewares.push(middleware);
this.logger.info(`Added middleware: ${middleware.constructor.name}`);
}
}
exports.AIAssistant = AIAssistant;