UNPKG

@langchain/langgraph

Version:
192 lines (191 loc) 7.69 kB
const require_constants = require("../constants.cjs"); const require_binop = require("../channels/binop.cjs"); const require_last_value = require("../channels/last_value.cjs"); const require_types = require("./types.cjs"); const require_adapter = require("./adapter.cjs"); const require_delta = require("../channels/delta.cjs"); const require_untracked_value = require("../channels/untracked_value.cjs"); require("../channels/index.cjs"); const require_reduced = require("./values/reduced.cjs"); const require_untracked = require("./values/untracked.cjs"); const require_delta$1 = require("./values/delta.cjs"); //#region src/state/schema.ts const STATE_SCHEMA_SYMBOL = Symbol.for("langgraph.state.state_schema"); /** * StateSchema provides a unified API for defining LangGraph state schemas. * * @example * ```ts * import { z } from "zod"; * import { StateSchema, ReducedValue, MessagesValue } from "@langchain/langgraph"; * * const AgentState = new StateSchema({ * // Prebuilt messages value * messages: MessagesValue, * // Basic LastValue channel from any standard schema * currentStep: z.string(), * // LastValue with native default * count: z.number().default(0), * // ReducedValue for fields needing reducers * history: new ReducedValue( * z.array(z.string()).default(() => []), * { * inputSchema: z.string(), * reducer: (current, next) => [...current, next], * } * ), * }); * * // Extract types * type State = typeof AgentState.State; * type Update = typeof AgentState.Update; * * // Use in StateGraph * const graph = new StateGraph(AgentState); * ``` */ var StateSchema = class { /** * Symbol for runtime identification. * @internal Used by isInstance for runtime type checking */ [STATE_SCHEMA_SYMBOL] = true; constructor(fields) { this.fields = fields; } /** * Get the channel definitions for use with StateGraph. * This converts the StateSchema fields into BaseChannel instances. */ getChannels() { const channels = {}; for (const [key, value] of Object.entries(this.fields)) if (require_delta$1.DeltaValue.isInstance(value)) { const defaultGetter = require_adapter.getSchemaDefaultGetter(value.valueSchema); channels[key] = new require_delta.DeltaChannel(value.reducer, { snapshotFrequency: value.snapshotFrequency, initialValueFactory: defaultGetter }); } else if (require_reduced.ReducedValue.isInstance(value)) { const defaultGetter = require_adapter.getSchemaDefaultGetter(value.valueSchema); channels[key] = new require_binop.BinaryOperatorAggregate(value.reducer, defaultGetter); } else if (require_untracked.UntrackedValue.isInstance(value)) { const defaultGetter = value.schema ? require_adapter.getSchemaDefaultGetter(value.schema) : void 0; channels[key] = new require_untracked_value.UntrackedValueChannel({ guard: value.guard, initialValueFactory: defaultGetter }); } else if (require_types.isStandardSchema(value)) channels[key] = new require_last_value.LastValue(require_adapter.getSchemaDefaultGetter(value)); else throw new Error(`Invalid state field "${key}": must be a schema, ReducedValue, DeltaValue, UntrackedValue, or ManagedValue`); return channels; } /** * Get the JSON schema for the full state type. * Used by Studio and API for schema introspection. */ getJsonSchema() { const properties = {}; const required = []; for (const [key, value] of Object.entries(this.fields)) { let fieldSchema; if (require_delta$1.DeltaValue.isInstance(value) || require_reduced.ReducedValue.isInstance(value)) { fieldSchema = require_adapter.getJsonSchemaFromSchema(value.valueSchema); if (value.jsonSchemaExtra) fieldSchema = { ...fieldSchema ?? {}, ...value.jsonSchemaExtra }; } else if (require_untracked.UntrackedValue.isInstance(value)) fieldSchema = value.schema ? require_adapter.getJsonSchemaFromSchema(value.schema) : void 0; else if (require_types.isStandardSchema(value)) fieldSchema = require_adapter.getJsonSchemaFromSchema(value); if (fieldSchema) { properties[key] = fieldSchema; let hasDefault = false; if (require_delta$1.DeltaValue.isInstance(value) || require_reduced.ReducedValue.isInstance(value)) hasDefault = require_adapter.getSchemaDefaultGetter(value.valueSchema) !== void 0; else if (require_untracked.UntrackedValue.isInstance(value)) hasDefault = value.schema ? require_adapter.getSchemaDefaultGetter(value.schema) !== void 0 : false; else hasDefault = require_adapter.getSchemaDefaultGetter(value) !== void 0; if (!hasDefault) required.push(key); } } return { type: "object", properties, required: required.length > 0 ? required : void 0 }; } /** * Get the JSON schema for the update/input type. * All fields are optional in updates. */ getInputJsonSchema() { const properties = {}; for (const [key, value] of Object.entries(this.fields)) { let fieldSchema; if (require_delta$1.DeltaValue.isInstance(value) || require_reduced.ReducedValue.isInstance(value)) { fieldSchema = require_adapter.getJsonSchemaFromSchema(value.inputSchema); if (value.jsonSchemaExtra) fieldSchema = { ...fieldSchema ?? {}, ...value.jsonSchemaExtra }; } else if (require_untracked.UntrackedValue.isInstance(value)) fieldSchema = value.schema ? require_adapter.getJsonSchemaFromSchema(value.schema) : void 0; else if (require_types.isStandardSchema(value)) fieldSchema = require_adapter.getJsonSchemaFromSchema(value); if (fieldSchema) properties[key] = fieldSchema; } return { type: "object", properties }; } /** * Get the list of channel keys (excluding managed values). */ getChannelKeys() { return Object.entries(this.fields).map(([key]) => key); } /** * Get all keys (channels + managed values). */ getAllKeys() { return Object.keys(this.fields); } /** * Validate input data against the schema. * This validates each field using its corresponding schema. * * @param data - The input data to validate * @returns The validated data with coerced types */ async validateInput(data) { if (data == null || typeof data !== "object") return data; const result = {}; for (const [key, value] of Object.entries(data)) { const fieldDef = this.fields[key]; if (fieldDef === void 0) { result[key] = value; continue; } let schema; if (require_delta$1.DeltaValue.isInstance(fieldDef) || require_reduced.ReducedValue.isInstance(fieldDef)) { const [isOverwrite, overwriteValue] = require_constants._getOverwriteValue(value); if (isOverwrite) { schema = fieldDef.valueSchema; const validationResult = await schema["~standard"].validate(overwriteValue); if (validationResult.issues) throw new Error(`Validation failed for field "${key}": ${JSON.stringify(validationResult.issues)}`); result[key] = { [require_constants.OVERWRITE]: validationResult.value }; continue; } schema = fieldDef.inputSchema; } else if (require_untracked.UntrackedValue.isInstance(fieldDef)) schema = fieldDef.schema; else if (require_types.isStandardSchema(fieldDef)) schema = fieldDef; if (schema) { const validationResult = await schema["~standard"].validate(value); if (validationResult.issues) throw new Error(`Validation failed for field "${key}": ${JSON.stringify(validationResult.issues)}`); result[key] = validationResult.value; } else result[key] = value; } return result; } static isInstance(value) { return typeof value === "object" && value !== null && STATE_SCHEMA_SYMBOL in value && value[STATE_SCHEMA_SYMBOL] === true; } }; //#endregion exports.StateSchema = StateSchema; //# sourceMappingURL=schema.cjs.map