import { y as normalizeChannelId } from "./subsystem-ocBR131w.js";
import { t as INTERNAL_MESSAGE_CHANNEL } from "./message-channel-DSU96OKy.js";
import { r as normalizeChannelId$1, t as getChannelPlugin } from "./plugins-DYgcd4QJ.js";
import { a as stripHeartbeatToken } from "./heartbeat-BJ0mtjXV.js";
import { t as AGENT_LANE_NESTED } from "./lanes-s-MZ35vD.js";
import { n as callGateway } from "./call-C206Z-zx.js";
import { a as stripToolMessages, r as extractAssistantText } from "./sessions-helpers-DYJnJN3U.js";
import crypto from "node:crypto";

//#region src/agents/tools/sessions/sessions-send-helpers.ts
const ANNOUNCE_SKIP_TOKEN = "ANNOUNCE_SKIP";
const REPLY_SKIP_TOKEN = "REPLY_SKIP";
const DEFAULT_PING_PONG_TURNS = 5;
const MAX_PING_PONG_TURNS = 5;
function resolveAnnounceTargetFromKey(sessionKey) {
	const rawParts = sessionKey.split(":").filter(Boolean);
	const parts = rawParts.length >= 3 && rawParts[0] === "agent" ? rawParts.slice(2) : rawParts;
	if (parts.length < 3) return null;
	const [channelRaw, kind, ...rest] = parts;
	if (kind !== "group" && kind !== "channel") return null;
	let threadId;
	const restJoined = rest.join(":");
	const topicMatch = restJoined.match(/:topic:(\d+)$/);
	const threadMatch = restJoined.match(/:thread:(\d+)$/);
	const match = topicMatch || threadMatch;
	if (match) threadId = match[1];
	const id = match ? restJoined.replace(/:(topic|thread):\d+$/, "") : restJoined.trim();
	if (!id) return null;
	if (!channelRaw) return null;
	const normalizedChannel = normalizeChannelId$1(channelRaw) ?? normalizeChannelId(channelRaw);
	const channel = normalizedChannel ?? channelRaw.toLowerCase();
	const kindTarget = (() => {
		if (!normalizedChannel) return id;
		if (normalizedChannel === "discord" || normalizedChannel === "slack") return `channel:${id}`;
		return kind === "channel" ? `channel:${id}` : `group:${id}`;
	})();
	return {
		channel,
		to: (normalizedChannel ? getChannelPlugin(normalizedChannel)?.messaging?.normalizeTarget?.(kindTarget) : void 0) ?? kindTarget,
		threadId
	};
}
function buildAgentToAgentMessageContext(params) {
	return [
		"Agent-to-agent message context:",
		params.requesterSessionKey ? `Agent 1 (requester) session: ${params.requesterSessionKey}.` : void 0,
		params.requesterChannel ? `Agent 1 (requester) channel: ${params.requesterChannel}.` : void 0,
		`Agent 2 (target) session: ${params.targetSessionKey}.`
	].filter(Boolean).join("\n");
}
function buildAgentToAgentReplyContext(params) {
	return [
		"Agent-to-agent reply step:",
		`Current agent: ${params.currentRole === "requester" ? "Agent 1 (requester)" : "Agent 2 (target)"}.`,
		`Turn ${params.turn} of ${params.maxTurns}.`,
		params.requesterSessionKey ? `Agent 1 (requester) session: ${params.requesterSessionKey}.` : void 0,
		params.requesterChannel ? `Agent 1 (requester) channel: ${params.requesterChannel}.` : void 0,
		`Agent 2 (target) session: ${params.targetSessionKey}.`,
		params.targetChannel ? `Agent 2 (target) channel: ${params.targetChannel}.` : void 0,
		`If you want to stop the ping-pong, reply exactly "${REPLY_SKIP_TOKEN}".`
	].filter(Boolean).join("\n");
}
function buildAgentToAgentAnnounceContext(params) {
	return [
		"Agent-to-agent announce step:",
		params.requesterSessionKey ? `Agent 1 (requester) session: ${params.requesterSessionKey}.` : void 0,
		params.requesterChannel ? `Agent 1 (requester) channel: ${params.requesterChannel}.` : void 0,
		`Agent 2 (target) session: ${params.targetSessionKey}.`,
		params.targetChannel ? `Agent 2 (target) channel: ${params.targetChannel}.` : void 0,
		`Original request: ${params.originalMessage}`,
		params.roundOneReply ? `Round 1 reply: ${params.roundOneReply}` : "Round 1 reply: (not available).",
		params.latestReply ? `Latest reply: ${params.latestReply}` : "Latest reply: (not available).",
		`If you want to remain silent, reply exactly "${ANNOUNCE_SKIP_TOKEN}".`,
		"Any other reply will be posted to the target channel.",
		"After this reply, the agent-to-agent conversation is over."
	].filter(Boolean).join("\n");
}
function isAnnounceSkip(text) {
	return (text ?? "").trim() === ANNOUNCE_SKIP_TOKEN;
}
function isReplySkip(text) {
	return (text ?? "").trim() === REPLY_SKIP_TOKEN;
}
function resolvePingPongTurns(cfg) {
	const raw = cfg?.session?.agentToAgent?.maxPingPongTurns;
	const fallback = DEFAULT_PING_PONG_TURNS;
	if (typeof raw !== "number" || !Number.isFinite(raw)) return fallback;
	const rounded = Math.floor(raw);
	return Math.max(0, Math.min(MAX_PING_PONG_TURNS, rounded));
}

