langchain
Version:
Typescript bindings for langchain
1 lines • 11.3 kB
Source Map (JSON)
{"version":3,"file":"utils.cjs","names":["StateSchema","ReducedValue","z","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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"}