/**
 * AgentFactory — universal wiring of OODA agents from AgentFactoryConfig.
 *
 * Promoted from forge/src/agents/shared/agent-factory.ts (Vague 1.B.2).
 * Forge-specific business logic (Slack/Telegram HITL channels, buildRevenueSkills,
 * etc.) is NOT promoted — only the generic wiring pattern.
 *
 * Neutralized Forge couplings:
 * - HITL channels injected via deps.messaging (not hardcoded Telegram bot tokens)
 * - "FORGE.md" hardcoded string → parameterizable via loadAgentContext options
 * - Forge-specific metrics not promoted — consumers add via optional peer dep
 *
 * @public @since 0.17.0
 */
import { createOODAAgent } from "../orchestration/ooda/factory.js";
import { alwaysOn } from "../orchestration/ooda/guards/always-on.js";
import { waitForHITLApproval } from "../orchestration/ooda/hitl-gate.js";
// ─── createAgentFromConfig ────────────────────────────────────────────────────
/**
 * Create an OODAAgent from a generic config + dependency bundle.
 *
 * Handles:
 * - Strict deps validation (SDK_STRICT_DEPS gate via createOODAAgent)
 * - Auto-registration in AgentRegistryPort when deps.registry is set
 * - HITL wiring via MessagingChannelPort (not Forge-specific Slack/Telegram)
 * - Resource limits with production-safe defaults
 *
 * @example
 * ```ts
 * const agent = await createAgentFromConfig(deps, {
 *   agentId: "my-agent",
 *   agentVersion: "1.0.0",
 *   intervalMs: 60_000,
 *   phases: { observe, orient, decide, act, feedback },
 * });
 * await agent.start();
 * ```
 *
 * @public
 */
export async function createAgentFromConfig(deps, config) {
    const { agentId, agentVersion, intervalMs, phases, sessionGuards, riskGuards, outcomeMapping, hitlEscalationLevel = "L2", registryDescriptor, } = config;
    // 1. Auto-register in AgentRegistryPort if descriptor + registry provided
    if (registryDescriptor && deps.registry) {
        await deps.registry
            .register({
            id: `${registryDescriptor.product}:${agentId}`,
            ...registryDescriptor,
        })
            .catch((err) => {
            // Non-fatal: registration failure should not block agent boot
            deps.logger.warn({ err }, `[${agentId}] AgentRegistry.register failed — agent may not appear in discovery`);
        });
    }
    // 2. Build OODA deps bundle from AgentFactoryDeps
    const oodaDeps = {
        eventBus: deps.eventBus,
        memory: deps.brain,
        messaging: deps.messaging,
    };
    // 3. Build HITL waiter if messaging channel available and in live mode
    let waitForHITL;
    if (deps.messaging && deps.executionMode === "live") {
        const messaging = deps.messaging;
        const onTimeout = hitlEscalationLevel === "L3" ? "reject" : "approve";
        const timeoutMs = hitlEscalationLevel === "L3" ? 10 * 60_000 : 5 * 60_000;
        waitForHITL = async (ctx) => {
            const decisionPayload = ctx.payload ?? {};
            // Skip HITL when act phase produced no actionable output
            const hasActions = (Array.isArray(decisionPayload["actions"]) &&
                decisionPayload["actions"].length > 0) ||
                (typeof decisionPayload["action"] === "string" &&
                    decisionPayload["action"].length > 0) ||
                decisionPayload["estimatedCostCents"] !== undefined;
            if (!hasActions)
                return;
            const verdictPromise = waitForHITLApproval(deps.db, {
                runId: ctx.runId,
                agentId,
                decisionPayload,
                executionMode: deps.executionMode,
            }, { onTimeout, timeoutMs });
            // Fire-and-forget notification via messaging channel
            const costCents = decisionPayload["estimatedCostCents"];
            const costLabel = costCents !== undefined ? ` — estimated cost: ${costCents}¢` : "";
            messaging
                .sendAlert("warn", `[HITL] ${agentId} requires approval (${hitlEscalationLevel})`, `runId=${ctx.runId} stepId=${ctx.stepId}${costLabel}\n` +
                `Payload: ${JSON.stringify(decisionPayload).slice(0, 500)}`)
                .catch((err) => {
                deps.logger.warn({ err }, `[${agentId}] HITL notification failed`);
            });
            const verdict = await verdictPromise;
            if (!verdict.approved) {
                throw new Error(verdict.rationale ?? "HITL: rejected");
            }
        };
    }
    // 4. Assemble OODAAgentConfig
    const oodaConfig = {
        agentId,
        agentVersion,
        intervalMs,
        executionMode: deps.executionMode,
        config: config.defaults,
        db: deps.db,
        logger: deps.logger,
        skills: deps.skills,
        deps: oodaDeps,
        phases,
        sessionGuards: sessionGuards ?? [alwaysOn()],
        riskGuards: riskGuards ?? [],
        outcomeMapping,
        resourceLimits: { phaseTimeoutMs: 300_000, maxStepsPerCycle: 20 },
        waitForHITL,
    };
    // 5. Create and return agent
    return createOODAAgent(oodaConfig);
}
//# sourceMappingURL=agent-factory.js.map