UNPKG

@langchain/langgraph-sdk

Version:

Client library for interacting with the LangGraph API

84 lines (83 loc) • 3.17 kB
//#region src/ui/hitl-interrupt-payload.ts /** * Human-in-the-loop interrupt values from the LangGraph API may use * snake_case (Python server) while JS clients and LangChain types expect * camelCase. Normalize known HITL fields on interrupt payloads at read time. */ /** * Copy a plain object and expose both casing styles for a field. * * camelCase is treated as canonical when both keys are present so newer * consumers keep the current behavior while legacy snake_case access still * resolves to the same value. */ function aliasCasePair(item, camel, snake) { if (item === null || typeof item !== "object" || Array.isArray(item)) return item; const o = item; const merged = o[camel] ?? o[snake]; const next = { ...o }; if (merged !== void 0) { next[camel] = merged; next[snake] = merged; } return next; } function mapArrayAlias(raw, camel, snake) { if (!Array.isArray(raw)) return raw; return raw.map((item) => aliasCasePair(item, camel, snake)); } /** * If `value` looks like a HITL request object, expose both the new camelCase * keys and the deprecated snake_case aliases so older apps keep working while * migrating to the new shape. */ function normalizeHitlInterruptPayload(value) { if (value === null || typeof value !== "object") return value; if (Array.isArray(value)) return value.map((v) => normalizeHitlInterruptPayload(v)); const obj = value; if (!("action_requests" in obj || "actionRequests" in obj || "review_configs" in obj || "reviewConfigs" in obj)) return value; const next = { ...obj }; const actionRequestsRaw = obj.actionRequests ?? obj.action_requests; if (actionRequestsRaw !== void 0) { const actionRequests = mapArrayAlias(actionRequestsRaw, "name", "action_name"); next.actionRequests = actionRequests; next.action_requests = actionRequests; } const reviewConfigsRaw = obj.reviewConfigs ?? obj.review_configs; if (reviewConfigsRaw !== void 0) { const reviewConfigs = mapArrayAlias(reviewConfigsRaw, "allowedDecisions", "allowed_decisions"); next.reviewConfigs = reviewConfigs; next.review_configs = reviewConfigs; } return next; } function normalizeDecisionForServer(decision) { if (decision === null || typeof decision !== "object" || Array.isArray(decision)) return decision; const obj = decision; if (obj.type !== "edit") return decision; const edited = obj.editedAction ?? obj.edited_action; if (edited === void 0) return decision; return { ...obj, editedAction: edited, edited_action: edited }; } /** * If `value` looks like a HITL resume payload from a JS client, expose both * camelCase and snake_case decision fields so Python and JS runtimes accept it. */ function normalizeHitlResponseForServer(value) { if (value === null || typeof value !== "object" || Array.isArray(value)) return value; const obj = value; const decisions = obj.decisions; if (!Array.isArray(decisions)) return value; return { ...obj, decisions: decisions.map(normalizeDecisionForServer) }; } //#endregion exports.normalizeHitlInterruptPayload = normalizeHitlInterruptPayload; exports.normalizeHitlResponseForServer = normalizeHitlResponseForServer; //# sourceMappingURL=hitl-interrupt-payload.cjs.map