import {z} from 'zod' export type WorkspaceQuery = {version?: 1 | undefined, sql: string}; export type ScenarioSearch = {n_trials?: number | undefined, max_steps?: number | undefined, stop_after_improvement?: number | undefined, rescore_every?: number | undefined, reattribute_every?: number | undefined, top_k_features?: (number | null) | undefined, random_state?: (number | null) | undefined}; export type FeatureConstraintSchema = {immutable?: boolean | undefined, monotonic?: ('increase' | 'decrease' | null) | undefined, value_range?: (Array | null) | undefined, allowed_values?: (Array | null) | undefined, preserve_sign?: boolean | undefined, integer?: boolean | undefined, max_percentile_delta?: (number | null) | undefined}; export type CategoryHierarchySchema = {kind?: 'category_hierarchy' | undefined, parent: string, child: string, child_to_parent: Array>}; export type CategoryCompatibilitySchema = {kind?: 'category_compatibility' | undefined, feature: string, other: string, allowed: Array>}; export type StructuralConstraintSchema = CategoryHierarchySchema | CategoryCompatibilitySchema; export type ScenarioRequest = {dataframe: WorkspaceQuery, target_value: number, search?: ScenarioSearch | undefined, constraints?: {[key: string]: FeatureConstraintSchema} | undefined, numeric_quantiles?: Array | undefined, structural_constraints?: Array | undefined}; export type CreateApiV1ModelsModelIdScenarioArgs = {model_id: string, body: ScenarioRequest}; export type CreateApiV1ModelsModelIdScenarioOptions = {baseUrl: string, BearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const iD = z.union([z.string(), z.string()]); export const jobStatus = z.enum(["pending", "running", "completed", "failed", "cancelled"]); export const jobSubmissionResponse = z.object({job_id: iD, status: jobStatus, message: z.string()}); 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 }; /** * Scenario * * POST /v1/models/{model_id}/scenario */ export const createApiV1ModelsModelIdScenario = async (args: CreateApiV1ModelsModelIdScenarioArgs, options: CreateApiV1ModelsModelIdScenarioOptions) => { const {baseUrl, fetch: fetchFn = fetch, BearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (BearerAuth !== undefined) headers.set('authorization', `Bearer ${BearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/v1/models/${encodeURIComponent(String(args.model_id))}/scenario${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(jobSubmissionResponse, await res.json()) };