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 { createAgent, summarizationMiddleware, humanInTheLoopMiddleware } from "langchain";
import { createApiBasedToolsMiddleware } from "../middleware/apiBasedTools.js";
import { createSequenceDebugMiddleware } from "../middleware/sequenceDebug.js";
import { createAgentLlmMetricsLogger } from "../simpleAgent.js";
import { contextSchema, toLangchainAgentContext } from "./AgentContext.js";
function createHumanInTheLoopInterrupts(apiBasedTools) {
    return Object.fromEntries(Object.entries(apiBasedTools)
        .filter(([, apiBasedTool]) => { var _a; return ((_a = apiBasedTool.agent) === null || _a === void 0 ? void 0 : _a.isDangerous) === true; })
        .map(([toolName]) => [
        toolName,
        {
            allowedDecisions: ["approve", "reject"],
        },
    ]));
}
export class AgentRuntime {
    constructor(options) {
        this.options = options;
    }
    stream(input) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a;
            const apiBasedTools = this.options.toolProvider.getApiBasedTools();
            const tools = yield this.options.toolProvider.getTools(apiBasedTools);
            const adminforth = this.options.getAdminforth();
            const apiBasedToolsMiddleware = createApiBasedToolsMiddleware(apiBasedTools, adminforth);
            const sequenceDebugMiddleware = createSequenceDebugMiddleware(input.observability.sequenceDebugSink);
            const hitlMiddleware = humanInTheLoopMiddleware({
                interruptOn: createHumanInTheLoopInterrupts(apiBasedTools),
                descriptionPrefix: "Tool execution pending approval",
            });
            const middleware = [
                apiBasedToolsMiddleware,
                hitlMiddleware,
                ...((_a = input.models.modelMiddleware) !== null && _a !== void 0 ? _a : []),
                sequenceDebugMiddleware,
                summarizationMiddleware({
                    model: input.models.summaryModel,
                    trigger: { tokens: 1024 * 64 },
                    keep: { messages: 10 },
                }),
            ];
            const agent = createAgent({
                name: this.options.name,
                model: input.models.model,
                checkpointer: this.options.getCheckpointer(),
                tools,
                contextSchema,
                middleware,
            });
            return agent.stream(input.input, {
                streamMode: ["messages", "updates"],
                recursionLimit: 100,
                callbacks: [createAgentLlmMetricsLogger()],
                signal: input.context.abortSignal,
                configurable: {
                    thread_id: input.context.sessionId,
                },
                context: toLangchainAgentContext(Object.assign(Object.assign({}, input.context), { adminBaseUrl: adminforth.config.baseUrlSlashed, emit: input.observability.emit, sequenceDebugSink: input.observability.sequenceDebugSink })),
            });
        });
    }
}
