Merge pull request #73 from langchain-ai/brace/improve-hitl-rendering

fix: Allow for human interrupt to be passed without array
This commit is contained in:
Brace Sproul
2025-03-17 14:09:49 -07:00
committed by GitHub
4 changed files with 27 additions and 22 deletions

View File

@@ -100,6 +100,7 @@ export function ThreadActionsView({
const threadTitle = interrupt.action_request.action || "Unknown";
const actionsDisabled = loading || streaming;
const ignoreAllowed = interrupt.config.allow_ignore;
return (
<div className="flex flex-col min-h-full w-full gap-9">
@@ -138,14 +139,16 @@ export function ThreadActionsView({
>
Mark as Resolved
</Button>
<Button
variant="outline"
className="text-gray-800 border-gray-500 font-normal bg-white"
onClick={handleIgnore}
disabled={actionsDisabled}
>
Ignore
</Button>
{ignoreAllowed && (
<Button
variant="outline"
className="text-gray-800 border-gray-500 font-normal bg-white"
onClick={handleIgnore}
disabled={actionsDisabled}
>
Ignore
</Button>
)}
</div>
{/* Actions */}

View File

@@ -5,10 +5,11 @@ import { HumanInterrupt } from "@langchain/langgraph/prebuilt";
import { useStreamContext } from "@/providers/Stream";
interface ThreadViewProps {
interrupt: HumanInterrupt;
interrupt: HumanInterrupt | HumanInterrupt[];
}
export function ThreadView({ interrupt }: ThreadViewProps) {
const interruptObj = Array.isArray(interrupt) ? interrupt[0] : interrupt;
const thread = useStreamContext();
const [showDescription, setShowDescription] = useState(false);
const [showState, setShowState] = useState(false);
@@ -39,13 +40,13 @@ export function ThreadView({ interrupt }: ThreadViewProps) {
{showSidePanel ? (
<StateView
handleShowSidePanel={handleShowSidePanel}
description={interrupt.description}
description={interruptObj.description}
values={thread.values}
view={showState ? "state" : "description"}
/>
) : (
<ThreadActionsView
interrupt={interrupt}
interrupt={interruptObj}
handleShowSidePanel={handleShowSidePanel}
showState={showState}
showDescription={showDescription}

View File

@@ -131,7 +131,7 @@ export function AssistantMessage({
<CustomComponent message={message} thread={thread} />
{isAgentInboxInterruptSchema(interrupt?.value) && isLastMessage && (
<ThreadView interrupt={interrupt.value[0]} />
<ThreadView interrupt={interrupt.value} />
)}
<div
className={cn(

View File

@@ -2,16 +2,17 @@ import { HumanInterrupt } from "@langchain/langgraph/prebuilt";
export function isAgentInboxInterruptSchema(
value: unknown,
): value is HumanInterrupt[] {
): value is HumanInterrupt | HumanInterrupt[] {
const valueAsObject = Array.isArray(value) ? value[0] : value;
return (
Array.isArray(value) &&
"action_request" in value[0] &&
typeof value[0].action_request === "object" &&
"config" in value[0] &&
typeof value[0].config === "object" &&
"allow_respond" in value[0].config &&
"allow_accept" in value[0].config &&
"allow_edit" in value[0].config &&
"allow_ignore" in value[0].config
valueAsObject &&
"action_request" in valueAsObject &&
typeof valueAsObject.action_request === "object" &&
"config" in valueAsObject &&
typeof valueAsObject.config === "object" &&
"allow_respond" in valueAsObject.config &&
"allow_accept" in valueAsObject.config &&
"allow_edit" in valueAsObject.config &&
"allow_ignore" in valueAsObject.config
);
}