import {z} from 'zod' export type WorkspaceFileSource = {type?: 'workspace_file' | undefined, workspace_id: string, file_id: string}; export type ParseSettingsFigures = {mode: 'omit' | 'include' | 'describe'}; export type ParseDiagramsOptions = {mode?: ('omit' | 'mermaid') | undefined}; export type ParseSpreadsheetOptions = {sheets?: (Array | null) | undefined, include_hidden_sheets?: boolean | undefined, include_hidden_rows?: boolean | undefined, include_hidden_columns?: boolean | undefined, include_formulas?: boolean | undefined}; export type PageRange = {start: number, end: number}; export type ParseSettings = {figures?: (ParseSettingsFigures | null) | undefined, diagrams?: (ParseDiagramsOptions | null) | undefined, spreadsheet?: (ParseSpreadsheetOptions | null) | undefined, page_ranges?: (Array | null) | undefined, parse_mode?: ('high' | 'medium' | 'low' | null) | undefined}; export type UploadSource = {type?: 'upload' | undefined, upload_id: string}; export type UrlSource = {type?: 'url' | undefined, url: string, file_name: string}; export type ParseResultSource = {type?: 'parse_result' | undefined, job_id: string}; export type ClassifyContext = {entity_name?: (string | null) | undefined, entity_aliases?: Array | undefined}; export type ClassifySubclass = {id: string, label: string, description?: string | undefined, criteria?: Array | undefined}; export type ClassifyClass = {id: string, label: string, description?: string | undefined, criteria?: Array | undefined, subclasses?: Array | undefined}; export type ClassifyOutputOptions = {max_alternatives?: number | undefined, include_reason?: boolean | undefined, delivery?: ('progressive' | 'complete') | undefined}; export type ClassifyRequest = {name?: (string | null) | undefined, project_id?: (string | null) | undefined, output_workspace_id?: (string | null) | undefined, corpus_sources?: Array | undefined, parse_mode?: ('low' | 'medium' | 'high') | undefined, parse?: (ParseSettings | null) | undefined, source: UploadSource | UrlSource | WorkspaceFileSource | ParseResultSource, context?: (ClassifyContext | null) | undefined, classes: Array, granularity?: ('document' | 'page') | undefined, page_ranges?: (Array | null) | undefined, unknown_policy?: ('allow' | 'force_best') | undefined, output?: ClassifyOutputOptions | undefined}; export type CreateApiV1ClassifyArgs = {wait_seconds?: number | undefined, 'Idempotency-Key'?: (string | null) | undefined, body: ClassifyRequest}; export type CreateApiV1ClassifyOptions = {baseUrl: string, APIKeyHeader?: string | undefined, fetch?: typeof fetch | undefined}; export const ndiServiceAppPlatformApiContractsJobStatus = z.enum(["queued", "running", "succeeded", "failed", "cancelled"]); export const uploadSource = z.object({type: z.literal("upload").optional(), upload_id: z.string()}); export const urlSource = z.object({type: z.literal("url").optional(), url: z.string().max(2048), file_name: z.string().max(512)}); export const workspaceFileSource = z.object({type: z.literal("workspace_file").optional(), workspace_id: z.string(), file_id: z.string()}); export const parseResultSource = z.object({type: z.literal("parse_result").optional(), job_id: z.string()}); export const workspaceQueryScope = z.object({type: z.literal("workspace").optional()}); export const fileQueryScope = z.object({type: z.literal("file").optional(), path: z.string().min(1).max(1024)}); export const pathPrefixQueryScope = z.object({type: z.literal("path_prefix").optional(), prefix: z.string().min(1).max(1024)}); export const filesQueryScope = z.object({type: z.literal("files").optional(), count: z.number().int().gte(2)}); export const knowledgeGraphBuildProgress = z.object({phase_index: z.number().int(), phase_count: z.number().int(), countable: z.boolean(), documents: z.number().int().nullable().optional(), mentions: z.number().int().nullable().optional(), step: z.string().nullable().optional(), step_done: z.number().int().nullable().optional(), step_total: z.number().int().nullable().optional()}); export const automaticLlmRouter = z.object({kind: z.literal("llm").optional()}); export const automaticNaceDmRouter = z.object({kind: z.literal("nacedm").optional(), p_agent: z.number().gte(0).lte(1).nullable(), decision_point: z.number().gte(0).lte(1)}); export const automaticRequestedRouter = z.object({kind: z.literal("requested").optional()}); export const automaticSearchRouting = z.object({selected: z.enum(["fact", "agent", "deep", "filtered"]), final: z.enum(["fact", "agent", "deep", "filtered"]), reason: z.string(), router_model: z.string(), router: z.discriminatedUnion("kind", [automaticLlmRouter, automaticNaceDmRouter, automaticRequestedRouter]).optional(), router_wall_ms: z.number().int().nullable().optional(), fact_wall_ms: z.number().int().nullable().optional(), delegated_wall_ms: z.number().int().nullable().optional()}); export const jobProgress = z.object({units_total: z.number().int().nullable().optional(), units_done: z.number().int().optional(), items_total: z.number().int().nullable().optional(), items_done: z.number().int().optional(), items_failed: z.number().int().optional(), stage: z.string().nullable().optional(), knowledge_graph: knowledgeGraphBuildProgress.nullable().optional(), routing: automaticSearchRouting.nullable().optional()}); export const classifyPageRange = z.object({start: z.number().int().gte(1), end: z.number().int().gte(1)}); export const classifyLabel = z.object({class_id: z.string(), subclass_id: z.string().nullable().optional(), label: z.string(), rank: z.number().int().gte(1), reason: z.string().nullable().optional(), confidence: z.number().nullable().optional()}); export const classifyUnit = z.object({granularity: z.enum(["document", "page"]).optional(), page_range: classifyPageRange.nullable().optional(), unknown: z.boolean(), labels: z.array(classifyLabel)}); export const classificationGapFillDisclosure = z.object({code: z.literal("classification_gap_fill"), filled_pages: z.array(z.number().int().gte(1)), fallback_label: z.string()}); export const classificationUnreadPagesDisclosure = z.object({code: z.literal("classification_unread_pages"), unread_pages: z.array(z.number().int().gte(1))}); export const extractionNullOnSuccessDisclosure = z.object({code: z.literal("extraction_null_on_success"), field_paths: z.array(z.string())}); export const parseEngine = z.enum(["native_ocr", "document_ocr", "layout_ocr"]); export const parseVendorProvenanceDisclosure = z.object({code: z.literal("parse_vendor_provenance"), engine: parseEngine, fallback_depth: z.number().int().gte(0)}); export const parseFidelityDisclosure = z.object({code: z.literal("parse_fidelity"), mode: z.enum(["reduced_resolution", "reduced_layout"]), pages: z.array(z.number().int().gte(1))}); export const truncationTarget = z.enum(["classification_input", "document_content", "spreadsheet_region", "extraction_array"]); export const truncationUnit = z.enum(["characters", "tokens", "rows", "columns", "cells", "items"]); export const contentTruncatedDisclosure = z.object({code: z.literal("content_truncated"), target: truncationTarget, unit: truncationUnit, original_size: z.number().int().gte(1), retained_size: z.number().int().gte(0)}); export const sourceIncompleteDisclosure = z.object({code: z.literal("source_incomplete"), received_bytes: z.number().int().gte(1)}); export const classifyResult = z.object({result_type: z.literal("classify").optional(), reason_status: z.enum(["pending", "complete", "failed", "not_requested"]).optional(), labels_at: z.string().nullable().optional(), units: z.array(classifyUnit), unknown_units: z.number().int().optional(), pages_read_fraction: z.number().gte(0).lte(1).optional(), warnings: z.array(z.string()).optional(), disclosures: z.array(z.discriminatedUnion("code", [classificationGapFillDisclosure, classificationUnreadPagesDisclosure, extractionNullOnSuccessDisclosure, parseVendorProvenanceDisclosure, parseFidelityDisclosure, contentTruncatedDisclosure, sourceIncompleteDisclosure])).optional()}); export const resultState = z.enum(["available", "expired", "not_retained", "cancelled", "storage_unavailable"]); export const errorCode = z.enum(["storage_connection_not_found", "storage_connection_in_use", "storage_limit_exceeded", "storage_conflict", "storage_auth_required", "storage_unavailable", "scan_required", "scan_rejected", "scan_unavailable", "invalid_request", "unsupported_file_type", "file_too_large", "invalid_schema", "invalid_sql", "invalid_path_prefix", "command_not_permitted", "batch_too_large", "domain_validation_failed", "default_label_required", "wait_required_for_zero_retention", "ledger_decision_invalid", "tenant_required", "partner_required", "workspace_not_found", "file_not_found", "job_not_found", "upload_not_found", "node_not_found", "schema_not_found", "domain_not_found", "session_not_found", "access_label_not_found", "ledger_understanding_not_found", "ledger_table_not_found", "tenant_not_found", "path_conflict", "schema_version_conflict", "access_label_name_taken", "workspace_name_taken", "access_label_in_use", "upload_expired", "file_not_ingested", "workspace_deleting", "workspace_not_deletable", "ingestion_in_progress", "job_not_cancellable", "confirmation_required", "domain_not_published", "domain_in_use", "reserved_domain_slug", "kg_not_built", "kg_build_in_progress", "ledger_understanding_in_progress", "ledger_understanding_version_outdated", "session_busy", "tenant_limit_reached", "range_not_satisfiable", "result_expired", "access_denied", "tenant_disabled", "access_backstop_violation", "access_mode_not_implemented", "rate_limited", "concurrency_limit_reached", "quota_exceeded", "corrupt_file", "zero_byte_file", "encrypted_file", "csv_dialect_ambiguous", "csv_parse_failed", "parse_failed", "ocr_failed", "conversion_failed", "sheetless_workbook", "unplayable_media", "unclassified_pages", "job_cancelled", "job_timeout", "upstream_unavailable", "internal_error", "unauthorized", "not_implemented"]); export const error = z.object({code: errorCode, message: z.string(), detail: z.record(z.string(), z.unknown()).nullable().optional(), retryable: z.boolean(), request_id: z.string().nullable().optional()}); export const costLine = z.object({operation: z.enum(["parse", "split", "classify", "extract", "ground"]), quantity: z.number().int().gte(0), unit: z.enum(["page", "item"]), execution: z.enum(["fresh", "reused"]), unit_price_usd: z.string(), amount_usd: z.string(), reuse_reason: z.enum(["reused_parse", "repeat_of_job"]).nullable().optional()}); export const jobCost = z.object({currency: z.literal("USD").optional(), pricing_version: z.string(), total_usd: z.string(), lines: z.array(costLine)}); export const usageWaiver = z.object({part: z.enum(["parse", "job"]), reason: z.enum(["reused_parse", "repeat_of_job"]), source_job_id: z.string().nullable().optional()}); export const usageLine = z.object({part: z.enum(["parse", "operation", "image_ocr"]), quantity: z.number().int().gte(0), unit: z.enum(["page", "item", "unit", "image"]), credits_per_unit: z.number().int().gte(0), multiplier: z.number().int().gte(1), credits: z.number().int().gte(0), waiver: usageWaiver.nullable().optional()}); export const jobUsage = z.object({lines: z.array(usageLine)}); export const classifyJob = z.object({job_id: z.string(), kind: z.literal("classify").optional(), status: ndiServiceAppPlatformApiContractsJobStatus, name: z.string().nullable().optional(), project_id: z.string().nullable().optional(), workspace_id: z.string().nullable().optional(), idempotency_key: z.string().nullable().optional(), force: z.boolean().nullable().optional(), source: z.union([uploadSource, urlSource, workspaceFileSource, parseResultSource]).nullable().optional(), query: z.string().nullable().optional(), query_scope: z.union([workspaceQueryScope, fileQueryScope, pathPrefixQueryScope, filesQueryScope]).nullable().optional(), effort: z.string().nullable().optional(), surface: z.enum(["deep_search", "qa", "workbook"]).nullable().optional(), progress: jobProgress.nullable().optional(), result: classifyResult.nullable().optional(), result_state: resultState.optional(), result_error: error.nullable().optional(), error: error.nullable().optional(), units: z.number().int().optional(), credits: z.number().int().nullable().optional(), usage_final: z.boolean().optional(), credit_schedule_version: z.number().int().nullable().optional(), usage_finalized_at: z.string().nullable().optional(), cost: jobCost.nullable().optional(), usage: jobUsage.nullable().optional(), created_at: z.string(), started_at: z.string().nullable().optional(), finished_at: z.string().nullable().optional(), payload_expires_at: z.string().nullable().optional(), deleted_at: z.string().nullable().optional()}); export const textRange = z.object({kind: z.literal("text_range").optional(), page: z.number().int().nullable().optional(), pages: z.array(z.number().int()).optional(), char_start: z.number().int(), char_end: z.number().int()}); export const visualRegion = z.object({kind: z.literal("visual_region").optional(), page: z.number().int(), bbox: z.array(z.unknown())}); export const spreadsheetRange = z.object({kind: z.literal("spreadsheet_range").optional(), sheet: z.string(), a1_range: z.string()}); export const jsonlRecord = z.object({kind: z.literal("jsonl_record").optional(), row_offset: z.number().int(), column: z.string().nullable().optional()}); export const jsonPointer = z.object({kind: z.literal("json_pointer").optional(), pointer: z.string()}); export const audioRange = z.object({kind: z.literal("audio_range").optional(), start_ms: z.number().int(), end_ms: z.number().int()}); export const rowRange = z.object({kind: z.literal("row_range").optional(), start_row: z.number().int().gte(0), end_row: z.number().int().gte(0), column: z.string().nullable().optional()}); export const evidence = z.object({file_id: z.string(), path: z.string(), locator: z.union([textRange, visualRegion, spreadsheetRange, jsonlRecord, jsonPointer, audioRange, rowRange]).nullable().optional(), page: z.number().int().nullable().optional(), relevance_score: z.number(), snippet: z.string(), why: z.string(), component: z.string().nullable().optional(), sql_table: z.string().nullable().optional(), line_start: z.number().int().nullable().optional(), line_end: z.number().int().nullable().optional()}); export const scoredCategory = z.object({category: z.string(), confidence: z.number()}); export const categoryAssignment = z.object({source_index: z.number().int(), file_name: z.string(), category: z.string().nullable().optional(), confidence: z.number(), evidence: evidence.nullable().optional(), alternatives: z.array(scoredCategory).optional()}); export const ndiServiceAppPlatformApiResultsCategorizeResult = z.object({result_type: z.literal("categorize").optional(), assignments: z.array(categoryAssignment), units: z.number().int(), warnings: z.array(z.string()).optional()}); export const categorizeJob = z.object({job_id: z.string(), kind: z.literal("categorize").optional(), status: ndiServiceAppPlatformApiContractsJobStatus, name: z.string().nullable().optional(), project_id: z.string().nullable().optional(), workspace_id: z.string().nullable().optional(), idempotency_key: z.string().nullable().optional(), force: z.boolean().nullable().optional(), source: z.union([uploadSource, urlSource, workspaceFileSource, parseResultSource]).nullable().optional(), query: z.string().nullable().optional(), query_scope: z.union([workspaceQueryScope, fileQueryScope, pathPrefixQueryScope, filesQueryScope]).nullable().optional(), effort: z.string().nullable().optional(), surface: z.enum(["deep_search", "qa", "workbook"]).nullable().optional(), progress: jobProgress.nullable().optional(), result: ndiServiceAppPlatformApiResultsCategorizeResult.nullable().optional(), result_state: resultState.optional(), result_error: error.nullable().optional(), error: error.nullable().optional(), units: z.number().int().optional(), credits: z.number().int().nullable().optional(), usage_final: z.boolean().optional(), credit_schedule_version: z.number().int().nullable().optional(), usage_finalized_at: z.string().nullable().optional(), cost: jobCost.nullable().optional(), usage: jobUsage.nullable().optional(), created_at: z.string(), started_at: z.string().nullable().optional(), finished_at: z.string().nullable().optional(), payload_expires_at: z.string().nullable().optional(), deleted_at: z.string().nullable().optional()}); export const createApiV1ClassifyResponse = z.union([classifyJob, categorizeJob]); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * classify * * POST /v1/classify */ export const createApiV1Classify = async (args: CreateApiV1ClassifyArgs, options: CreateApiV1ClassifyOptions) => { const {baseUrl, fetch: fetchFn = fetch, APIKeyHeader} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args.wait_seconds != null) query.append("wait_seconds", String(args.wait_seconds)) if (args['Idempotency-Key'] != null) headers.set("Idempotency-Key", String(args['Idempotency-Key'])) if (APIKeyHeader !== undefined) headers.set("X-API-Key", APIKeyHeader) const url = `${baseUrl.replace(/\/+$/, '')}/v1/classify${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(createApiV1ClassifyResponse, await res.json()) };