UNPKG

langchain

Version:
1 lines • 11.7 kB
{"version":3,"file":"utils.cjs","names":["StateSchema","ReducedValue","z","isInteropZodObject","interopZodObjectMakeFieldsOptional","interopSafeParseAsync","getInteropZodObjectShape","interopZodObjectPartial","isZodSchemaV4","END"],"sources":["../../../src/agents/nodes/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport {\n getInteropZodObjectShape,\n interopSafeParseAsync,\n interopZodObjectMakeFieldsOptional,\n interopZodObjectPartial,\n isInteropZodObject,\n isZodSchemaV4,\n type InteropZodObject,\n} from \"@langchain/core/utils/types\";\nimport type { StateDefinitionInit } from \"@langchain/langgraph\";\nimport { END, StateSchema, ReducedValue } from \"@langchain/langgraph\";\n\nimport type { JumpTo } from \"../types.js\";\nimport type { AnyAgentMiddleware } from \"../middleware/types.js\";\n\n/**\n * Helper function to initialize middleware state defaults.\n * This is used to ensure all middleware state properties are initialized.\n *\n * Private properties (starting with _) are automatically made optional since\n * users cannot provide them when invoking the agent.\n */\nexport async function initializeMiddlewareStates(\n middlewareList: readonly AnyAgentMiddleware[],\n state: unknown\n): Promise<Record<string, any>> {\n const middlewareStates: Record<string, any> = {};\n\n for (const middleware of middlewareList) {\n /**\n * skip middleware if it doesn't have a state schema\n */\n if (!middleware.stateSchema) {\n continue;\n }\n\n // Convert StateSchema to Zod object if needed\n let zodSchema: InteropZodObject;\n if (StateSchema.isInstance(middleware.stateSchema)) {\n const zodShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(\n middleware.stateSchema.fields\n )) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n zodShape[key] = field.inputSchema || field.valueSchema;\n } else {\n zodShape[key] = field;\n }\n }\n zodSchema = z.object(zodShape);\n } else if (isInteropZodObject(middleware.stateSchema)) {\n zodSchema = middleware.stateSchema;\n } else {\n continue;\n }\n\n // Create a modified schema where private properties are optional\n const modifiedSchema = interopZodObjectMakeFieldsOptional(\n zodSchema,\n (key) => key.startsWith(\"_\")\n );\n\n // Use safeParse with the modified schema\n const parseResult = await interopSafeParseAsync(modifiedSchema, state);\n if (parseResult.success) {\n Object.assign(middlewareStates, parseResult.data);\n continue;\n }\n\n /**\n * If safeParse fails, there are required public fields missing.\n * Note: Zod v3 uses message \"Required\", Zod v4 uses \"Invalid input: expected X, received undefined\"\n */\n const requiredFields = parseResult.error.issues\n .filter((issue) => issue.code === \"invalid_type\")\n .map((issue) => ` - ${issue.path.join(\".\")}: Required`)\n .join(\"\\n\");\n\n throw new Error(\n `Middleware \"${middleware.name}\" has required state fields that must be initialized:\\n` +\n `${requiredFields}\\n\\n` +\n `To fix this, either:\\n` +\n `1. Provide default values in your middleware's state schema using .default():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().default(\"default value\")\\n` +\n ` })\\n\\n` +\n `2. Or make the fields optional using .optional():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().optional()\\n` +\n ` })\\n\\n` +\n `3. Or ensure you pass these values when invoking the agent:\\n` +\n ` agent.invoke({\\n` +\n ` messages: [...],\\n` +\n ` ${parseResult.error.issues[0]?.path.join(\".\")}: \"value\"\\n` +\n ` })`\n );\n }\n\n return middlewareStates;\n}\n\n/**\n * Users can define private and public state for a middleware. Private state properties start with an underscore.\n * This function will return the private state properties from the state schema, making all of them optional.\n * @param stateSchema - The middleware state schema\n * @returns A new schema containing only the private properties (underscore-prefixed), all made optional\n */\nexport function derivePrivateState(\n stateSchema?: StateDefinitionInit\n): InteropZodObject {\n const builtInStateSchema = {\n messages: z.custom<BaseMessage[]>(() => []),\n // Include optional structuredResponse so after_agent hooks can access/modify it\n structuredResponse: z.any().optional(),\n };\n\n if (!stateSchema) {\n return z.object(builtInStateSchema);\n }\n\n // Extract shape from either StateSchema or Zod object\n let shape: Record<string, any>;\n if (StateSchema.isInstance(stateSchema)) {\n // For StateSchema, extract Zod schemas from fields\n shape = {};\n for (const [key, field] of Object.entries(stateSchema.fields)) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n shape[key] = field.inputSchema || field.valueSchema;\n } else {\n shape[key] = field;\n }\n }\n } else if (isInteropZodObject(stateSchema)) {\n shape = getInteropZodObjectShape(stateSchema);\n } else {\n return z.object(builtInStateSchema);\n }\n\n const privateShape: Record<string, any> = { ...builtInStateSchema };\n\n // Filter properties that start with underscore and make them optional\n for (const [key, value] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) {\n // Make the private property optional\n privateShape[key] = value.optional();\n } else {\n privateShape[key] = value;\n }\n }\n\n // Return a new schema with only private properties (all optional)\n return z.object(privateShape);\n}\n\n/**\n * Converts any supported schema type (ZodObject, StateSchema, AnnotationRoot) to a partial Zod object.\n * This is useful for parsing state loosely where all fields are optional.\n *\n * @param schema - The schema to convert (InteropZodObject, StateSchema, or AnnotationRoot)\n * @returns A partial Zod object schema where all fields are optional\n */\nexport function toPartialZodObject(\n schema: StateDefinitionInit\n): InteropZodObject {\n // Handle ZodObject directly\n if (isInteropZodObject(schema)) {\n return interopZodObjectPartial(schema);\n }\n\n // Handle StateSchema: convert fields to Zod shape, then make partial\n if (StateSchema.isInstance(schema)) {\n const partialShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(schema.fields)) {\n let fieldSchema: unknown;\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n fieldSchema = field.inputSchema || field.valueSchema;\n } else {\n fieldSchema = field;\n }\n // Only call .optional() on Zod v4 schemas, otherwise use z.any()\n partialShape[key] = isZodSchemaV4(fieldSchema)\n ? (fieldSchema as any).optional()\n : z.any().optional();\n }\n return z.object(partialShape);\n }\n\n // Fallback: return empty object schema\n return z.object({});\n}\n\n/**\n * Parse `jumpTo` target from user facing labels to a LangGraph node names\n */\nexport function parseJumpToTarget(target: string): JumpTo;\nexport function parseJumpToTarget(target?: string): JumpTo | undefined {\n if (!target) {\n return undefined;\n }\n\n /**\n * if target is already a valid jump target, return it\n */\n if ([\"model_request\", \"tools\", END].includes(target)) {\n return target as JumpTo;\n }\n\n if (target === \"model\") {\n return \"model_request\";\n }\n if (target === \"tools\") {\n return \"tools\";\n }\n if (target === \"end\") {\n return END;\n }\n\n throw new Error(\n `Invalid jump target: ${target}, must be \"model\", \"tools\" or \"end\".`\n );\n}\n\n/**\n * TypeScript currently doesn't support types for `AbortSignal.any`\n * @see https://github.com/microsoft/TypeScript/issues/60695\n */\ndeclare const AbortSignal: {\n any(signals: AbortSignal[]): AbortSignal;\n};\n\n/**\n * `config` always contains a signal from LangGraphs Pregel class.\n * To ensure we acknowledge the abort signal from the user, we merge it\n * with the signal from the ToolNode.\n *\n * @param signals - The signals to merge.\n * @returns The merged signal.\n */\nexport function mergeAbortSignals(\n ...signals: (AbortSignal | undefined)[]\n): AbortSignal {\n return AbortSignal.any(\n signals.filter(\n (maybeSignal): maybeSignal is AbortSignal =>\n maybeSignal !== null &&\n maybeSignal !== undefined &&\n typeof maybeSignal === \"object\" &&\n \"aborted\" in maybeSignal &&\n typeof maybeSignal.aborted === \"boolean\"\n )\n );\n}\n"],"mappings":"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"}