import {z} from 'zod' export type BrowserIdentity = {device_id: string, session_id?: (number | null) | undefined, arrival_id?: (string | null) | undefined}; export type AgentLinkSubject = {product: 'flight' | 'hotel', page: string, page_key: string, url_sha256?: (string | null) | undefined, token_sha256?: (string | null) | undefined, fare_index?: (number | null) | undefined, request_id?: (string | null) | undefined, session_id?: (string | null) | undefined, trip_reference?: (string | null) | undefined, observation_id?: (string | null) | undefined, quote_id?: (string | null) | undefined, hotel_id?: (number | null) | undefined, room_key?: (string | null) | undefined}; export type AgentLinkFeedback = {scope: 'product' | 'results', reason: 'poor_fit' | 'better_elsewhere' | 'missing_information' | 'product_issue'}; export type AgentHandoffTarget = {product: 'flight' | 'hotel', page_key: string, url_sha256: string, kind: 'flight_review' | 'hotel_review' | 'saved_trip' | 'results' | 'other', pricing?: ('priced_selection' | 'incomplete' | 'unknown') | undefined, quote_id?: (string | null) | undefined, trip_reference?: (string | null) | undefined, session_id?: (string | null) | undefined, fare_index?: (number | null) | undefined, token_sha256?: (string | null) | undefined}; export type AgentLinkHandoff = {evidence: 'agent_reported' | 'browser_opened', target: AgentHandoffTarget, utm_source?: (string | null) | undefined, utm_medium?: (string | null) | undefined}; export type AgentLinkTransition = {version?: 1 | undefined, subject: AgentLinkSubject, action: 'return' | 'navigate', destination: string, feedback?: (AgentLinkFeedback | null) | undefined, handoff?: (AgentLinkHandoff | null) | undefined}; export type FlightLinkProvenance = {version: 1, evidence: 'signed_source_page', source_page: string, link_kind: 'dated_page' | 'live_search'}; export type DiscoveryHit = {type: 'discovery_hit', request_id: string, occurred_at?: (string | null) | undefined, utm_source?: (string | null) | undefined, browser?: (BrowserIdentity | null) | undefined, user_id?: (string | null) | undefined, proxy_outcome?: ('pass_through' | 'redirect' | 'rewrite' | 'rejected' | 'error' | null) | undefined, proxy_status?: (number | null) | undefined, transition?: (AgentLinkTransition | null) | undefined, link_provenance?: (FlightLinkProvenance | null) | undefined, host: string, path: string, page_revision?: (string | null) | undefined, navigation?: {[key: string]: string} | undefined, method: 'GET' | 'HEAD', user_agent: string, fetcher: 'chatgpt' | 'claude' | 'perplexity' | 'google' | 'muse' | 'mcp' | 'crawler' | 'unknown', sampling_rate?: number | undefined, referrer_host?: (string | null) | undefined, prefetch: boolean, rsc: boolean, count_as_page_fetch: boolean, viewer?: ('assistant' | 'person' | null) | undefined}; export type BrowserPageSignal = {type: 'browser_page_signal', version?: 1 | undefined, request_id: string, page_id: string, occurred_at: string, browser: BrowserIdentity, user_id?: (string | null) | undefined, host: string, path: string, fetcher: 'chatgpt' | 'claude' | 'perplexity' | 'google' | 'muse' | 'mcp' | 'crawler' | 'unknown', page_revision?: (string | null) | undefined, event: 'rendered' | 'form_interacted' | 'form_submitted' | 'handoff_succeeded' | 'handoff_failed'}; export type CreateApiConvFlightCheckSignalsArgs = {authorization?: (string | null) | undefined, body: DiscoveryHit | BrowserPageSignal}; export type CreateApiConvFlightCheckSignalsOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const flightCheckSignalRecorded = z.object({recorded: z.boolean()}); 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 }; /** * Record Discovery Hit * * POST /conv/flight-check-signals */ export const createApiConvFlightCheckSignals = async (args: CreateApiConvFlightCheckSignalsArgs, options: CreateApiConvFlightCheckSignalsOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args.authorization != null) headers.set("authorization", String(args.authorization)) const url = `${baseUrl.replace(/\/+$/, '')}/conv/flight-check-signals${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(flightCheckSignalRecorded, await res.json()) };