UNPKG

@hotmeshio/hotmesh

Version:

Permanent-Memory Workflows & AI Agents

59 lines (58 loc) 2.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.hook = void 0; const common_1 = require("./common"); const context_1 = require("./context"); const isSideEffectAllowed_1 = require("./isSideEffectAllowed"); /** * Spawns a hook from the main thread or a hook thread. * If entity/workflowName are not provided, defaults to the current workflow. * * @param {HookOptions} options - Hook configuration options. * @returns {Promise<string>} The resulting hook/stream ID. */ async function hook(options) { const { workflowId, connection, namespace, workflowTopic } = (0, context_1.getContext)(); const hotMeshClient = await common_1.WorkerService.getHotMesh(workflowTopic, { connection, namespace, }); if (await (0, isSideEffectAllowed_1.isSideEffectAllowed)(hotMeshClient, 'hook')) { const targetWorkflowId = options.workflowId ?? workflowId; let targetTopic; if (options.entity || (options.taskQueue && options.workflowName)) { targetTopic = `${options.taskQueue ?? options.entity}-${options.entity ?? options.workflowName}`; } else { targetTopic = workflowTopic; } // DEFENSIVE CHECK: Prevent infinite loops if (targetTopic === workflowTopic && !options.entity && !options.taskQueue) { throw new Error(`MemFlow Hook Error: Potential infinite loop detected!\n\n` + `The hook would target the same workflow topic ('${workflowTopic}') as the current workflow, ` + `creating an infinite loop.\n\n` + `To fix this, provide either:\n` + `1. 'taskQueue' parameter: MemFlow.workflow.hook({ taskQueue: 'your-queue', workflowName: '${options.workflowName}', args: [...] })\n` + `2. 'entity' parameter: MemFlow.workflow.hook({ entity: 'your-entity', args: [...] })\n\n` + `Current workflow topic: ${workflowTopic}\n` + `Target topic would be: ${targetTopic}\n` + `Provided options: ${JSON.stringify({ workflowName: options.workflowName, taskQueue: options.taskQueue, entity: options.entity, }, null, 2)}`); } const payload = { arguments: [...options.args], id: targetWorkflowId, workflowTopic: targetTopic, backoffCoefficient: options.config?.backoffCoefficient || common_1.HMSH_MEMFLOW_EXP_BACKOFF, maximumAttempts: options.config?.maximumAttempts || common_1.HMSH_MEMFLOW_MAX_ATTEMPTS, maximumInterval: (0, common_1.s)(options?.config?.maximumInterval ?? common_1.HMSH_MEMFLOW_MAX_INTERVAL), }; return await hotMeshClient.hook(`${namespace}.flow.signal`, payload, common_1.StreamStatus.PENDING, 202); } } exports.hook = hook;