/**
 * System Prompt Builder
 *
 * OpenClaw-inspired dynamic system prompt assembly.
 *
 * Dynamically merges:
 * - Base system instructions
 * - Available tools description
 * - Active skills
 * - Relevant memories
 * - Session context
 * - Operating mode constraints
 * - User preferences
 *
 * The builder produces context-aware system prompts that adapt to
 * the current session state, available capabilities, and user needs.
 *
 * Usage:
 * ```typescript
 * const builder = new SystemPromptBuilder();
 *
 * const prompt = builder
 *   .withBaseInstructions('You are Code Buddy...')
 *   .withTools(availableTools)
 *   .withSkills(activeSkills)
 *   .withMemory(relevantMemories)
 *   .withMode('code')
 *   .withSkillContext(matchedSkill)
 *   .build();
 * ```
 */
// ============================================================================
// Default Configuration
// ============================================================================
const DEFAULT_BUILD_CONFIG = {
    maxTokens: 4096,
    includeTools: true,
    includeSkills: true,
    includeMemory: true,
    includeDatetime: true,
    includePlatform: true,
    compact: false,
};
// ============================================================================
// System Prompt Builder
// ============================================================================
export class SystemPromptBuilder {
    sections = new Map();
    tools = [];
    skills = [];
    memories = [];
    mode = 'code';
    buildConfig;
    customInstructions = [];
    activeSkillContext = null;
    constructor(config = {}) {
        this.buildConfig = { ...DEFAULT_BUILD_CONFIG, ...config };
    }
    // ==========================================================================
    // Fluent API
    // ==========================================================================
    /**
     * Set base instructions
     */
    withBaseInstructions(instructions) {
        this.addSection({
            id: 'base',
            title: 'Instructions',
            content: instructions,
            priority: 100,
            required: true,
        });
        return this;
    }
    /**
     * Set available tools
     */
    withTools(tools) {
        this.tools = tools;
        return this;
    }
    /**
     * Set active skills
     */
    withSkills(skills) {
        this.skills = skills;
        return this;
    }
    /**
     * Set relevant memories
     */
    withMemory(memories) {
        this.memories = memories;
        return this;
    }
    /**
     * Set operating mode
     */
    withMode(mode) {
        this.mode = mode;
        return this;
    }
    /**
     * Add custom instructions
     */
    withCustomInstructions(instructions) {
        this.customInstructions.push(instructions);
        return this;
    }
    /**
     * Add a custom section
     */
    withSection(section) {
        this.addSection({ required: false, ...section });
        return this;
    }
    /**
     * Inject context from a matched UnifiedSkill.
     *
     * When a skill is matched for the current query, this method adds the
     * skill's system prompt / description as a high-priority section so the
     * LLM receives skill-specific instructions.
     *
     * @param skill - The matched UnifiedSkill (or null to clear)
     */
    withSkillContext(skill) {
        this.activeSkillContext = skill;
        return this;
    }
    /**
     * Set project context (from CLAUDE.md or similar)
     */
    withProjectContext(context) {
        if (context.trim()) {
            this.addSection({
                id: 'project-context',
                title: 'Project Context',
                content: context,
                priority: 90,
                required: false,
            });
        }
        return this;
    }
    /**
     * Set user preferences
     */
    withUserPreferences(preferences) {
        const lines = Object.entries(preferences)
            .map(([key, value]) => `- ${key}: ${value}`)
            .join('\n');
        if (lines) {
            this.addSection({
                id: 'user-preferences',
                title: 'User Preferences',
                content: lines,
                priority: 60,
                required: false,
            });
        }
        return this;
    }
    // ==========================================================================
    // Build
    // ==========================================================================
    /**
     * Build the complete system prompt
     */
    build() {
        const parts = [];
        // Add dynamic sections
        this.buildDynamicSections();
        // Sort sections by priority (descending)
        const sortedSections = Array.from(this.sections.values())
            .filter(s => !s.condition || s.condition())
            .sort((a, b) => b.priority - a.priority);
        // Build prompt within token budget
        let estimatedTokens = 0;
        for (const section of sortedSections) {
            const sectionTokens = this.estimateTokens(section.content);
            if (!section.required && estimatedTokens + sectionTokens > this.buildConfig.maxTokens) {
                continue; // Skip non-required sections if over budget
            }
            if (section.maxTokens && sectionTokens > section.maxTokens) {
                // Truncate section content
                const truncated = this.truncateToTokens(section.content, section.maxTokens);
                parts.push(this.formatSection(section.title, truncated));
                estimatedTokens += section.maxTokens;
            }
            else {
                parts.push(this.formatSection(section.title, section.content));
                estimatedTokens += sectionTokens;
            }
        }
        return parts.join('\n\n');
    }
    /**
     * Build and return sections (for inspection)
     */
    buildSections() {
        this.buildDynamicSections();
        return Array.from(this.sections.values())
            .filter(s => !s.condition || s.condition())
            .sort((a, b) => b.priority - a.priority);
    }
    // ==========================================================================
    // Dynamic Section Building
    // ==========================================================================
    /**
     * Build all dynamic sections based on current state
     */
    buildDynamicSections() {
        // Tools section
        if (this.buildConfig.includeTools && this.tools.length > 0) {
            this.addSection({
                id: 'tools',
                title: 'Available Tools',
                content: this.buildToolsSection(),
                priority: 80,
                required: false,
                maxTokens: 1000,
            });
        }
        // Skills section
        if (this.buildConfig.includeSkills && this.skills.length > 0) {
            this.addSection({
                id: 'skills',
                title: 'Available Skills',
                content: this.buildSkillsSection(),
                priority: 70,
                required: false,
                maxTokens: 500,
            });
        }
        // Memory section
        if (this.buildConfig.includeMemory && this.memories.length > 0) {
            this.addSection({
                id: 'memory',
                title: 'Relevant Context',
                content: this.buildMemorySection(),
                priority: 75,
                required: false,
                maxTokens: 800,
            });
        }
        // Mode constraints
        this.addSection({
            id: 'mode',
            title: 'Operating Mode',
            content: this.buildModeSection(),
            priority: 85,
            required: true,
        });
        // Datetime context
        if (this.buildConfig.includeDatetime) {
            this.addSection({
                id: 'datetime',
                title: 'Current Context',
                content: `Current date: ${new Date().toISOString().split('T')[0]}`,
                priority: 40,
                required: false,
            });
        }
        // Platform context
        if (this.buildConfig.includePlatform) {
            this.addSection({
                id: 'platform',
                title: 'Environment',
                content: `Platform: ${process.platform}, Node: ${process.version}`,
                priority: 30,
                required: false,
            });
        }
        // Active skill context
        if (this.activeSkillContext) {
            const skill = this.activeSkillContext;
            const skillContent = this.buildActiveSkillSection(skill);
            if (skillContent) {
                this.addSection({
                    id: 'active-skill',
                    title: `Active Skill: ${skill.name}`,
                    content: skillContent,
                    priority: 95, // Very high - just below base instructions
                    required: true,
                    maxTokens: 1500,
                });
            }
        }
        // Custom instructions
        if (this.customInstructions.length > 0) {
            this.addSection({
                id: 'custom',
                title: 'Additional Instructions',
                content: this.customInstructions.join('\n\n'),
                priority: 50,
                required: false,
            });
        }
    }
    /**
     * Build tools description section
     */
    buildToolsSection() {
        if (this.buildConfig.compact) {
            return this.tools.map(t => `- ${t.name}: ${t.description}`).join('\n');
        }
        // Group by category
        const groups = {};
        for (const tool of this.tools) {
            const cat = tool.category || 'other';
            if (!groups[cat])
                groups[cat] = [];
            groups[cat].push(tool);
        }
        const lines = [];
        for (const [category, tools] of Object.entries(groups)) {
            lines.push(`### ${category}`);
            for (const tool of tools) {
                lines.push(`- **${tool.name}**: ${tool.description}`);
            }
        }
        return lines.join('\n');
    }
    /**
     * Build skills description section
     */
    buildSkillsSection() {
        return this.skills.map(s => {
            const triggers = s.triggers.slice(0, 3).join(', ');
            return `- **${s.name}**: ${s.description} (triggers: ${triggers})`;
        }).join('\n');
    }
    /**
     * Build memory context section
     */
    buildMemorySection() {
        // Sort by relevance
        const sorted = [...this.memories]
            .sort((a, b) => (b.relevance ?? 0) - (a.relevance ?? 0));
        return sorted.map(m => `- [${m.category}] ${m.key}: ${m.value}`).join('\n');
    }
    /**
     * Build active skill section from UnifiedSkill context
     */
    buildActiveSkillSection(skill) {
        const lines = [];
        // Skill description
        lines.push(skill.description);
        // System prompt (the main skill instructions)
        if (skill.systemPrompt) {
            lines.push('');
            lines.push(skill.systemPrompt);
        }
        // Steps
        if (skill.steps && skill.steps.length > 0) {
            lines.push('');
            lines.push('### Steps');
            for (const step of skill.steps) {
                const toolHint = step.tool ? ` (use: ${step.tool})` : '';
                lines.push(`${step.index}. ${step.description}${toolHint}`);
            }
        }
        // Required tools
        const requiredTools = [
            ...(skill.requires?.tools ?? []),
            ...(skill.tools ?? []),
        ];
        if (requiredTools.length > 0) {
            const unique = [...new Set(requiredTools)];
            lines.push('');
            lines.push(`**Required tools**: ${unique.join(', ')}`);
        }
        return lines.join('\n');
    }
    /**
     * Build operating mode constraints
     */
    buildModeSection() {
        switch (this.mode) {
            case 'plan':
                return 'You are in PLAN mode. Focus on analyzing, planning, and breaking down tasks. Do not execute code or make changes. Provide detailed plans with clear steps.';
            case 'code':
                return 'You are in CODE mode. Execute tasks by writing and modifying code. Use available tools to accomplish goals efficiently.';
            case 'ask':
                return 'You are in ASK mode. Answer questions and provide information. Do not make changes to code or files unless explicitly asked.';
            case 'architect':
                return 'You are in ARCHITECT mode. Focus on system design, architecture decisions, and high-level patterns. Provide diagrams and design documents rather than implementation.';
            default:
                return 'You are in standard mode. Help the user with their request using available tools and knowledge.';
        }
    }
    // ==========================================================================
    // Helpers
    // ==========================================================================
    /**
     * Add or replace a section
     */
    addSection(section) {
        this.sections.set(section.id, section);
    }
    /**
     * Format a section with title
     */
    formatSection(title, content) {
        return `## ${title}\n\n${content}`;
    }
    /**
     * Estimate token count (rough: ~4 chars per token)
     */
    estimateTokens(text) {
        return Math.ceil(text.length / 4);
    }
    /**
     * Truncate text to fit within token budget
     */
    truncateToTokens(text, maxTokens) {
        const maxChars = maxTokens * 4;
        if (text.length <= maxChars)
            return text;
        return text.slice(0, maxChars - 3) + '...';
    }
    // ==========================================================================
    // Reset
    // ==========================================================================
    /**
     * Reset builder state
     */
    reset() {
        this.sections.clear();
        this.tools = [];
        this.skills = [];
        this.memories = [];
        this.mode = 'code';
        this.customInstructions = [];
        this.activeSkillContext = null;
        return this;
    }
}
export default SystemPromptBuilder;
//# sourceMappingURL=system-prompt-builder.js.map