@langchain/langgraph
Version:
LangGraph
125 lines • 4.27 kB
JavaScript
import { BinaryOperatorAggregate } from "../../channels/binop.js";
import { LastValue } from "../../channels/last_value.js";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const META_MAP = new WeakMap();
function isZodType(value) {
return (typeof value === "object" &&
value != null &&
"_parse" in value &&
typeof value._parse === "function");
}
/**
* @internal
*/
export function isZodDefault(value) {
return (isZodType(value) &&
"removeDefault" in value &&
typeof value.removeDefault === "function");
}
/**
* @internal
*/
export function isAnyZodObject(value) {
return (isZodType(value) &&
"partial" in value &&
typeof value.partial === "function");
}
export function withLangGraph(schema, meta) {
if (meta.reducer && !meta.default) {
const defaultValue = isZodDefault(schema)
? schema._def.defaultValue
: undefined;
if (defaultValue != null) {
// eslint-disable-next-line no-param-reassign
meta.default = defaultValue;
}
}
META_MAP.set(schema, meta);
return schema;
}
export function getMeta(schema) {
return META_MAP.get(schema);
}
export function extendMeta(schema, update) {
const existingMeta = getMeta(schema);
const newMeta = update(existingMeta);
META_MAP.set(schema, newMeta);
}
export function getChannelsFromZod(schema) {
const channels = {};
for (const key in schema.shape) {
if (Object.prototype.hasOwnProperty.call(schema.shape, key)) {
const keySchema = schema.shape[key];
const meta = getMeta(keySchema);
if (meta?.reducer) {
channels[key] = new BinaryOperatorAggregate(meta.reducer.fn, meta.default);
}
else {
channels[key] = new LastValue();
}
}
}
return channels;
}
const ZOD_TYPE_CACHE = {};
const ZOD_DESCRIPTION_PREFIX = "lg:";
export function applyZodPlugin(schema, actions) {
const cacheKey = [
`reducer:${actions.reducer ?? false}`,
`jsonSchemaExtra:${actions.jsonSchemaExtra ?? false}`,
`partial:${actions.partial ?? false}`,
].join("|");
ZOD_TYPE_CACHE[cacheKey] ??= new WeakMap();
const cache = ZOD_TYPE_CACHE[cacheKey];
if (cache.has(schema))
return cache.get(schema);
let shape = schema.extend({
...Object.fromEntries(Object.entries(schema.shape).map(([key, input]) => {
const meta = getMeta(input);
let output = actions.reducer ? meta?.reducer?.schema ?? input : input;
if (actions.jsonSchemaExtra) {
const strMeta = JSON.stringify({
...meta?.jsonSchemaExtra,
description: output.description ?? input.description,
});
if (strMeta !== "{}") {
output = output.describe(`${ZOD_DESCRIPTION_PREFIX}${strMeta}`);
}
}
return [key, output];
})),
});
// using zObject.extend() will set `unknownKeys` to `passthrough`
// which trips up `zod-to-json-schema`
if ("_def" in shape &&
shape._def != null &&
typeof shape._def === "object" &&
"unknownKeys" in shape._def) {
shape._def.unknownKeys = "strip";
}
if (actions.partial)
shape = shape.partial();
cache.set(schema, shape);
return shape;
}
export function applyExtraFromDescription(schema) {
if (Array.isArray(schema)) {
return schema.map(applyExtraFromDescription);
}
if (typeof schema === "object" && schema != null) {
const output = Object.fromEntries(Object.entries(schema).map(([key, value]) => [
key,
applyExtraFromDescription(value),
]));
if ("description" in output &&
typeof output.description === "string" &&
output.description.startsWith(ZOD_DESCRIPTION_PREFIX)) {
const strMeta = output.description.slice(ZOD_DESCRIPTION_PREFIX.length);
delete output.description;
Object.assign(output, JSON.parse(strMeta));
}
return output;
}
return schema;
}
//# sourceMappingURL=state.js.map