/**
 * Thread Router — automatic problem-solving orchestration for threads.
 *
 * Classifies the user's task, auto-selects relevant skills, and produces
 * a RoutingPlan that guides the agent's execution strategy.
 *
 * The router runs at thread start (before the first turn) and injects
 * its plan into the thread record + agent context.
 */
const INTENT_SIGNALS = [
    {
        intent: "debugging",
        patterns: [
            /\b(fix|bug|error|crash|broken|fail|exception|stack\s?trace|debug|diagnos|troubleshoot|not\s+working|issue|wrong|unexpected)\b/i,
        ],
        weight: 1.2,
    },
    {
        intent: "coding",
        patterns: [
            /\b(implement|create|build|add|write|refactor|extract|rename|move|delete|remove|update|change|modify|feature|component|function|class|module|endpoint|route|api|test|spec|migrate)\b/i,
        ],
        weight: 1.0,
    },
    {
        intent: "review",
        patterns: [
            /\b(review|audit|check|inspect|assess|evaluate|quality|lint|analyze|PR|pull\s+request|code\s+review|security\s+review)\b/i,
        ],
        weight: 1.1,
    },
    {
        intent: "research",
        patterns: [
            /\b(research|investigate|compare|explore|find\s+out|how\s+does|what\s+is|explain|understand|look\s+into|learn|documentation|docs)\b/i,
        ],
        weight: 1.0,
    },
    {
        intent: "planning",
        patterns: [
            /\b(plan|design|architect|breakdown|decompos|structure|organiz|strateg|roadmap|milestone|spec|rfc|proposal)\b/i,
        ],
        weight: 1.1,
    },
    {
        intent: "devops",
        patterns: [
            /\b(deploy|CI\/CD|pipeline|docker|container|kubernetes|k8s|terraform|infra|server|hosting|monitoring|release|publish)\b/i,
        ],
        weight: 1.1,
    },
    {
        intent: "data",
        patterns: [
            /\b(data|dataset|csv|json|sql|query|transform|ETL|analysis|analytics|chart|graph|visualization|parse|scrape)\b/i,
        ],
        weight: 1.0,
    },
];
function classifyIntent(message) {
    const scores = new Map();
    for (const signal of INTENT_SIGNALS) {
        for (const pattern of signal.patterns) {
            const matches = message.match(new RegExp(pattern, "gi"));
            if (matches) {
                const current = scores.get(signal.intent) ?? 0;
                scores.set(signal.intent, current + matches.length * signal.weight);
            }
        }
    }
    if (scores.size === 0) {
        return { intent: "general", confidence: 0.3 };
    }
    let bestIntent = "general";
    let bestScore = 0;
    let totalScore = 0;
    for (const [intent, score] of scores) {
        totalScore += score;
        if (score > bestScore) {
            bestScore = score;
            bestIntent = intent;
        }
    }
    const confidence = Math.min(bestScore / Math.max(totalScore, 1), 1);
    return { intent: bestIntent, confidence };
}
// ── Skill matching ───────────────────────────────────────────────────
/** Normalize a skill name/id to a slash-command token (kebab-case). */
function skillSlug(value) {
    return value
        .toLowerCase()
        .trim()
        .replace(/[\s_]+/g, "-")
        .replace(/[^a-z0-9-]/g, "");
}
/**
 * Extract explicit `/skill-id` invocations from a message.
 * The slash-command picker in the composer inserts these tokens, so a user
 * can deterministically request a skill by typing `/`. Tokens must appear at
 * the start of the message or after whitespace to avoid matching paths/URLs.
 */
