@sema-agent/core
Version:
Stateless, task-oriented AI agent core
75 lines (74 loc) • 2.1 kB
JavaScript
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";
}