//#endregion
//#region src/agents/tools/agent-step.ts
async function readLatestAssistantReply(params) {
	const history = await callGateway({
		method: "chat.history",
		params: {
			sessionKey: params.sessionKey,
			limit: params.limit ?? 50
		}
	});
	const filtered = stripToolMessages(Array.isArray(history?.messages) ? history.messages : []);
	for (let i = filtered.length - 1; i >= 0; i -= 1) {
		const candidate = filtered[i];
		if (!candidate || typeof candidate !== "object") continue;
		if (candidate.role !== "assistant") continue;
		const text = extractAssistantText(candidate);
		if (!text?.trim()) continue;
		if (stripHeartbeatToken(text, { mode: "heartbeat" }).shouldSkip) continue;
		return text;
	}
}
async function runAgentStep(params) {
	const stepIdem = crypto.randomUUID();
	const response = await callGateway({
		method: "agent",
		params: {
			message: params.message,
			sessionKey: params.sessionKey,
			idempotencyKey: stepIdem,
			deliver: false,
			channel: params.channel ?? INTERNAL_MESSAGE_CHANNEL,
			lane: params.lane ?? AGENT_LANE_NESTED,
			extraSystemPrompt: params.extraSystemPrompt,
			inputProvenance: {
				kind: "inter_session",
				sourceSessionKey: params.sourceSessionKey,
				sourceChannel: params.sourceChannel,
				sourceTool: params.sourceTool ?? "sessions_send"
			}
		},
		timeoutMs: 1e4
	});
	const resolvedRunId = (typeof response?.runId === "string" && response.runId ? response.runId : "") || stepIdem;
	const stepWaitMs = Math.min(params.timeoutMs, 6e4);
	if ((await callGateway({
		method: "agent.wait",
		params: {
			runId: resolvedRunId,
			timeoutMs: stepWaitMs
		},
		timeoutMs: stepWaitMs + 2e3
	}))?.status !== "ok") return;
	return await readLatestAssistantReply({ sessionKey: params.sessionKey });
}

//#endregion
export { buildAgentToAgentReplyContext as a, resolveAnnounceTargetFromKey as c, buildAgentToAgentMessageContext as i, resolvePingPongTurns as l, runAgentStep as n, isAnnounceSkip as o, buildAgentToAgentAnnounceContext as r, isReplySkip as s, readLatestAssistantReply as t };