import path from "node:path";
import { DatabaseSync } from "node:sqlite";
import { logger } from "../logger.js";
import { getConfigDir, loadOwnerConfig as loadAgentOwnerConfig } from "../config/index.js";
import { getAgentState } from "../agent/state.js";
import { TOOLS } from "./tools.js";
let voiceDb = null;
export function getVoiceDb() {
    if (voiceDb)
        return voiceDb;
    const dbPath = path.join(getConfigDir(), "transcript-memory.db");
    voiceDb = new DatabaseSync(dbPath);
    voiceDb.exec("PRAGMA journal_mode = WAL");
    voiceDb.exec(`
    CREATE TABLE IF NOT EXISTS voice_sessions (
      session_id      TEXT PRIMARY KEY,
      user_id         TEXT NOT NULL,
      user_name       TEXT,
      timestamp_start TEXT NOT NULL,
      timestamp_end   TEXT NOT NULL,
      duration        INTEGER,
      summary         TEXT,
      transcript      TEXT NOT NULL,
      message_count   INTEGER NOT NULL DEFAULT 0
    )
  `);
    voiceDb.exec(`
    CREATE INDEX IF NOT EXISTS idx_voice_sessions_user
    ON voice_sessions(user_id, timestamp_start DESC)
  `);
    logger.system("[Realtime] SQLite database initialized (voice_sessions table ready)");
    return voiceDb;
}
export function loadOwnerConfig() {
    const owner = loadAgentOwnerConfig();
    return {
        ownerName: owner.ownerName,
        ownerEmail: owner.ownerEmail,
        timezone: owner.timezone ?? "UTC",
        language: owner.language,
        telegramChatId: owner.telegramChatId,
    };
}
const REALTIME_CONTEXT_CHAR_LIMIT = 4_000;
const REALTIME_ACTIVITY_CHAR_LIMIT = 4_000;
const REALTIME_LIMITS = [
    "No desktop control: no clicking, typing, screenshotting, or GUI automation.",
    "No code execution, terminal access, or file edits.",
    "No chat-app automation for WeChat, Feishu, Discord, WhatsApp, or similar apps.",
    "No direct access to the main agent's skill catalog, MCP servers, browser automation, transcript search, or full wake context.",
    "No ability to start, stop, restart, upgrade, or reconfigure the main agent.",
    "No access to historical Telegram or voice transcripts; ongoing work comes only from the live status block in this prompt.",
];
function formatToolCapabilityList() {
    return TOOLS
        .map((tool) => `- ${tool.name}: ${tool.description}`)
        .join("\n");
}
function formatCurrentTime(timezone) {
    const current = new Date().toLocaleString("en-US", {
        timeZone: timezone,
        dateStyle: "full",
        timeStyle: "long",
    });
    return `${current} (${timezone})`;
}
function trimToLimit(text, limit) {
    if (text.length <= limit)
        return text;
    return text.slice(0, Math.max(0, limit - 80)).trimEnd() + "\n...[truncated for realtime context budget]";
}
function getActivitySummary() {
    try {
        return trimToLimit(getAgentState().activityTracker.getSummary(), REALTIME_ACTIVITY_CHAR_LIMIT);
    }
    catch (err) {
        logger.warn(`[Realtime] Failed to read ActivityTracker: ${err instanceof Error ? err.message : String(err)}`);
        return "Agent live status is unavailable during startup.";
    }
}
function buildCompactMainAgentContext(config, owner, time) {
    let stateLine = "unknown";
    let openTodos = [];
    try {
        const state = getAgentState();
        stateLine = state.busy ? "running a wake cycle" : "idle";
        openTodos = state.activityTracker
            .getTodos()
            .filter((todo) => todo.status !== "completed")
            .slice(0, 8)
            .map((todo) => `- ${todo.status}: ${todo.content}`);
    }
    catch (err) {
        logger.warn(`[Realtime] Failed to build compact main-agent context: ${err instanceof Error ? err.message : String(err)}`);
    }
    const lines = [
        `Agent: ${config.agentName}`,
        `Owner: ${owner.ownerName}${owner.ownerEmail ? ` (${owner.ownerEmail})` : ""}`,
        `Current time: ${time}`,
        `Main agent state at realtime session start: ${stateLine}`,
        "This is a bounded summary generated when the realtime session started, not the full main-agent context.",
    ];
    if (openTodos.length > 0) {
        lines.push("Open todos from the current/last active wake cycle:", ...openTodos);
    }
    return trimToLimit(lines.join("\n"), REALTIME_CONTEXT_CHAR_LIMIT);
}
export function buildRealtimeContextFromAgent(config) {
    const owner = loadOwnerConfig();
    const time = formatCurrentTime(owner.timezone);
    const compactContext = buildCompactMainAgentContext(config, owner, time);
    const liveStatus = getActivitySummary();
    const ownerEmail = owner.ownerEmail ? ` (${owner.ownerEmail})` : "";
    return `You are the realtime voice interface for ${config.agentName}, the owner's long-running VisionClaw desktop agent. The owner (${owner.ownerName}${ownerEmail}) is speaking to you live through a Telegram Mini App.

## Authority and Trust
Every speaker in this voice session is the verified owner. Treat this as a short-lived voice front-end for the main agent, not as a standalone assistant.

## Current Time
${time}
Owner language: ${owner.language}

## Capabilities You Have Right Now
You may use only the realtime tools listed below:
${formatToolCapabilityList()}

## Capabilities You Do NOT Have
${REALTIME_LIMITS.map((limit) => `- ${limit}`).join("\n")}

## Handoff Rule
If the owner asks for anything outside the explicit realtime capabilities list, do not attempt it. Briefly acknowledge that the main agent will handle it. The request will be captured in this voice transcript, summarized as an open follow-up, and injected into the main agent's next wake context.

## Compact Main Agent Context
This bounded summary was generated when the realtime session started. It is not the full main-agent context; omitted details may still exist in the main agent.
${compactContext}

## Agent Live Status
This section is a compact live-status bridge from the main agent via ActivityTracker, using the same current-activity summary mechanism as the fast responder. It is the source of truth for what the main agent is currently doing right now, but it may simply say the agent is idle.
${liveStatus}

## Voice Behavior
Keep replies short and conversational. Ask one question at a time. When a tool is needed, give a very brief acknowledgement and call it. Confirm meaningful side effects before performing them. Never narrate raw tool payloads, IDs, URLs, or internal status unless the owner explicitly asks.`;
}
export function closeVoiceDb() {
    if (voiceDb) {
        try {
            voiceDb.close();
        }
        catch { /* ignore */ }
        voiceDb = null;
    }
}
//# sourceMappingURL=context.js.map