export function matchExplicitSkillInvocations(message, skills) {
    if (skills.length === 0)
        return [];
    const tokens = new Set();
    const re = /(?:^|\s)\/([a-z0-9][a-z0-9-]*)/gi;
    let m;
    while ((m = re.exec(message)) !== null) {
        if (m[1])
            tokens.add(m[1].toLowerCase());
    }
    if (tokens.size === 0)
        return [];
    const matched = [];
    for (const skill of skills) {
        if (tokens.has(skill.id.toLowerCase()) || tokens.has(skillSlug(skill.id)) || tokens.has(skillSlug(skill.name))) {
            matched.push(skill.id);
        }
    }
    return matched;
}
export function matchSkills(message, skills) {
    if (skills.length === 0)
        return [];
    // Explicit `/skill-id` invocations always win and come first.
    const explicit = matchExplicitSkillInvocations(message, skills);
    const messageLower = message.toLowerCase();
    const matched = [];
    for (const skill of skills) {
        if (explicit.includes(skill.id))
            continue; // already forced in
        // Score based on keyword overlap between task and skill description
        const descWords = skill.description.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
        const nameWords = skill.name.toLowerCase().split(/[\s\-_]+/).filter((w) => w.length > 2);
        let score = 0;
        for (const word of descWords) {
            if (messageLower.includes(word))
                score += 1;
        }
        for (const word of nameWords) {
            if (messageLower.includes(word))
                score += 2; // Name matches are stronger
        }
        if (score > 0) {
            matched.push({ id: skill.id, score });
        }
    }
    // Return top matches, sorted by score — explicit invocations always lead.
    const keywordMatches = matched
        .sort((a, b) => b.score - a.score)
        .slice(0, 5)
        .map((m) => m.id);
    return [...explicit, ...keywordMatches];
}
// ── Topology detection ───────────────────────────────────────────────
function detectTopology(message, intent) {
    // For now, detect obvious multi-part tasks
    // Phase 2 will use LLM-based decomposition
    const lines = message.split("\n").filter((l) => l.trim());
    // Check for numbered lists or bullet points indicating subtasks
    const listItems = lines.filter((l) => /^\s*(?:\d+[.)]\s|-\s|\*\s|•\s)/.test(l));
    if (listItems.length >= 3 && (intent === "coding" || intent === "planning")) {
        return {
            topology: "delegated",
            subtasks: listItems.map((l) => l.replace(/^\s*(?:\d+[.)]\s|-\s|\*\s|•\s)/, "").trim()),
        };
    }
    // Multi-file or multi-component tasks
    if (intent === "coding" && /\b(and|also|plus|additionally)\b/i.test(message) && message.length > 300) {
        return { topology: "delegated" };
    }
    return { topology: "single" };
}
/**
 * Route a thread — classify intent, match skills, determine topology.
 * This is a synchronous, heuristic-based router (Phase 1).
 * Phase 2 will add an optional LLM classification pass for ambiguous cases.
 */
export function routeThread(options) {
    const { message, availableSkills, pinnedSkillIds, kind } = options;
    // Classify intent
    const { intent } = classifyIntent(message);
    // Match skills from description
    const autoSkillIds = matchSkills(message, availableSkills);
    // Merge with pinned skills (pinned take priority)
    const pinnedSet = new Set(pinnedSkillIds ?? []);
    const suggestedSkillIds = [
        ...pinnedSet,
        ...autoSkillIds.filter((id) => !pinnedSet.has(id)),
    ];
    // Determine topology
    const { topology, subtasks } = kind === "delegation"
        ? { topology: "single", subtasks: undefined }
        : detectTopology(message, intent);
    // Build reason
    const reason = buildReason(intent, topology, suggestedSkillIds, availableSkills);
    return {
        intent,
        reason,
        suggestedSkillIds,
        topology,
        subtasks,
        routedAt: new Date().toISOString(),
    };
}
function buildReason(intent, topology, skillIds, skills) {
    const intentLabel = {
        coding: "code implementation",
        debugging: "debugging/troubleshooting",
        research: "research/investigation",
        review: "code review/assessment",
        planning: "planning/architecture",
        devops: "DevOps/infrastructure",
        data: "data processing",
        general: "general task",
    };
    const parts = [`Classified as ${intentLabel[intent]}.`];
    if (skillIds.length > 0) {
        const names = skillIds
            .map((id) => skills.find((s) => s.id === id)?.name)
            .filter(Boolean)
            .slice(0, 3);
        if (names.length > 0) {
            parts.push(`Auto-activated skills: ${names.join(", ")}.`);
        }
    }
    if (topology === "delegated") {
        parts.push("Task has separable subtasks — helper threads recommended.");
    }
    return parts.join(" ");
}
// ── Prompt injection ─────────────────────────────────────────────────
/**
 * Format the routing plan as a prescriptive problem-solving methodology
 * injected into the agent's first turn message. This tells the agent
 * exactly how to approach the task using structured orchestration phases.
 *
 * For short, straightforward messages the orchestration is kept lightweight
 * to avoid wasting tokens on ceremony for trivial tasks.
 */
