var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { AdminForthPlugin, logger } from "adminforth";
import { MemorySaver } from "@langchain/langgraph";
import { AdminForthCheckpointSaver } from "./persistence/checkpointStore.js";
import { appendCustomSystemPrompt, buildAgentSystemPrompt, DEFAULT_AGENT_SYSTEM_PROMPT } from "./domain/systemPrompt.js";
import { setupCoreEndpoints } from "./transport/http/coreEndpoints.js";
import { setupSessionEndpoints } from "./transport/http/sessionEndpoints.js";
import { setupChatSurfaceEndpoints } from "./transport/http/chatSurfaceEndpoints.js";
import { AgentSessionStore } from "./persistence/sessionStore.js";
import { ChatSurfaceService } from "./transport/surfaces/chatSurfaceService.js";
import { RunTurnUseCase } from "./application/runTurnUseCase.js";
import { createSequenceDebugCollector } from "./llm/middleware/sequenceDebug.js";
import { LangGraphLlm } from "./llm/langGraphLlm.js";
import { AgentModelFactory } from "./llm/modelFactory.js";
import { AgentRuntime } from "./llm/agentRuntime.js";
import { SpeechTurnService } from "./transport/surfaces/speechTurnService.js";
import { AgentToolProvider } from "./tools/agentToolProvider.js";
import { SteerBuffer } from "./domain/steerBuffer.js";
export default class AdminForthAgentPlugin extends AdminForthPlugin {
    getCheckpointer() {
        if (this.checkpointer)
            return this.checkpointer;
        this.checkpointer = this.options.checkpointResource
            ? new AdminForthCheckpointSaver(this.adminforth, this.options)
            : new MemorySaver();
        return this.checkpointer;
    }
    getInternalAgentResourceIds() {
        var _a;
        return [
            this.options.sessionResource.resourceId,
            this.options.turnResource.resourceId,
            (_a = this.options.checkpointResource) === null || _a === void 0 ? void 0 : _a.resourceId,
        ].filter((resourceId) => Boolean(resourceId));
    }
    getAgentSystemPrompt() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.agentSystemPrompt) {
                const systemPrompt = yield buildAgentSystemPrompt(this.adminforth, this.getInternalAgentResourceIds()).catch((err) => {
                    logger.error(`Failed to build agent system prompt, falling back to default: ${err instanceof Error ? err.message : String(err)}`);
                    return DEFAULT_AGENT_SYSTEM_PROMPT;
                });
                this.agentSystemPrompt = appendCustomSystemPrompt(systemPrompt, this.options.systemPrompt);
            }
            return this.agentSystemPrompt;
        });
    }
    constructor(options) {
        var _a;
        super(options, import.meta.url);
        this.pluginsScope = "global";
        this.agentSystemPrompt = null;
        this.checkpointer = null;
        this.options = options;
        this.sessionStore = new AgentSessionStore(() => this.adminforth, this.options);
        this.steerBuffer = new SteerBuffer();
        const toolProvider = new AgentToolProvider(() => this.adminforth, this.getInternalAgentResourceIds.bind(this));
        const runtime = new AgentRuntime({
            name: `adminforth-agent-${this.pluginInstanceId}`,
            getAdminforth: () => this.adminforth,
            getCheckpointer: this.getCheckpointer.bind(this),
            toolProvider,
            steerBuffer: this.steerBuffer,
        });
        const llm = new LangGraphLlm(runtime, new AgentModelFactory((_a = this.options.maxTokens) !== null && _a !== void 0 ? _a : 1000));
        this.runTurnUseCase = new RunTurnUseCase({
            llm,
            sessions: this.sessionStore,
            steerBuffer: this.steerBuffer,
            modes: this.options.modes,
            getAdminforth: () => this.adminforth,
            getAgentSystemPrompt: this.getAgentSystemPrompt.bind(this),
            hasPersistentCheckpointer: Boolean(this.options.checkpointResource),
            turnCheckpointsEnabled: Boolean(this.options.turnResource.checkpointIdField),
            sessionResource: this.options.sessionResource,
            createDebugSink: createSequenceDebugCollector,
        });
        this.speechTurnService = new SpeechTurnService(this.runTurnUseCase.runAndPersistAgentResponse.bind(this.runTurnUseCase));
        this.chatSurfaceService = new ChatSurfaceService(() => this.adminforth, this.options, this.sessionStore, this.runTurnUseCase.handleTurn.bind(this.runTurnUseCase), this.runTurnUseCase.runAndPersistAgentResponse.bind(this.runTurnUseCase));
        this.agentSystemPromptPromise = Promise.resolve(appendCustomSystemPrompt(DEFAULT_AGENT_SYSTEM_PROMPT, this.options.systemPrompt));
        this.shouldHaveSingleInstancePerWholeApp = () => false;
    }
    modifyGlobalConfig(adminforth) {
        const _super = Object.create(null, {
            modifyGlobalConfig: { get: () => super.modifyGlobalConfig }
        });
        return __awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            _super.modifyGlobalConfig.call(this, adminforth);
            if (!((_a = this.options.modes) === null || _a === void 0 ? void 0 : _a.length)) {
                throw new Error("modes is required for AdminForthAgentPlugin");
            }
            if (!this.adminforth.config.customization.globalInjections.header) {
                this.adminforth.config.customization.globalInjections.header = [];
            }
            this.adminforth.config.customization.globalInjections.header.push({
                file: this.componentPath("ChatSurface.vue"),
                meta: {
                    pluginInstanceId: this.pluginInstanceId,
                    modes: this.options.modes.map((mode) => ({ name: mode.name })),
                    defaultModeName: this.options.modes[0].name,
                    stickByDefault: (_b = this.options.stickByDefault) !== null && _b !== void 0 ? _b : false,
                    hasAudioAdapter: Boolean(this.options.audioAdapter),
                    editingEnabled: Boolean(this.options.checkpointResource && this.options.turnResource.checkpointIdField),
                }
            });
            if (!this.adminforth.config.customization.customHeadItems) {
                this.adminforth.config.customization.customHeadItems = [];
            }
            this.adminforth.config.customization.customHeadItems.push({
                tagName: 'script',
                attributes: {
                    src: 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/ort.wasm.min.js'
                }
            }, {
                tagName: 'script',
                attributes: {
                    src: 'https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.29/dist/bundle.min.js'
                },
            });
            if (!this.options.sessionResource) {
                throw new Error("sessionResource is required for AdminForthAgentPlugin");
            }
        });
    }
    validateConfigAfterDiscover(adminforth, resourceConfig) {
        var _a, _b;
        (_a = this.options.audioAdapter) === null || _a === void 0 ? void 0 : _a.validate();
        for (const chatSurfaceAdapter of (_b = this.options.chatSurfaceAdapters) !== null && _b !== void 0 ? _b : []) {
            chatSurfaceAdapter.validate();
        }
        this.agentSystemPromptPromise = buildAgentSystemPrompt(adminforth, this.getInternalAgentResourceIds())
            .then((systemPrompt) => {
            const finalPrompt = appendCustomSystemPrompt(systemPrompt, this.options.systemPrompt);
            this.agentSystemPrompt = finalPrompt;
            return finalPrompt;
        });
    }
    instanceUniqueRepresentation(pluginOptions) {
        return `single`;
    }
    setupEndpoints(server) {
        const endpointContext = {
            adminforth: this.adminforth,
            options: this.options,
            handleTurn: this.runTurnUseCase.handleTurn.bind(this.runTurnUseCase),
            handleEditTurn: this.runTurnUseCase.handleEditTurn.bind(this.runTurnUseCase),
            handleSpeechTurn: this.speechTurnService.handle.bind(this.speechTurnService),
            steer: ({ sessionId, message }) => {
                const { id } = this.steerBuffer.add(sessionId, message);
                return { id, queued: this.steerBuffer.size(sessionId) };
            },
            runAndPersistAgentResponse: this.runTurnUseCase.runAndPersistAgentResponse.bind(this.runTurnUseCase),
            getSessionTurns: this.sessionStore.getSessionTurns.bind(this.sessionStore),
            createNewTurn: this.sessionStore.createNewTurn.bind(this.sessionStore),
            createSystemTurn: this.sessionStore.createSystemTurn.bind(this.sessionStore),
            appendSteerToCurrentTurn: this.sessionStore.appendSteerToCurrentTurn.bind(this.sessionStore),
            handleChatSurfaceMessage: this.chatSurfaceService.handleMessage.bind(this.chatSurfaceService),
        };
        setupCoreEndpoints(endpointContext, server);
        setupSessionEndpoints(endpointContext, server);
        setupChatSurfaceEndpoints(endpointContext, server);
    }
}
