UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

80 lines (79 loc) • 3.5 kB
import { checkpointStoreOfSeat } from "./checkpoint-seat.js"; import { inlineUntrusted } from "./untrusted-text.js"; const STATUS_WORDS = { pending: true, running: true, parked: true, completed: true, failed: true, killed: true, cancelled: true }; export function agentStateSourceOfHandle(h) { return { status: h.status, row: "live_row", lastActivityAt: h.updatedAt, ...(h.parkedCheckpointToken !== undefined ? { parkedCheckpointToken: h.parkedCheckpointToken } : {}), }; } export function agentStateSourceOfRecord(r) { const at = r.status === "parked" ? r.parkedAt : r.status === "running" ? undefined : r.settledAt; return { status: r.status, row: "durable_row", ...(at !== undefined ? { lastActivityAt: at } : {}), ...(r.parkedCheckpointToken !== undefined ? { parkedCheckpointToken: r.parkedCheckpointToken } : {}), }; } const finite = (n) => typeof n === "number" && Number.isFinite(n); async function readApprovalCard(store, token) { let cp; try { cp = (await store.get(token)); } catch { return { state: "unreadable" }; } if (cp === null || cp === undefined) return { state: "missing" }; const state = cp.status === "pending" || cp.status === "resolved" || cp.status === "expired" ? cp.status : "unreadable"; return { state, ...(typeof cp.checkpointId === "string" && cp.checkpointId !== "" ? { checkpointId: cp.checkpointId } : {}), ...(finite(cp.deadline) ? { deadline: cp.deadline } : {}), }; } export function readAgentState(src, seat, now) { const base = { status: Object.hasOwn(STATUS_WORDS, src.status) ? src.status : "unknown", readAt: now, row: src.row, ...(finite(src.lastActivityAt) ? { lastActivityAt: src.lastActivityAt } : {}), }; if (base.status !== "parked") return base; if (src.parkedCheckpointToken === undefined) return { ...base, approval: { state: "missing" } }; const store = checkpointStoreOfSeat(seat); if (store === undefined) return { ...base, approval: { state: "unreadable" } }; return readApprovalCard(store, src.parkedCheckpointToken).then((approval) => ({ ...base, approval })); } export function formatAgo(ms) { const sec = Math.max(0, Math.floor(ms / 1000)); if (sec < 60) return `${sec}s`; const min = Math.floor(sec / 60); if (min < 60) return `${min}m`; const h = Math.floor(min / 60); if (h < 48) return `${h}h`; return `${Math.floor(h / 24)}d`; } export function agentActivityClause(s) { if (s.lastActivityAt !== undefined) return `last activity ${formatAgo(s.readAt - s.lastActivityAt)} ago`; return s.row === "durable_row" && s.status === "running" ? "last activity unknown (recorded as running by another engine process)" : "last activity unknown (not recorded)"; } export function agentApprovalClause(a, readAt) { const id = a.checkpointId !== undefined ? ` ${inlineUntrusted(a.checkpointId, 64)}` : ""; const deadline = a.deadline === undefined ? "" : a.deadline > readAt ? ` (deadline in ${formatAgo(a.deadline - readAt)})` : ` (deadline passed ${formatAgo(readAt - a.deadline)} ago)`; return `approval${id} ${a.state}${deadline}`; } export function agentStateSummary(s) { return [s.status, agentActivityClause(s), ...(s.approval !== undefined ? [agentApprovalClause(s.approval, s.readAt)] : [])].join(" · "); }