@hotmeshio/hotmesh
Version:
Permanent-Memory Workflows & AI Agents
59 lines (58 loc) • 2.92 kB
JavaScript
;
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;