c3671d86cf
Implements Khala cloud workflow orchestrator (Phase 0-4): - Project scaffolding: Hono + Wrangler + D1 + DO - D1 schema: agents, threads, messages, tasks tables - Data access layer with atomic claim/release - Agent auth (SHA-256 Bearer token) + admin API - ThreadDO workflow engine with JSONata moderator - Task queue API: poll/claim/release - Cron-based timeout sweep - Ping-pong demo workflow Closes #124, closes #125, closes #127, closes #128, closes #129
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
import jsonata from "jsonata";
|
|
import type { Result } from "./result.js";
|
|
import { err, ok } from "./result.js";
|
|
|
|
export type ModeratorDecision = { role: string };
|
|
|
|
export async function evaluateModerator(
|
|
expression: string,
|
|
context: Readonly<Record<string, unknown>>,
|
|
): Promise<Result<ModeratorDecision, string>> {
|
|
let expr: ReturnType<typeof jsonata>;
|
|
try {
|
|
expr = jsonata(expression);
|
|
} catch (e) {
|
|
const msg = e instanceof Error ? e.message : String(e);
|
|
return err(`jsonata compile: ${msg}`);
|
|
}
|
|
let out: unknown;
|
|
try {
|
|
out = await expr.evaluate(context);
|
|
} catch (e) {
|
|
const msg = e instanceof Error ? e.message : String(e);
|
|
return err(`jsonata eval: ${msg}`);
|
|
}
|
|
if (out === null || out === undefined) {
|
|
return err("moderator returned empty");
|
|
}
|
|
if (typeof out !== "object" || out === null || Array.isArray(out)) {
|
|
return err("moderator must return an object");
|
|
}
|
|
const rec = out as Readonly<Record<string, unknown>>;
|
|
const role = rec.role;
|
|
if (typeof role === "string") {
|
|
return ok({ role });
|
|
}
|
|
return err("moderator result missing string role");
|
|
}
|