UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

75 lines (74 loc) • 2.1 kB
import { PushQueue } from "../core/push-queue.js"; const channels = new Map(); const activeRuns = new Map(); export function markWorkflowActive(runId, scope) { activeRuns.set(runId, scope); } export function isWorkflowRunActive(runId) { return activeRuns.has(runId); } export function publishWorkflowEvent(runId, event) { const subs = channels.get(runId); if (!subs) return; for (const q of subs) q.push(event); } export function closeWorkflowChannel(runId) { activeRuns.delete(runId); const subs = channels.get(runId); if (!subs) return; for (const q of subs) q.close(); channels.delete(runId); } export function subscribeWorkflow(runId, scope) { if (activeRuns.get(runId) !== scope) { return { async *[Symbol.asyncIterator]() { }, }; } const queue = new PushQueue(); let subs = channels.get(runId); if (!subs) { subs = new Set(); channels.set(runId, subs); } subs.add(queue); return { async *[Symbol.asyncIterator]() { try { for await (const ev of queue) yield ev; } finally { const live = channels.get(runId); if (live) { live.delete(queue); if (live.size === 0) channels.delete(runId); } } }, }; } export function listWorkflowRuns(store, scope, opts) { return store.listByScope(scope, opts); } export async function getWorkflowRun(store, id, scope) { const run = await store.get(id); return run && run.scope === scope ? run : null; } export function deriveAgentDisplayStatus(agent, runStatus) { if (agent.status === "completed") return "done"; if (agent.status === "failed") return "failed"; if (agent.status === "parked") return "parked"; if (runStatus !== "running") return "interrupted"; return agent.startedAt === undefined ? "queued" : "running"; }