SurfSense/surfsense_web/lib/hitl/use-hitl-decision.ts

41 lines
1.5 KiB
TypeScript

/**
* Shared hook for dispatching HITL decisions.
*
* Tool-ui cards always call ``dispatch([decision])``. When a multi-card bundle
* is active (``HitlBundleProvider``), the dispatch is intercepted and staged
* against this card's ``toolCallId`` so the orchestrator can submit one
* ordered N-decision payload. With no bundle active (N=1 path), it falls back
* to the legacy ``window`` event the host listens for in ``page.tsx``.
*/
import { useCallback } from "react";
import { useHitlBundle, useToolCallIdContext } from "./bundle-context";
import type { HitlDecision } from "./types";
export function useHitlDecision() {
const bundle = useHitlBundle();
const toolCallId = useToolCallIdContext();
const dispatch = useCallback(
(decisions: HitlDecision[]) => {
if (bundle && toolCallId && bundle.isInBundle(toolCallId) && decisions.length > 0) {
if (decisions.length > 1 && process.env.NODE_ENV !== "production") {
// Tool-ui cards stage one decision per call; a multi-decision
// dispatch into an active bundle would silently drop tail entries.
// eslint-disable-next-line no-console
console.warn(
"[hitl] dispatch received %d decisions inside an active bundle; only [0] will be staged for %s",
decisions.length,
toolCallId
);
}
bundle.stage(toolCallId, decisions[0]);
return;
}
window.dispatchEvent(new CustomEvent("hitl-decision", { detail: { decisions } }));
},
[bundle, toolCallId]
);
return { dispatch };
}