"use strict";
/**
 * test_squad_skill_design_llm.ts — Stories 8.1 + 8.2
 *
 * Asserts that:
 *   1. Brain.isAnyProviderAvailable() returns false when no env keys.
 *   2. SquadCreator.designWithBrain() falls back to heuristic when
 *      Brain reports no provider.
 *   3. With a mocked Brain that returns valid JSON, designWithBrain()
 *      returns source='brain'.
 *   4. With a mocked Brain that throws / returns junk, designWithBrain()
 *      gracefully falls back to source='heuristic'.
 *   5. Same four scenarios for SkillCreator.designWithBrain().
 */
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 os = __importStar(require("os"));
const path = __importStar(require("path"));
const Brain_1 = require("./orchestrator/Brain");
const SquadCreator_1 = require("./orchestrator/SquadCreator");
const SkillCreator_1 = require("./orchestrator/SkillCreator");
function assertTrue(cond, label) {
    if (!cond)
        throw new Error(`ASSERT_FAILED[${label}]`);
}
async function main() {
    // ── Scenario 1: real Brain reports no providers when env is clean ──
    const origKeys = {
        OPENAI_API_KEY: process.env.OPENAI_API_KEY,
        ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
        GEMINI_API_KEY: process.env.GEMINI_API_KEY,
        OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY,
        OLLAMA_URL: process.env.OLLAMA_URL,
    };
    delete process.env.OPENAI_API_KEY;
    delete process.env.ANTHROPIC_API_KEY;
    delete process.env.GEMINI_API_KEY;
    delete process.env.OPENROUTER_API_KEY;
    delete process.env.OLLAMA_URL;
    const cleanBrain = new Brain_1.Brain();
    assertTrue(!cleanBrain.isAnyProviderAvailable(), 'Brain reports unavailable with no env');
    console.log('[8.1] Brain.isAnyProviderAvailable returns false when clean ✓');
    // ── Scenario 2: SquadCreator.designWithBrain with unavailable Brain → heuristic ──
    const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'design-llm-'));
    try {
        const sc = new SquadCreator_1.SquadCreator({ catalogRoot: path.join(tmp, '.catalog', 'squads') });
        const noBrain = {
            isAnyProviderAvailable: () => false,
            think: async () => { throw new Error('should not be called'); },
        };
        const r1 = await sc.designWithBrain(noBrain, 'research mid-cap medical devices', { mode: 'professional' });
        assertTrue(r1.ok, 'designWithBrain ok when no provider');
        if (r1.ok) {
            assertTrue(r1.source === 'heuristic', `source=heuristic (got ${r1.source})`);
            assertTrue(r1.proposal.agents.length >= 3, 'heuristic professional has >=3 agents');
        }
        console.log('[8.1] SquadCreator.designWithBrain unavailable → heuristic ✓');
        // ── Scenario 3: Mocked Brain returns valid JSON → source=brain ──
        const validBrain = {
            isAnyProviderAvailable: () => true,
            think: async () => `\`\`\`json
{
  "agents": [
    { "id": "research-lead", "role": "lead" },
    { "id": "research-executor", "role": "executor" },
    { "id": "research-reviewer", "role": "reviewer" }
  ],
  "tasks": [
    { "id": "research-default", "ownerAgentId": "research-lead", "purpose": "do the research" }
  ],
  "checklists": []
}
\`\`\``,
        };
        const r2 = await sc.designWithBrain(validBrain, 'research medical devices', { mode: 'professional', id: 'mock-brain-squad' });
        assertTrue(r2.ok, 'designWithBrain ok with valid mocked Brain');
        if (r2.ok) {
            assertTrue(r2.source === 'brain', `source=brain (got ${r2.source})`);
            assertTrue(r2.proposal.agents.length === 3, '3 agents from mocked response');
            assertTrue(r2.proposal.agents[0].id === 'research-lead', 'first agent id preserved');
        }
        console.log('[8.1] SquadCreator.designWithBrain valid JSON → source=brain ✓');
        // ── Scenario 4: Mocked Brain returns junk → falls back to heuristic ──
        const junkBrain = {
            isAnyProviderAvailable: () => true,
            think: async () => 'definitely not JSON, just prose',
        };
        const r3 = await sc.designWithBrain(junkBrain, 'something weird', { mode: 'quick', id: 'junk-test-squad' });
        assertTrue(r3.ok, 'designWithBrain ok despite junk');
        if (r3.ok) {
            assertTrue(r3.source === 'heuristic', `source=heuristic on junk (got ${r3.source})`);
        }
        console.log('[8.1] SquadCreator.designWithBrain junk → heuristic fallback ✓');
        // ── Scenario 5: Mocked Brain throws → falls back ──
        const throwBrain = {
            isAnyProviderAvailable: () => true,
            think: async () => { throw new Error('network'); },
        };
        const r4 = await sc.designWithBrain(throwBrain, 'will throw', { mode: 'quick', id: 'throw-test-squad' });
        assertTrue(r4.ok, 'designWithBrain ok despite throw');
        if (r4.ok)
            assertTrue(r4.source === 'heuristic', `source=heuristic on throw (got ${r4.source})`);
        console.log('[8.1] SquadCreator.designWithBrain throw → heuristic fallback ✓');
        // ── Scenarios 6–9: same for SkillCreator ──
        const skc = new SkillCreator_1.SkillCreator({ catalogRoot: path.join(tmp, '.catalog', 'skills') });
        const r5 = await skc.designWithBrain(noBrain, 'extract images from PDFs', { mode: 'professional' });
        assertTrue(r5.ok && r5.source === 'heuristic', '[8.2] SkillCreator unavailable → heuristic');
        console.log('[8.2] SkillCreator.designWithBrain unavailable → heuristic ✓');
        const validSkillBrain = {
            isAnyProviderAvailable: () => true,
            think: async () => `{
        "description": "extract structured data from PDFs",
        "whenToUse": ["pdf parsing needed", "structured extraction"],
        "procedure": ["open pdf", "OCR pages", "parse layout", "emit JSON"],
        "validation": ["json schema valid"],
        "guardrails": ["never store raw pdf content"]
      }`,
        };
        const r6 = await skc.designWithBrain(validSkillBrain, 'pdf-extract', { mode: 'professional', id: 'pdf-extract' });
        assertTrue(r6.ok && r6.source === 'brain', '[8.2] SkillCreator valid → brain');
        if (r6.ok) {
            assertTrue(r6.proposal.procedure.length === 4, '4 procedure steps');
            assertTrue(r6.proposal.guardrails?.[0] === 'never store raw pdf content', 'guardrail preserved');
        }
        console.log('[8.2] SkillCreator.designWithBrain valid → source=brain ✓');
        const r7 = await skc.designWithBrain(junkBrain, 'junk skill', { mode: 'quick', id: 'junk-skill' });
        assertTrue(r7.ok && r7.source === 'heuristic', '[8.2] SkillCreator junk → heuristic');
        console.log('[8.2] SkillCreator.designWithBrain junk → heuristic ✓');
    }
    finally {
        fs.rmSync(tmp, { recursive: true, force: true });
        // restore env
        for (const [k, v] of Object.entries(origKeys)) {
            if (v !== undefined)
                process.env[k] = v;
        }
    }
    console.log('TEST_SQUAD_SKILL_DESIGN_LLM_OK');
}
main().catch((err) => {
    console.error('[design-llm] FAILED:', err instanceof Error ? err.message : err);
    process.exit(1);
});
