

import { InjectionSymbols } from "../constants.mjs";
import { AgentConfig } from "./AgentConfig.mjs";
import { AgentContext } from "./context/AgentContext.mjs";
import { CredoError } from "../error/CredoError.mjs";
import "../error/index.mjs";
import { DependencyManager } from "../plugins/DependencyManager.mjs";
import "../plugins/index.mjs";
import { DefaultAgentContextProvider } from "./context/DefaultAgentContextProvider.mjs";
import "./context/index.mjs";
import { JwsService } from "../crypto/JwsService.mjs";
import { EventEmitter } from "./EventEmitter.mjs";
import { StorageVersionRepository } from "../storage/migration/repository/StorageVersionRepository.mjs";
import { StorageUpdateService } from "../storage/migration/StorageUpdateService.mjs";
import { UpdateAssistant } from "../storage/migration/UpdateAssistant.mjs";
import "../storage/index.mjs";
import { extendModulesWithDefaultModules } from "./AgentModules.mjs";
import { BaseAgent } from "./BaseAgent.mjs";
import { Subject } from "rxjs";

//#region src/agent/Agent.ts
var Agent = class extends BaseAgent {
	constructor(options, dependencyManager = new DependencyManager()) {
		const agentConfig = new AgentConfig(options.config ?? {}, options.dependencies);
		const modulesWithDefaultModules = extendModulesWithDefaultModules(options.modules);
		dependencyManager.registerSingleton(EventEmitter);
		dependencyManager.registerSingleton(JwsService);
		dependencyManager.registerSingleton(StorageVersionRepository);
		dependencyManager.registerSingleton(StorageUpdateService);
		dependencyManager.registerInstance(AgentConfig, agentConfig);
		dependencyManager.registerInstance(InjectionSymbols.AgentDependencies, agentConfig.agentDependencies);
		dependencyManager.registerInstance(InjectionSymbols.Stop$, new Subject());
		dependencyManager.registerInstance(InjectionSymbols.FileSystem, new agentConfig.agentDependencies.FileSystem());
		dependencyManager.registerModules(modulesWithDefaultModules);
		if (!dependencyManager.isRegistered(InjectionSymbols.Logger)) dependencyManager.registerInstance(InjectionSymbols.Logger, agentConfig.logger);
		if (!dependencyManager.isRegistered(InjectionSymbols.StorageService)) throw new CredoError("Missing required dependency: 'StorageService'. You can register it using the AskarModule, DrizzleStorageModule, or implement your own.");
		dependencyManager.registerInstance(AgentContext, new AgentContext({
			dependencyManager,
			contextCorrelationId: "default",
			isRootAgentContext: true
		}));
		if (!dependencyManager.isRegistered(InjectionSymbols.AgentContextProvider)) dependencyManager.registerSingleton(InjectionSymbols.AgentContextProvider, DefaultAgentContextProvider);
		super(agentConfig, dependencyManager);
	}
	get events() {
		return this.eventEmitter;
	}
	async initialize() {
		if (this._isInitialized) throw new CredoError("Agent already initialized. Currently it is not supported to re-initialize an already initialized agent.");
		await this.dependencyManager.initializeModules(this.agentContext);
		await this.dependencyManager.initializeAgentContext(this.agentContext);
		const storageUpdateService = this.dependencyManager.resolve(StorageUpdateService);
		const isStorageUpToDate = await storageUpdateService.isUpToDate(this.agentContext);
		this.logger.info(`Agent storage is ${isStorageUpToDate ? "" : "not "}up to date.`);
		if (!isStorageUpToDate && this.agentConfig.autoUpdateStorageOnStartup) {
			const updateAssistant = new UpdateAssistant(this);
			await updateAssistant.initialize();
			await updateAssistant.update();
		} else if (!isStorageUpToDate) {
			const currentVersion = await storageUpdateService.getCurrentStorageVersion(this.agentContext);
			await this.dependencyManager.closeAgentContext(this.agentContext);
			throw new CredoError(`Current agent storage is not up to date. To prevent the framework state from getting corrupted the agent initialization is aborted. Make sure to update the agent storage (currently at ${currentVersion}) to the latest version (${UpdateAssistant.frameworkStorageVersion}). You can also downgrade your version of Credo.`);
		}
		this._isInitialized = true;
	}
	async shutdown() {
		this.dependencyManager.resolve(InjectionSymbols.Stop$).next(true);
		await this.dependencyManager.shutdownModules(this.agentContext);
		await this.dependencyManager.closeAgentContext(this.agentContext);
		this._isInitialized = false;
	}
};

//#endregion
export { Agent };
//# sourceMappingURL=Agent.mjs.map