/**
 * Message Tools for Agent
 *
 * Allow the agent to search and retrieve folder message history.
 * Enables the agent to answer questions about past conversations
 * and use chat context for entity creation.
 */
import { Type as T } from 'typebox';
import { wrapToolResult } from './graph-tools.js';
import { formatTranscript } from '../../services/message-service.js';
import * as access from '../../services/access-control.js';
/** Get folders the current user can access. Null = no filtering (API key / open mode).
 *  Uses access-control so personal-folder restrictions match the HTTP layer. */
function getAccessibleFolders(user, workspaceManager, authService) {
    if (!user)
        return null; // API key / open mode → all
    return access.getAccessibleRepos(user, workspaceManager, authService).map(r => r.name);
}
export function createMessageTools(messageService, getCurrentUser, workspaceManager, authService) {
    return [
        {
            name: 'search_messages',
            label: 'Search Messages',
            description: 'Search folder message history by keyword. Returns matching messages with sender, timestamp, and folder. Use this to find past conversations, decisions, and context discussed in team threads.',
            parameters: T.Object({
                query: T.String({ description: 'Search term to find in message content' }),
                folder: T.Optional(T.String({ description: 'Scope search to a specific folder (optional)' })),
                limit: T.Optional(T.Number({ description: 'Max results (default 20, max 50)' })),
            }),
            execute: async (_toolCallId, params) => {
                const { query, folder, limit } = params;
                const user = getCurrentUser();
                const accessible = getAccessibleFolders(user, workspaceManager, authService);
                const results = messageService.searchMessages(query, {
                    folder,
                    folders: accessible ?? undefined,
                    limit: Math.min(limit ?? 20, 50),
                });
                // Filter by accessible folders if user has restricted access.
                // Workspace-scoped messages (folder = null) are excluded here because
                // restricted search is opt-in to specific folders. A dedicated
                // workspace-search tool can be added later if needed.
                const filtered = accessible
                    ? results.filter(m => m.folder !== null && accessible.includes(m.folder))
                    : results;
                return wrapToolResult({
                    count: filtered.length,
                    transcript: formatTranscript(filtered, true),
                });
            },
        },
        {
            name: 'get_conversation_context',
            label: 'Get Conversation',
            description: 'Get the full recent conversation in a folder, or messages around a specific message. Use this to understand the context of a discussion before responding or creating entities.',
            parameters: T.Object({
                folder: T.String({ description: 'Folder name' }),
                messageId: T.Optional(T.Number({ description: 'Center context around this message ID (optional — defaults to most recent)' })),
                limit: T.Optional(T.Number({ description: 'Number of messages to retrieve (default 20, max 50)' })),
            }),
            execute: async (_toolCallId, params) => {
                const { folder, messageId, limit: rawLimit } = params;
                const user = getCurrentUser();
                const accessible = getAccessibleFolders(user, workspaceManager, authService);
                // Access check
                if (accessible && !accessible.includes(folder)) {
                    return wrapToolResult({ error: `Access denied to folder "${folder}"` });
                }
                const limit = Math.min(rawLimit ?? 20, 50);
                let messages;
                if (messageId) {
                    // Get messages around the target: half before, half after
                    const half = Math.ceil(limit / 2);
                    const before = messageService.getMessages(folder, { before: messageId + 1, limit: half });
                    const after = messageService.getMessages(folder, { before: messageId + half + 1, limit: half })
                        .filter(m => m.id > messageId);
                    const target = messageService.getMessageById(messageId);
                    const all = new Map();
                    for (const m of [...before, ...after])
                        all.set(m.id, m);
                    if (target)
                        all.set(target.id, target);
                    messages = [...all.values()].sort((a, b) => a.id - b.id);
                }
                else {
                    // Most recent messages
                    messages = messageService.getMessages(folder, { limit });
                }
                return wrapToolResult({
                    folder,
                    count: messages.length,
                    transcript: formatTranscript(messages),
                });
            },
        },
    ];
}
//# sourceMappingURL=message-tools.js.map