import { seedRuntimeLanguageReminder } from "../features/language/index.js";
import { writeContinuationSnapshot, renderContinuationContext } from "../features/continuation-state/index.js";
import { buildOrchestratorState, renderOrchestratorContext } from "../features/orchestrator-loop/index.js";
import { listProfessorMemory, renderProfessorMemoryContext } from "../features/professor-memory/index.js";
import { createRunStore, getActiveRun, getRun } from "../features/run-state/index.js";
import { findAgentThreadBySession, listAgentThreadHelpers, renderAgentThreadContext } from "../features/agent-thread/index.js";
import { resumeLabMeeting } from "../features/lab-meeting/index.js";
import { buildTeamRosterSnapshot, findTeamMemberBySession, listTeamInbox, listTeamMeetings, listTeamTasks, loadMemberMemory, loadTeamRuntime, renderMemberMemoryContext, renderTeamMeetingContext, renderTeamMemberContract, renderTeamRosterContext } from "../features/team-mode/index.js";
import { planContextInjection, renderContextAttachments, upsertContextBundle } from "../features/context-ledger/index.js";
import { clearSeedCommandSession, recordSeedCommandText } from "./command-mode.js";
export function createMessagesTransformHandler(ctx) {
    const store = createRunStore(ctx.input.directory, ctx.config);
    return async function messagesTransform(_input, output) {
        const injectContinuation = ctx.config.continuation.enabled && ctx.config.continuation.inject_on_chat;
        const target = findLatestRealUserMessage(output.messages);
        if (!target)
            return;
        const latestUserText = textPartValue(target.message.parts[target.textPartIndex]);
        if (!latestUserText || !recordSeedCommandText(ctx, target.message.info.sessionID, latestUserText, "messages_transform")) {
            clearSeedCommandSession(ctx, target.message.info.sessionID);
        }
        const hasContinuationContext = hasSyntheticText(target.message, "SEED continuation context");
        const active = await getActiveRun(store);
        if (!active)
            return;
        const run = await getRun(store, active.run_id);
        if (!run || run.status === "completed" || run.status === "stopped")
            return;
        const sessionId = target.message.info.sessionID;
        const runtime = await loadTeamRuntime(store, run.run_id);
        const thread = sessionId ? await findAgentThreadBySession(store, run.run_id, sessionId) : undefined;
        const member = findTeamMemberBySession(runtime, sessionId) ?? (thread && runtime ? runtime.members.find((candidate) => candidate.name === thread.thread_id) : undefined);
        const isRootSession = !run.root_session_id || !sessionId || run.root_session_id === sessionId;
        if (!isRootSession && !member && !thread)
            return;
        const injections = [];
        const contextBundleRefs = [];
        const addContext = async (input) => {
            if (!input.text.trim())
                return;
            if (!ctx.config.context_ledger.enabled) {
                injections.push({
                    id: input.id,
                    messageID: target.message.info.id,
                    sessionID: sessionId ?? "",
                    type: "text",
                    text: input.text,
                    synthetic: true,
                });
                return;
            }
            const bundle = await upsertContextBundle(store, run.run_id, {
                bundle_id: input.id,
                category: input.category,
                scope: input.scope,
                title: input.title,
                body: input.text,
                owner_agent: input.ownerAgent,
                owner_thread_id: input.ownerThreadId,
                metadata: {
                    source: "messages_transform",
                    session_id: sessionId,
                    legacy_marker: input.legacyMarker,
                },
            });
            contextBundleRefs.push(`context:${bundle.bundle_id}`);
        };
        const latestText = latestUserText ?? "";
        if (isRootSession && run.status === "awaiting_feedback" && !latestText.includes("<seed-command>") && !hasSyntheticText(target.message, "SEED Lab Meeting feedback accepted")) {
            await resumeLabMeeting(store, run.run_id, {
                feedback: latestText,
                decision: "continue",
            });
            const continuation = await writeContinuationSnapshot(store, run.run_id, {
                reason: "lab_meeting_resume",
                sessionId,
                recordEvent: true,
            });
            injections.push({
                id: `seed-lab-meeting-feedback-${run.run_id}`,
                messageID: target.message.info.id,
                sessionID: sessionId ?? "",
                type: "text",
                text: `<system-reminder>
[SEED Lab Meeting feedback accepted]
The active run was awaiting Lab Meeting feedback. The professor's latest normal chat message has been recorded as feedback and the run is resumed.
Continuation context: ${continuation.markdown_path}

Lab-Representative: treat the professor message below as the meeting feedback, re-plan if priorities changed, then continue the SEED plan-execute-verify loop. Do not wait for a separate slash command.
</system-reminder>`,
                synthetic: true,
            });
        }
        if (!hasSyntheticText(target.message, "SEED language preference")) {
            injections.push({
                id: `seed-language-${run.run_id}`,
                messageID: target.message.info.id,
                sessionID: sessionId ?? "",
                type: "text",
                text: seedRuntimeLanguageReminder(ctx.config),
                synthetic: true,
            });
        }
        if (isRootSession && injectContinuation && !hasContinuationContext) {
            const result = await writeContinuationSnapshot(store, run.run_id, {
                reason: "chat_message_context",
                sessionId,
                recordEvent: false,
            });
            await addContext({
                id: `seed-continuation-${run.run_id}`,
                title: "SEED continuation context",
                category: "warm",
                scope: "run",
                text: renderContinuationContext(result.snapshot, ctx.config.continuation.context_max_chars),
                legacyMarker: "SEED continuation context",
            });
        }
        if (isRootSession && !hasSyntheticText(target.message, "SEED orchestrator loop")) {
            const state = await buildOrchestratorState(store, run.run_id);
            await addContext({
                id: `seed-orchestrator-${run.run_id}`,
                title: "SEED orchestrator loop",
                category: "warm",
                scope: "run",
                text: renderOrchestratorContext(state),
                legacyMarker: "SEED orchestrator loop",
            });
        }
        if (isRootSession && !hasSyntheticText(target.message, "SEED professor memory")) {
            const memoryContext = renderProfessorMemoryContext(await listProfessorMemory(store, { reusableOnly: true }));
            if (memoryContext) {
                await addContext({
                    id: `seed-professor-memory-${run.run_id}`,
                    title: "SEED professor memory",
                    category: "memory",
                    scope: "run",
                    text: memoryContext,
                    legacyMarker: "SEED professor memory",
                });
            }
        }
        if (runtime && member && !hasSyntheticText(target.message, "SEED member contract")) {
            await addContext({
                id: `seed-member-contract-${run.run_id}-${member.name}`,
                title: `SEED member contract: ${member.name}`,
                category: "stable",
                scope: "agent_thread",
                text: renderTeamMemberContract(run.run_id, runtime, member),
                ownerAgent: member.name,
                ownerThreadId: member.name,
                legacyMarker: "SEED member contract",
            });
        }
        if (member && !hasSyntheticText(target.message, "SEED member memory")) {
            const memoryContext = renderMemberMemoryContext(await loadMemberMemory(store, run.run_id, String(member.name)));
            if (memoryContext) {
                await addContext({
                    id: `seed-member-memory-${run.run_id}-${member.name}`,
                    title: `SEED member memory: ${member.name}`,
                    category: "memory",
                    scope: "agent_thread",
                    text: memoryContext,
                    ownerAgent: member.name,
                    ownerThreadId: member.name,
                    legacyMarker: "SEED member memory",
                });
            }
        }
        if (thread && !hasSyntheticText(target.message, "SEED agent-thread context")) {
            const [helpers, unread, tasks] = await Promise.all([
                listAgentThreadHelpers(store, run.run_id, thread.thread_id),
                listTeamInbox(store, run.run_id, thread.thread_id, { includeAcknowledged: false }),
                listTeamTasks(store, run.run_id),
            ]);
            const openTaskIds = tasks
                .filter((task) => task.owner_agent === thread.thread_id && task.status !== "completed" && task.status !== "cancelled")
                .map((task) => task.team_task_id);
            await addContext({
                id: `seed-agent-thread-${run.run_id}-${thread.thread_id}`,
                title: `SEED agent-thread context: ${thread.thread_id}`,
                category: "warm",
                scope: "agent_thread",
                text: renderAgentThreadContext({
                    thread,
                    helpers,
                    unreadMessageCount: unread.length,
                    openTaskIds,
                }),
                ownerAgent: thread.thread_id,
                ownerThreadId: thread.thread_id,
                legacyMarker: "SEED agent-thread context",
            });
        }
        if (runtime) {
            const teamContext = await renderTeamRuntimeContext(store, run.run_id, runtime, member?.name);
            if (teamContext && !hasSyntheticText(target.message, "SEED team context")) {
                await addContext({
                    id: `seed-team-context-${run.run_id}`,
                    title: "SEED team context",
                    category: "warm",
                    scope: "run",
                    text: teamContext,
                    legacyMarker: "SEED team context",
                });
            }
        }
        if (runtime && !hasSyntheticText(target.message, "SEED team meetings")) {
            const meetingContext = renderTeamMeetingContext(await listTeamMeetings(store, run.run_id, {
                status: "open",
                participant: member ? String(member.name) : undefined,
            }), member ? String(member.name) : undefined);
            if (meetingContext) {
                await addContext({
                    id: `seed-team-meetings-${run.run_id}`,
                    title: "SEED team meetings",
                    category: "hot",
                    scope: "meeting",
                    text: meetingContext,
                    legacyMarker: "SEED team meetings",
                });
            }
        }
        if (member && !hasSyntheticText(target.message, "SEED team mailbox")) {
            const mailbox = await renderTeamMailboxContext(store, run.run_id, member.name);
            if (mailbox) {
                await addContext({
                    id: `seed-team-mailbox-${run.run_id}-${member.name}`,
                    title: `SEED team mailbox: ${member.name}`,
                    category: "hot",
                    scope: "message",
                    text: mailbox,
                    ownerAgent: member.name,
                    ownerThreadId: member.name,
                    legacyMarker: "SEED team mailbox",
                });
            }
        }
        if (contextBundleRefs.length && !hasSyntheticText(target.message, "SEED context ledger attachments")) {
            const turnKind = "root_chat";
            const plan = await planContextInjection(store, {
                turn_kind: turnKind,
                run_id: run.run_id,
                actor: member?.name ?? run.active_agent,
                target_agent: member?.name ?? run.active_agent,
                target_thread_id: thread?.thread_id ?? member?.name,
                bundle_ids: contextBundleRefs,
            });
            const contextText = renderContextAttachments(plan);
            if (contextText) {
                injections.push({
                    id: `seed-context-ledger-${run.run_id}-${sessionId ?? "root"}`,
                    messageID: target.message.info.id,
                    sessionID: sessionId ?? "",
                    type: "text",
                    text: contextText,
                    synthetic: true,
                });
            }
        }
        target.message.parts.splice(target.textPartIndex, 0, ...injections);
    };
}
function textPartValue(part) {
    return part?.type === "text" && "text" in part && typeof part.text === "string" ? part.text : undefined;
}
function findLatestRealUserMessage(messages) {
    for (let index = messages.length - 1; index >= 0; index -= 1) {
        const message = messages[index];
        if (!message || message.info.role !== "user")
            continue;
        const textPartIndex = message.parts.findIndex((part) => (part.type === "text"
            && "text" in part
            && typeof part.text === "string"
            && part.text.length > 0
            && !("synthetic" in part && part.synthetic === true)));
        if (textPartIndex >= 0)
            return { message, textPartIndex };
    }
    return undefined;
}
async function renderTeamRuntimeContext(store, runId, runtime, memberName) {
    const snapshot = await buildTeamRosterSnapshot(store, runId, runtime, memberName);
    return renderTeamRosterContext(snapshot);
}
async function renderTeamMailboxContext(store, runId, memberName) {
    const messages = await listTeamInbox(store, runId, memberName, { includeAcknowledged: false });
    if (!messages.length)
        return undefined;
    return `<system-reminder>
[SEED team mailbox]
Member: ${memberName}
Unread messages:
${messages.slice(0, 10).map((message) => `- ${message.message_id} from:${message.from} kind:${message.kind} ${message.body}`).join("\n")}

Use seed_team_ack after reading messages that are no longer actionable.
</system-reminder>`;
}
function hasSyntheticText(message, marker) {
    return message.parts.some((part) => part.type === "text" && "text" in part && typeof part.text === "string" && part.text.includes(marker));
}
//# sourceMappingURL=messages-transform.js.map