UNPKG

@llamaindex/ui

Version:

A comprehensive UI component library built with React, TypeScript, and Tailwind CSS for LlamaIndex applications

113 lines (98 loc) 3.18 kB
import type { ExtractedFieldMetadataDict, ExtractedFieldMetadata, } from "llama-cloud-services/beta/agent"; /** * Find metadata for a specific field path in the API metadata object * The metadata structure mirrors the data structure (tree-like) * * Algorithm: * Direct tree traversal following the exact path structure: * - For objects: metadata.merchant.name * - For arrays: metadata.items[0].description * * @param path - The field path as a string (e.g., "merchant.name") or array of path segments * @param metadata - The metadata object from API (ExtractedFieldMetadataDict) * @returns The metadata for the field, or undefined if not found */ export function findExtractedFieldMetadata( path: string | string[], metadata: ExtractedFieldMetadataDict ): ExtractedFieldMetadata | undefined { // Convert string path to array const pathArray = Array.isArray(path) ? path : path.split("."); // Direct tree traversal following the exact path structure let current: unknown = metadata; for (let i = 0; i < pathArray.length; i++) { const segment = pathArray[i]; if (!current || typeof current !== "object") { return undefined; } // Handle array indices if (!isNaN(Number(segment))) { if (Array.isArray(current)) { const index = Number(segment); current = current[index]; } else { // If we expect an array but current is not an array, path doesn't exist return undefined; } } else { // Handle object properties current = (current as Record<string, unknown>)[segment]; } // Check if we found metadata at this level if (isExtractedFieldMetadata(current)) { return current; } } return undefined; } /** * Type guard to check if a value is ExtractedFieldMetadata */ export function isExtractedFieldMetadata( value: unknown ): value is ExtractedFieldMetadata { if (value === null || typeof value !== "object") { return false; } const obj = value as Record<string, unknown>; // All fields are optional but confidence is actually always there // TODO: change ts sdk to reflect this fact if ("confidence" in obj && typeof obj.confidence === "number") { return true; } return false; } /** * Recursively build metadata paths for nested data structures * This helps with understanding all possible paths in a data object * * @param data - The data object to analyze * @param prefix - Current path prefix * @returns Array of all paths found in the data */ export function buildMetadataPaths( data: unknown, prefix: string = "" ): string[] { const paths: string[] = []; if (!data || typeof data !== "object") { return paths; } if (Array.isArray(data)) { data.forEach((_, index) => { const itemPath = prefix ? `${prefix}.${index}` : `${index}`; paths.push(itemPath); paths.push(...buildMetadataPaths(data[index], itemPath)); }); } else { Object.entries(data).forEach(([key, value]) => { const keyPath = prefix ? `${prefix}.${key}` : key; paths.push(keyPath); paths.push(...buildMetadataPaths(value, keyPath)); }); } return paths; }