export function formatRoutingPlanForPrompt(plan, messageLength) {
    const isSimple = (messageLength ?? 0) < 200 && plan.topology !== "delegated";
    const lines = [
        "<orchestration>",
        `Classification: ${plan.intent} — ${plan.reason}`,
    ];
    if (isSimple) {
        // Lightweight orchestration — no rigid phases for quick tasks
        lines.push("", "This looks like a straightforward task. Proceed directly — read the relevant code, make the change, and verify it compiles.", "</orchestration>");
        return lines.join("\n");
    }
    lines.push("", "You MUST follow this problem-solving process:", "");
    // Phase-specific instructions based on intent
    const phases = getOrchestrationPhases(plan);
    for (let i = 0; i < phases.length; i++) {
        const phase = phases[i];
        lines.push(`Phase ${i + 1}: ${phase.name}`);
        for (const step of phase.steps) {
            lines.push(`  - ${step}`);
        }
        lines.push("");
    }
    if (plan.topology === "delegated" && plan.subtasks?.length) {
        lines.push("Identified subtasks for parallel execution:");
        for (const subtask of plan.subtasks) {
            lines.push(`  - ${subtask}`);
        }
        lines.push("", "Use thread.control create_many to spawn helper threads for independent subtasks.", "Each helper should be kind: delegation so it auto-completes after one turn.", "");
    }
    lines.push("IMPORTANT: Do NOT skip phases. Show your reasoning at each phase before proceeding.", "</orchestration>");
    return lines.join("\n");
}
function getOrchestrationPhases(plan) {
    const common = [
        {
            name: "ANALYZE",
            steps: [
                "Read and understand the full request before touching any code",
                "Identify the core problem vs. symptoms",
                "List what you know vs. what you need to discover",
            ],
        },
    ];
    const intentPhases = {
        debugging: [
            {
                name: "REPRODUCE",
                steps: [
                    "Locate the error source — read stack traces, logs, failing tests",
                    "Trace the execution path to find the root cause",
                    "Confirm you understand WHY it fails, not just WHERE",
                ],
            },
            {
                name: "FIX",
                steps: [
                    "Implement the minimal correct fix",
                    "Check for related occurrences of the same bug pattern",
                ],
            },
            {
                name: "VERIFY",
                steps: [
                    "Run the failing test/scenario to confirm the fix works",
                    "Check for regressions — run related tests",
                ],
            },
        ],
        coding: [
            {
                name: "PLAN",
                steps: [
                    "Identify which files need changes and what the changes are",
                    "Consider edge cases and error handling needed",
                    "If the task is large, break it into sequential steps",
                ],
            },
            {
                name: "IMPLEMENT",
                steps: [
                    "Make changes file by file, verifying each step compiles",
                    "Follow existing code patterns and conventions in the codebase",
                ],
            },
            {
                name: "VERIFY",
                steps: [
                    "Run type checking / compilation to catch errors",
                    "Run relevant tests if they exist",
                    "Review your changes for correctness",
                ],
            },
        ],
        review: [
            {
                name: "SURVEY",
                steps: [
                    "Read all changed files / the code under review",
                    "Understand the intent and context of the changes",
                ],
            },
            {
                name: "ASSESS",
                steps: [
                    "Check for correctness, edge cases, and potential bugs",
                    "Evaluate code quality, naming, and adherence to conventions",
                    "Look for security issues and performance concerns",
                ],
            },
            {
                name: "REPORT",
                steps: [
                    "Summarize findings with specific file/line references",
                    "Categorize issues by severity (critical, warning, suggestion)",
                ],
            },
        ],
        research: [
            {
                name: "INVESTIGATE",
                steps: [
                    "Search the codebase for relevant implementations and patterns",
                    "Read documentation and comments for context",
                    "Map out the relevant architecture and data flow",
                ],
            },
            {
                name: "SYNTHESIZE",
                steps: [
                    "Compile findings into a clear summary",
                    "Provide concrete recommendations with code references",
                ],
            },
        ],
        planning: [
            {
                name: "SCOPE",
                steps: [
                    "Define clear boundaries — what is and isn't included",
                    "Identify dependencies and ordering constraints",
                ],
            },
            {
                name: "DECOMPOSE",
                steps: [
                    "Break the work into concrete, actionable tasks",
                    "Estimate relative complexity of each task",
                    "Identify which tasks can be parallelized",
                ],
            },
            {
                name: "DOCUMENT",
                steps: [
                    "Write the plan with task ordering and dependencies",
                    "Include acceptance criteria for each task",
                ],
            },
        ],
        devops: [
            {
                name: "ASSESS",
                steps: [
                    "Review current infrastructure/pipeline configuration",
                    "Identify what needs to change and potential risks",
                ],
            },
            {
                name: "IMPLEMENT",
                steps: [
                    "Make configuration changes incrementally",
                    "Validate each change before proceeding",
                ],
            },
            {
                name: "VERIFY",
                steps: [
                    "Test the pipeline/deployment in a safe way",
                    "Confirm rollback path exists if something goes wrong",
                ],
            },
        ],
        data: [
            {
                name: "EXPLORE",
                steps: [
                    "Understand the data schema, format, and volume",
                    "Identify transformations needed",
                ],
            },
            {
                name: "TRANSFORM",
                steps: [
                    "Implement data processing step by step",
                    "Validate intermediate results",
                ],
            },
            {
                name: "VALIDATE",
                steps: [
                    "Check output correctness with sample data",
                    "Handle edge cases (nulls, malformed entries, encoding)",
                ],
            },
        ],
    };
    const specific = intentPhases[plan.intent] ?? [
        {
            name: "EXECUTE",
            steps: [
                "Work through the task methodically",
                "Verify your work at each step",
            ],
        },
        {
            name: "VERIFY",
            steps: [
                "Confirm the result is correct and complete",
            ],
        },
    ];
    return [...common, ...specific];
}
//# sourceMappingURL=thread-router.js.map