import { getLogger as getLogger$1 } from "../../../../logger.js";
import { SESSION_CLEANUP_INTERVAL_MS, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS } from "../../constants/execution-limits/index.js";
import { generateId } from "@inkeep/agents-core";

//#region src/domains/run/agents/services/ToolSessionManager.ts
const logger = getLogger$1("ToolSessionManager");
/**
* Manages tool execution state during agent generation sessions.
* Allows tools to access previous tool call results within the same execution.
*/
var ToolSessionManager = class ToolSessionManager {
	static instance;
	sessions = /* @__PURE__ */ new Map();
	constructor() {
		setInterval(() => this.cleanupExpiredSessions(), SESSION_CLEANUP_INTERVAL_MS);
	}
	static getInstance() {
		if (!ToolSessionManager.instance) ToolSessionManager.instance = new ToolSessionManager();
		return ToolSessionManager.instance;
	}
	/**
	* Create a new tool session for an agent execution
	*/
	createSession(tenantId, projectId, contextId, taskId) {
		const sessionId = generateId();
		return this.createSessionWithId(sessionId, tenantId, projectId, contextId, taskId);
	}
	/**
	* Create a new tool session with a specific ID (for coordination with AgentSession)
	*/
	createSessionWithId(sessionId, tenantId, projectId, contextId, taskId) {
		const session = {
			sessionId,
			tenantId,
			projectId,
			contextId,
			taskId,
			toolResults: /* @__PURE__ */ new Map(),
			createdAt: Date.now()
		};
		this.sessions.set(sessionId, session);
		logger.debug({
			sessionId,
			tenantId,
			contextId,
			taskId,
			totalSessions: this.sessions.size
		}, "Created tool session with ID");
		return sessionId;
	}
	/**
	* Ensure an agent-scoped session exists (idempotent)
	* All agents in the same agent execution share this session
	*/
	ensureAgentSession(sessionId, tenantId, projectId, contextId, taskId) {
		if (this.sessions.has(sessionId)) {
			logger.debug({ sessionId }, "Agent session already exists, reusing");
			return sessionId;
		}
		logger.debug({
			sessionId,
			tenantId,
			contextId,
			taskId
		}, "Creating new agent-scoped tool session");
		return this.createSessionWithId(sessionId, tenantId, projectId, contextId, taskId);
	}
	/**
	* Record a tool result in the session
	*/
	recordToolResult(sessionId, toolResult) {
		const session = this.sessions.get(sessionId);
		if (!session) {
			logger.warn({
				sessionId,
				toolCallId: toolResult.toolCallId,
				availableSessionIds: Array.from(this.sessions.keys()),
				totalSessions: this.sessions.size
			}, "Tool result recorded for unknown session");
			return;
		}
		session.toolResults.set(toolResult.toolCallId, toolResult);
		logger.debug({
			sessionId,
			toolCallId: toolResult.toolCallId,
			toolName: toolResult.toolName
		}, "Tool result recorded successfully");
	}
	/**
	* Get a tool result by toolCallId within a session
	*/
	getToolResult(sessionId, toolCallId) {
		const session = this.sessions.get(sessionId);
		if (!session) {
			logger.warn({
				sessionId,
				toolCallId,
				availableSessionIds: Array.from(this.sessions.keys()),
				totalSessions: this.sessions.size
			}, "Requested tool result for unknown session");
			return;
		}
		const result = session.toolResults.get(toolCallId);
		if (!result) logger.warn({
			sessionId,
			toolCallId,
			availableToolResultIds: Array.from(session.toolResults.keys()),
			totalToolResults: session.toolResults.size
		}, "Tool result not found");
		else logger.debug({
			sessionId,
			toolCallId,
			toolName: result.toolName
		}, "Tool result found successfully");
		return result;
	}
	/**
	* Get session info
	*/
	getSession(sessionId) {
		return this.sessions.get(sessionId);
	}
	/**
	* Clean up a session after agent execution completes
	*/
	endSession(sessionId) {
		if (this.sessions.get(sessionId)) this.sessions.delete(sessionId);
	}
	/**
	* Remove expired sessions to prevent memory leaks
	*/
	cleanupExpiredSessions() {
		const now = Date.now();
		const expiredSessions = [];
		for (const [sessionId, session] of this.sessions.entries()) if (now - session.createdAt > SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS) expiredSessions.push(sessionId);
		for (const sessionId of expiredSessions) {
			this.sessions.delete(sessionId);
			logger.debug({ sessionId }, "Cleaned up expired tool session");
		}
		if (expiredSessions.length > 0) logger.info({ expiredCount: expiredSessions.length }, "Cleaned up expired tool sessions");
	}
};
const toolSessionManager = ToolSessionManager.getInstance();

//#endregion
export { ToolSessionManager, toolSessionManager };