"use strict";
// =============================================================================
// Pure Agent - Access File Tool
// Reads local files as multimodal content (images, audio, video)
// Ported from server.js access_file implementation
// =============================================================================
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const tool_registry_1 = require("../tool-registry");
const result_types_1 = require("../result-types");
const utils_1 = require("../utils");
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp', '.svg']);
const AUDIO_EXTENSIONS = new Set(['.mp3', '.wav', '.m4a', '.ogg', '.flac', '.aac']);
const VIDEO_EXTENSIONS = new Set(['.mp4', '.webm', '.mov', '.avi', '.mkv']);
const IMAGE_MIME = {
    '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',
    '.gif': 'image/gif', '.bmp': 'image/bmp', '.webp': 'image/webp', '.svg': 'image/svg+xml',
};
const AUDIO_MIME = {
    '.mp3': 'audio/mpeg', '.wav': 'audio/wav', '.m4a': 'audio/mp4',
    '.ogg': 'audio/ogg', '.flac': 'audio/flac', '.aac': 'audio/aac',
};
const VIDEO_MIME = {
    '.mp4': 'video/mp4', '.webm': 'video/webm', '.mov': 'video/quicktime',
    '.avi': 'video/x-msvideo', '.mkv': 'video/x-matroska',
};
const MAX_IMAGE_BYTES = 20 * 1024 * 1024;
const MAX_AUDIO_BYTES = 25 * 1024 * 1024;
const MAX_VIDEO_BYTES = 50 * 1024 * 1024;
// ---------------------------------------------------------------------------
// Handler
// ---------------------------------------------------------------------------
async function accessFileHandler(args, context) {
    const { path: filepath, question } = args;
    if (!filepath)
        return (0, result_types_1.toolError)('Missing required parameter: path');
    const resolved = (0, utils_1.resolvePath)(filepath, context.workingDir);
    if (!fs.existsSync(resolved)) {
        return (0, result_types_1.toolError)(`File not found: ${resolved}`);
    }
    const stat = fs.statSync(resolved);
    if (stat.isDirectory()) {
        return (0, result_types_1.toolError)(`Cannot load directory as multimodal content: ${resolved}`);
    }
    const ext = path.extname(resolved).toLowerCase();
    const baseName = path.basename(resolved);
    // Image
    if (IMAGE_EXTENSIONS.has(ext)) {
        if (stat.size > MAX_IMAGE_BYTES) {
            return (0, result_types_1.toolError)(`Image too large: ${stat.size} bytes (max ${MAX_IMAGE_BYTES})`);
        }
        const data = fs.readFileSync(resolved);
        const mime = IMAGE_MIME[ext] || 'image/jpeg';
        const dataUrl = `data:${mime};base64,${data.toString('base64')}`;
        return JSON.stringify({
            _multimodal: true,
            content: [
                { type: 'text', text: question || `Image loaded: ${baseName}` },
                { type: 'image_url', image_url: { url: dataUrl } },
            ],
            text_summary: `Image loaded: ${baseName} (${Math.round(stat.size / 1024)} KB)`,
        });
    }
    // Audio
    if (AUDIO_EXTENSIONS.has(ext)) {
        if (stat.size > MAX_AUDIO_BYTES) {
            return (0, result_types_1.toolError)(`Audio too large: ${stat.size} bytes (max ${MAX_AUDIO_BYTES})`);
        }
        const data = fs.readFileSync(resolved);
        const mime = AUDIO_MIME[ext] || 'audio/mpeg';
        const format = ext.replace('.', '');
        return JSON.stringify({
            _multimodal: true,
            content: [
                { type: 'text', text: question || `Audio loaded: ${baseName}` },
                { type: 'input_audio', input_audio: { data: data.toString('base64'), format } },
            ],
            text_summary: `Audio loaded: ${baseName} (${Math.round(stat.size / 1024)} KB)`,
        });
    }
    // Video
    if (VIDEO_EXTENSIONS.has(ext)) {
        if (stat.size > MAX_VIDEO_BYTES) {
            return (0, result_types_1.toolError)(`Video too large: ${stat.size} bytes (max ${MAX_VIDEO_BYTES})`);
        }
        const data = fs.readFileSync(resolved);
        const mime = VIDEO_MIME[ext] || 'video/mp4';
        const dataUrl = `data:${mime};base64,${data.toString('base64')}`;
        return JSON.stringify({
            _multimodal: true,
            content: [
                { type: 'text', text: question || `Video loaded: ${baseName}` },
                { type: 'video_url', video_url: { url: dataUrl } },
            ],
            text_summary: `Video loaded: ${baseName} (${Math.round(stat.size / 1024)} KB)`,
        });
    }
    // Text/code files - return as text
    if (stat.size > 500000) {
        return (0, result_types_1.toolError)(`File too large for text reading: ${stat.size} bytes. Use read_file with offset/limit.`);
    }
    try {
        const content = fs.readFileSync(resolved, 'utf-8');
        return (0, result_types_1.toolResult)({
            content,
            path: resolved,
            size: stat.size,
            type: 'text',
        });
    }
    catch (err) {
        return (0, result_types_1.toolError)(`Failed to read file: ${err.message}`);
    }
}
// ---------------------------------------------------------------------------
// Registration
// ---------------------------------------------------------------------------
tool_registry_1.registry.register({
    name: 'access_file',
    toolset: 'file',
    schema: {
        description: `Read a local file as multimodal content. Images are loaded so the model can see them directly. Audio files are loaded for transcription. Video files are loaded for visual analysis. Text files are returned as text. Use this when the user mentions or asks about any image, audio, or video file - you MUST load it with access_file rather than saying you can't see/hear it.`,
        parameters: {
            type: 'object',
            properties: {
                path: {
                    type: 'string',
                    description: 'Path to the file (absolute or relative to working directory)',
                },
                question: {
                    type: 'string',
                    description: 'Optional question or instruction about the file content',
                },
            },
            required: ['path'],
        },
    },
    handler: accessFileHandler,
    isAsync: true,
    description: 'Load file as multimodal content',
    emoji: '📂',
    maxResultSizeChars: 50_000_000, // Large for base64 media
});
//# sourceMappingURL=access-file.js.map