import { createLogger } from "../../utils/logger/index.js";
import { init_logger } from "../../utils/logger.js";
import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
import { createResponseMessage, createSignalMessage, createTaskMessage } from "./types.js";
import { AgentInbox } from "./inbox.js";
//#region src/agent/ipc/bus.ts
init_logger();
init_agent_scope();
const log = createLogger("AgentBus");
var AgentBus = class {
	appConfig;
	agentId;
	inbox;
	responseHandlers = /* @__PURE__ */ new Map();
	unsubscribe;
	constructor(appConfig, _stateDir, agentId) {
		this.appConfig = appConfig;
		this.agentId = agentId ?? resolveDefaultAgentId(appConfig);
		this.inbox = AgentInbox.forAgent(appConfig, this.agentId);
	}
	/**
	* Start listening for messages
	*/
	async startListening(handler) {
		this.unsubscribe = await this.inbox.watch(async (msg) => {
			if (msg.replyTo && this.responseHandlers.has(msg.replyTo)) {
				const handler = this.responseHandlers.get(msg.replyTo);
				clearTimeout(handler.timeout);
				this.responseHandlers.delete(msg.replyTo);
				handler.resolve(msg);
				return;
			}
			await handler(msg);
		});
		log.info({ agentId: this.agentId }, "AgentBus started listening");
	}
	/**
	* Stop listening for messages
	*/
	stopListening() {
		this.unsubscribe?.();
		this.unsubscribe = void 0;
		for (const [_id, handler] of this.responseHandlers) {
			clearTimeout(handler.timeout);
			handler.reject(/* @__PURE__ */ new Error("AgentBus stopped listening"));
		}
		this.responseHandlers.clear();
		this.inbox.stopWatching();
		log.info({ agentId: this.agentId }, "AgentBus stopped listening");
	}
	/**
	* Send a task to another agent
	*/
	async sendTask(targetAgentId, task, options = {}) {
		const message = createTaskMessage(this.agentId, targetAgentId, task, {
			...options,
			callbackAgentId: options.callbackAgentId || this.agentId
		});
		await this.deliverMessage(targetAgentId, message);
		log.debug({
			messageId: message.id,
			from: this.agentId,
			to: targetAgentId
		}, "Task sent");
		return message.id;
	}
	/**
	* Send a task and wait for response
	*/
	async sendTaskAndWait(targetAgentId, task, options = {}) {
		const messageId = await this.sendTask(targetAgentId, task, options);
		return this.waitForResponse(messageId, options.timeoutMs);
	}
	/**
	* Send a signal to another agent
	*/
	async sendSignal(targetAgentId, signal, data) {
		const message = createSignalMessage(this.agentId, targetAgentId, signal, data);
		await this.deliverMessage(targetAgentId, message);
		log.debug({
			messageId: message.id,
			from: this.agentId,
			to: targetAgentId,
			signal
		}, "Signal sent");
	}
	/**
	* Wait for a response to a specific message
	*/
	async waitForResponse(messageId, timeoutMs = 3e5) {
		return new Promise((resolve, reject) => {
			const timeout = setTimeout(() => {
				this.responseHandlers.delete(messageId);
				reject(/* @__PURE__ */ new Error(`Timeout waiting for response to ${messageId}`));
			}, timeoutMs);
			this.responseHandlers.set(messageId, {
				resolve: (msg) => {
					if (msg.type === "response") resolve(msg);
					else reject(/* @__PURE__ */ new Error(`Expected response, got ${msg.type}`));
				},
				reject,
				timeout
			});
		});
	}
	/**
	* Send a response to a message
	*/
	async respond(toMessageId, toAgentId, success, data, error) {
		const message = createResponseMessage(this.agentId, toAgentId, toMessageId, success, data, error);
		await this.deliverMessage(toAgentId, message);
		log.debug({
			messageId: message.id,
			to: toAgentId,
			success
		}, "Response sent");
	}
	/**
	* Get pending message count
	*/
	async getPendingCount() {
		return this.inbox.count();
	}
	/**
	* Peek at pending messages
	*/
	async peekPending(limit = 10) {
		return this.inbox.peek(limit);
	}
	async deliverMessage(targetAgentId, message) {
		await AgentInbox.forAgent(this.appConfig, targetAgentId).enqueue(message);
	}
};
//#endregion
export { AgentBus };

//# sourceMappingURL=bus.js.map