import { AsyncLocalStorage } from "node:async_hooks";
//#region src/agent/session/session-context.ts
/**
* Session Context — types + an `AsyncLocalStorage`-backed manager.
*
* The previous implementation kept the "current" session context in a single
* mutable field on the class. That meant bus-inbound and direct-stream paths
* concurrently handling different sessions could overwrite each other's view
* of "current session", with tools reading the wrong sessionKey at execution
* time (the only thing masking it was the inbound consumer being serial).
*
* The new manager uses `AsyncLocalStorage`, so each async chain sees its own
* context. Callers establish a scope via {@link SessionContextManager.runWith}
* (preferred for `async` functions) or {@link SessionContextManager.enter}
* (used at the top of `async function*` generators where callback-wrapping is
* awkward; the context leaks into the rest of the current async resource by
* design).
*/
var SessionContextManager = class {
	als = new AsyncLocalStorage();
	/**
	* Run `fn` with `ctx` exposed via {@link getContext} for every async branch
	* it launches. The context is automatically dropped when `fn` resolves or
	* throws — there is no manual `clearContext` needed.
	*/
	async runWith(ctx, fn) {
		return this.als.run(ctx, fn);
	}
	/**
	* Establish a context for the current async resource and its descendants.
	* Use this at the top of an `async function*` body where wrapping the whole
	* generator in {@link runWith} is impractical. The context leaks into the
	* rest of the current async tree by design — call from the start of an
	* isolated generator so it does not bleed across requests.
	*/
	enter(ctx) {
		this.als.enterWith(ctx);
	}
	/** Returns the session context for the current async chain, or null. */
	getContext() {
		return this.als.getStore() ?? null;
	}
	hasContext() {
		return this.als.getStore() !== void 0;
	}
	/** Extract session context from an inbound bus message. */
	static extractFromMessage(msg) {
		const metadata = msg.metadata || {};
		return {
			sessionKey: metadata.sessionKey || `${msg.channel}:${msg.chat_id}`,
			channel: msg.channel,
			chatId: msg.chat_id,
			senderId: metadata.senderId || "",
			isGroup: metadata.isGroup || false,
			model: metadata.model,
			metadata
		};
	}
	/** Create a clone of the current context with optional overrides. */
	cloneContext(overrides) {
		const current = this.getContext();
		if (!current) return null;
		return {
			...current,
			...overrides
		};
	}
};
//#endregion
export { SessionContextManager };

//# sourceMappingURL=session-context.js.map