visual-ai-assertions 0.7.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -18,11 +18,13 @@ declare const Provider: {
18
18
  /** Known model names grouped by provider. */
19
19
  declare const Model: {
20
20
  readonly Anthropic: {
21
+ readonly OPUS_4_7: "claude-opus-4-7";
21
22
  readonly OPUS_4_6: "claude-opus-4-6";
22
23
  readonly SONNET_4_6: "claude-sonnet-4-6";
23
24
  readonly HAIKU_4_5: "claude-haiku-4-5";
24
25
  };
25
26
  readonly OpenAI: {
27
+ readonly GPT_5_5: "gpt-5.5";
26
28
  readonly GPT_5_4: "gpt-5.4";
27
29
  readonly GPT_5_4_PRO: "gpt-5.4-pro";
28
30
  readonly GPT_5_4_MINI: "gpt-5.4-mini";
@@ -117,16 +119,24 @@ declare const StatementResultSchema: z.ZodObject<{
117
119
  pass: z.ZodBoolean;
118
120
  reasoning: z.ZodString;
119
121
  confidence: z.ZodOptional<z.ZodEnum<["high", "medium", "low"]>>;
122
+ /**
123
+ * For video inputs, the approximate timestamp (in seconds, from the start of the clip)
124
+ * of the frame that most clearly demonstrates the statement. `null` when the statement
125
+ * fails or applies across the whole clip. Always omitted for image inputs.
126
+ */
127
+ timestampSeconds: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
120
128
  }, "strip", z.ZodTypeAny, {
121
129
  statement: string;
122
130
  pass: boolean;
123
131
  reasoning: string;
124
132
  confidence?: "high" | "medium" | "low" | undefined;
133
+ timestampSeconds?: number | null | undefined;
125
134
  }, {
126
135
  statement: string;
127
136
  pass: boolean;
128
137
  reasoning: string;
129
138
  confidence?: "high" | "medium" | "low" | undefined;
139
+ timestampSeconds?: number | null | undefined;
130
140
  }>;
131
141
  /** Outcome of a single statement evaluated by `check()`. */
132
142
  type StatementResult = z.infer<typeof StatementResultSchema>;
@@ -153,7 +163,14 @@ declare const UsageInfoSchema: z.ZodObject<{
153
163
  }>;
154
164
  /** Token usage and optional cost/latency metadata for a provider call. */
155
165
  type UsageInfo = z.infer<typeof UsageInfoSchema>;
156
- /** Zod schema for results returned by `check()` and template helpers. */
166
+ /**
167
+ * Zod schema for results returned by `check()` and template helpers.
168
+ *
169
+ * Note: the runtime `CheckResult` TypeScript type extends this schema with
170
+ * an optional `frames` field that is populated client-side for video inputs.
171
+ * Parsing a stored `CheckResult` through this schema will silently drop
172
+ * `frames` because the schema only describes what the model returns.
173
+ */
157
174
  declare const CheckResultSchema: z.ZodObject<{
158
175
  pass: z.ZodBoolean;
159
176
  reasoning: z.ZodString;
@@ -199,16 +216,24 @@ declare const CheckResultSchema: z.ZodObject<{
199
216
  pass: z.ZodBoolean;
200
217
  reasoning: z.ZodString;
201
218
  confidence: z.ZodOptional<z.ZodEnum<["high", "medium", "low"]>>;
219
+ /**
220
+ * For video inputs, the approximate timestamp (in seconds, from the start of the clip)
221
+ * of the frame that most clearly demonstrates the statement. `null` when the statement
222
+ * fails or applies across the whole clip. Always omitted for image inputs.
223
+ */
224
+ timestampSeconds: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
202
225
  }, "strip", z.ZodTypeAny, {
203
226
  statement: string;
204
227
  pass: boolean;
205
228
  reasoning: string;
206
229
  confidence?: "high" | "medium" | "low" | undefined;
230
+ timestampSeconds?: number | null | undefined;
207
231
  }, {
208
232
  statement: string;
209
233
  pass: boolean;
210
234
  reasoning: string;
211
235
  confidence?: "high" | "medium" | "low" | undefined;
236
+ timestampSeconds?: number | null | undefined;
212
237
  }>, "many">;
213
238
  }, "strip", z.ZodTypeAny, {
214
239
  issues: {
@@ -224,6 +249,7 @@ declare const CheckResultSchema: z.ZodObject<{
224
249
  pass: boolean;
225
250
  reasoning: string;
226
251
  confidence?: "high" | "medium" | "low" | undefined;
252
+ timestampSeconds?: number | null | undefined;
227
253
  }[];
228
254
  usage?: {
229
255
  inputTokens: number;
@@ -246,6 +272,7 @@ declare const CheckResultSchema: z.ZodObject<{
246
272
  pass: boolean;
247
273
  reasoning: string;
248
274
  confidence?: "high" | "medium" | "low" | undefined;
275
+ timestampSeconds?: number | null | undefined;
249
276
  }[];
250
277
  usage?: {
251
278
  inputTokens: number;
@@ -255,8 +282,23 @@ declare const CheckResultSchema: z.ZodObject<{
255
282
  durationSeconds?: number | undefined;
256
283
  } | undefined;
257
284
  }>;
285
+ /**
286
+ * Metadata describing the sampled-frame timeline used when the input was a video.
287
+ * Populated client-side; not part of the model's response.
288
+ */
289
+ interface VideoFramesMetadata {
290
+ /** Total number of frames sampled from the video. */
291
+ count: number;
292
+ /** Timestamp (seconds, from the start of the clip) of each sampled frame, in order. */
293
+ timestampsSeconds: number[];
294
+ /** Total duration of the source video in seconds. */
295
+ durationSeconds: number;
296
+ }
258
297
  /** Result returned by `check()` and the template convenience methods. */
259
- type CheckResult = z.infer<typeof CheckResultSchema>;
298
+ type CheckResult = z.infer<typeof CheckResultSchema> & {
299
+ /** Present only when the input was a video. Describes which frames the model saw. */
300
+ frames?: VideoFramesMetadata;
301
+ };
260
302
  /** Zod schema for an individual visual change reported by `compare()`. */
261
303
  declare const ChangeEntrySchema: z.ZodObject<{
262
304
  description: z.ZodString;
@@ -338,7 +380,14 @@ declare const CompareResultSchema: z.ZodObject<{
338
380
  type CompareResult = z.infer<typeof CompareResultSchema> & {
339
381
  diffImage?: DiffImageResult;
340
382
  };
341
- /** Zod schema for results returned by `ask()`. */
383
+ /**
384
+ * Zod schema for results returned by `ask()`.
385
+ *
386
+ * Note: the runtime `AskResult` TypeScript type extends this schema with an
387
+ * optional `frames` field that is populated client-side for video inputs.
388
+ * Parsing a stored `AskResult` through this schema will silently drop
389
+ * `frames` because the schema only describes what the model returns.
390
+ */
342
391
  declare const AskResultSchema: z.ZodObject<{
343
392
  summary: z.ZodString;
344
393
  issues: z.ZodArray<z.ZodObject<{
@@ -357,6 +406,11 @@ declare const AskResultSchema: z.ZodObject<{
357
406
  description: string;
358
407
  suggestion: string;
359
408
  }>, "many">;
409
+ /**
410
+ * For video inputs, the indices of frames the model relied on to answer.
411
+ * Indices are 0-based and refer to entries in `frames.timestampsSeconds`.
412
+ */
413
+ frameReferences: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
360
414
  usage: z.ZodOptional<z.ZodObject<{
361
415
  inputTokens: z.ZodNumber;
362
416
  outputTokens: z.ZodNumber;
@@ -392,6 +446,7 @@ declare const AskResultSchema: z.ZodObject<{
392
446
  estimatedCost?: number | undefined;
393
447
  durationSeconds?: number | undefined;
394
448
  } | undefined;
449
+ frameReferences?: number[] | undefined;
395
450
  }, {
396
451
  issues: {
397
452
  priority: "critical" | "major" | "minor";
@@ -407,13 +462,25 @@ declare const AskResultSchema: z.ZodObject<{
407
462
  estimatedCost?: number | undefined;
408
463
  durationSeconds?: number | undefined;
409
464
  } | undefined;
465
+ frameReferences?: number[] | undefined;
410
466
  }>;
411
467
  /** Result returned by `ask()`. */
412
- type AskResult = z.infer<typeof AskResultSchema>;
468
+ type AskResult = z.infer<typeof AskResultSchema> & {
469
+ /** Present only when the input was a video. Describes which frames the model saw. */
470
+ frames?: VideoFramesMetadata;
471
+ };
413
472
  /** Supported input shapes for image arguments accepted by the client. */
414
473
  type ImageInput = Buffer | Uint8Array | string;
474
+ /**
475
+ * Supported input shapes for media arguments accepted by the client.
476
+ * Identical to `ImageInput` today — the client auto-detects whether the bytes are
477
+ * an image or a video.
478
+ */
479
+ type MediaInput = ImageInput;
415
480
  /** Supported image MIME types accepted by all providers. */
416
481
  type SupportedMimeType = "image/jpeg" | "image/png" | "image/webp" | "image/gif";
482
+ /** Supported video MIME types the client can accept and sample frames from. */
483
+ type SupportedVideoMimeType = "video/mp4" | "video/webm" | "video/quicktime" | "video/x-matroska";
417
484
  /** Supported provider identifiers. */
418
485
  type ProviderName = "anthropic" | "openai" | "google";
419
486
  /**
@@ -443,10 +510,20 @@ interface VisualAIConfig {
443
510
  /** Optional instructions for `check()`. */
444
511
  interface CheckOptions {
445
512
  instructions?: readonly string[];
513
+ /**
514
+ * Frame-sampling configuration applied when the input is a video.
515
+ * Ignored for image inputs. See `VideoSamplingOptions` for defaults.
516
+ */
517
+ video?: VideoSamplingOptions;
446
518
  }
447
519
  /** Optional instructions for `ask()`. */
448
520
  interface AskOptions {
449
521
  instructions?: readonly string[];
522
+ /**
523
+ * Frame-sampling configuration applied when the input is a video.
524
+ * Ignored for image inputs. See `VideoSamplingOptions` for defaults.
525
+ */
526
+ video?: VideoSamplingOptions;
450
527
  }
451
528
  /** Metadata and binary content for an AI-generated diff image. */
452
529
  interface DiffImageResult {
@@ -485,6 +562,42 @@ interface ContentOptions {
485
562
  checks?: ContentCheckName[];
486
563
  instructions?: readonly string[];
487
564
  }
565
+ /** Internal normalized image representation passed to provider drivers. */
566
+ interface NormalizedImage {
567
+ readonly data: Buffer;
568
+ readonly mimeType: SupportedMimeType;
569
+ readonly base64: string;
570
+ }
571
+ /**
572
+ * Options for sampling frames from a video input. Defaults match the v1
573
+ * sampling strategy: 1 fps, capped at 10 frames, max duration 10 s.
574
+ */
575
+ interface VideoSamplingOptions {
576
+ /** Sampling rate in frames per second. Default `1`. */
577
+ fps?: number;
578
+ /**
579
+ * Maximum number of frames extracted regardless of duration. Default `10`.
580
+ * Hard-capped at `60` to keep memory bounded; values above the cap throw
581
+ * `VisualAIVideoError`.
582
+ */
583
+ maxFrames?: number;
584
+ /**
585
+ * Maximum video duration accepted, in seconds. Videos longer than this
586
+ * cause `VisualAIVideoError` to be thrown before any provider call.
587
+ * Default `10`.
588
+ */
589
+ maxDurationSeconds?: number;
590
+ }
591
+ /**
592
+ * A single frame extracted from a video input. Identical in shape to
593
+ * `NormalizedImage` so it can be passed transparently to provider drivers.
594
+ */
595
+ interface Frame extends NormalizedImage {
596
+ /** 0-based timestamp (seconds, from the start of the clip) of this frame. */
597
+ readonly timestampSeconds: number;
598
+ /** 0-based index of this frame within the sampled sequence. */
599
+ readonly index: number;
600
+ }
488
601
 
489
602
  /**
490
603
  * High-level client for running visual checks against screenshots or other images.
@@ -497,14 +610,22 @@ interface ContentOptions {
497
610
  */
498
611
  interface VisualAIClient {
499
612
  /**
500
- * Verifies one or more statements against a single image.
613
+ * Verifies one or more statements against a single image or video.
501
614
  *
502
- * @param image Image source as a buffer, URL, file path, or base64 string.
503
- * @param statements One or more statements to validate against the image.
504
- * @param options Optional additional instructions appended to the prompt.
615
+ * Pass an image (PNG/JPEG/WebP/GIF) for a single-frame check. Pass a video
616
+ * (MP4/WebM/MOV/MKV file path, URL, base64, Buffer) and the client samples
617
+ * frames automatically; statements pass if they are true at any sampled
618
+ * frame, and each statement result includes the timestamp where it
619
+ * matched. The `frames` metadata on the result reports which timestamps
620
+ * the model saw.
621
+ *
622
+ * @param input Image or video source as a buffer, URL, file path, or base64 string.
623
+ * @param statements One or more statements to validate against the input.
624
+ * @param options Optional additional instructions and video sampling overrides.
505
625
  * @returns A structured result describing pass/fail, issues, and statement reasoning.
506
626
  * @throws {VisualAIConfigError} When no statements are provided.
507
- * @throws {VisualAIImageError} When the image cannot be loaded or decoded.
627
+ * @throws {VisualAIImageError} When an image input cannot be loaded or decoded.
628
+ * @throws {VisualAIVideoError} When a video input cannot be loaded, exceeds the duration cap, or ffmpeg is missing.
508
629
  * @throws {VisualAIError} When the provider rejects the request or returns invalid output.
509
630
  * @example
510
631
  * ```ts
@@ -513,23 +634,35 @@ interface VisualAIClient {
513
634
  * "There is no error banner",
514
635
  * ]);
515
636
  * ```
637
+ * @example
638
+ * ```ts
639
+ * const result = await client.check("./recording.webm", [
640
+ * 'A success toast with text "Saved" briefly appears',
641
+ * ]);
642
+ * console.log(result.statements[0].timestampSeconds); // e.g. 3.5
643
+ * ```
516
644
  */
517
- check(image: ImageInput, statements: string | string[], options?: CheckOptions): Promise<CheckResult>;
645
+ check(input: MediaInput, statements: string | string[], options?: CheckOptions): Promise<CheckResult>;
518
646
  /**
519
- * Asks an open-ended question about an image and returns a structured summary.
647
+ * Asks an open-ended question about an image or video and returns a structured summary.
520
648
  *
521
- * @param image Image source as a buffer, URL, file path, or base64 string.
522
- * @param prompt Prompt describing what to inspect in the image.
523
- * @param options Optional additional instructions appended to the prompt.
649
+ * Video inputs are sampled into frames and analyzed as a chronological
650
+ * timeline. The result's `frameReferences` array surfaces which frames the
651
+ * model relied on for its answer.
652
+ *
653
+ * @param input Image or video source as a buffer, URL, file path, or base64 string.
654
+ * @param prompt Prompt describing what to inspect in the input.
655
+ * @param options Optional additional instructions and video sampling overrides.
524
656
  * @returns A summary with any detected issues.
525
- * @throws {VisualAIImageError} When the image cannot be loaded or decoded.
657
+ * @throws {VisualAIImageError} When an image input cannot be loaded or decoded.
658
+ * @throws {VisualAIVideoError} When a video input cannot be loaded, exceeds the duration cap, or ffmpeg is missing.
526
659
  * @throws {VisualAIError} When the provider rejects the request or returns invalid output.
527
660
  * @example
528
661
  * ```ts
529
662
  * const result = await client.ask(screenshot, "What looks visually broken on this page?");
530
663
  * ```
531
664
  */
532
- ask(image: ImageInput, prompt: string, options?: AskOptions): Promise<AskResult>;
665
+ ask(input: MediaInput, prompt: string, options?: AskOptions): Promise<AskResult>;
533
666
  /**
534
667
  * Compares two images and reports meaningful visual differences.
535
668
  *
@@ -550,7 +683,8 @@ interface VisualAIClient {
550
683
  */
551
684
  compare(imageA: ImageInput, imageB: ImageInput, options?: CompareOptions): Promise<CompareResult>;
552
685
  /**
553
- * Checks that the listed elements are visible in an image.
686
+ * Checks that the listed elements are visible in an image. Image input only —
687
+ * template helpers do not accept video input; use `check()` for video.
554
688
  *
555
689
  * @param image Image source as a buffer, URL, file path, or base64 string.
556
690
  * @param elements Element descriptions that should be present and visible.
@@ -566,7 +700,8 @@ interface VisualAIClient {
566
700
  */
567
701
  elementsVisible(image: ImageInput, elements: string[], options?: ElementsVisibilityOptions): Promise<CheckResult>;
568
702
  /**
569
- * Checks that the listed elements are not visible in an image.
703
+ * Checks that the listed elements are not visible in an image. Image input
704
+ * only — template helpers do not accept video input; use `check()` for video.
570
705
  *
571
706
  * @param image Image source as a buffer, URL, file path, or base64 string.
572
707
  * @param elements Element descriptions that should be absent or hidden.
@@ -582,7 +717,8 @@ interface VisualAIClient {
582
717
  */
583
718
  elementsHidden(image: ImageInput, elements: string[], options?: ElementsVisibilityOptions): Promise<CheckResult>;
584
719
  /**
585
- * Runs the built-in accessibility template against an image.
720
+ * Runs the built-in accessibility template against an image. Image input
721
+ * only — template helpers do not accept video input.
586
722
  *
587
723
  * @param image Image source as a buffer, URL, file path, or base64 string.
588
724
  * @param options Optional checks and extra instructions for the accessibility prompt.
@@ -596,7 +732,8 @@ interface VisualAIClient {
596
732
  */
597
733
  accessibility(image: ImageInput, options?: AccessibilityOptions): Promise<CheckResult>;
598
734
  /**
599
- * Runs the built-in layout template against an image.
735
+ * Runs the built-in layout template against an image. Image input only —
736
+ * template helpers do not accept video input.
600
737
  *
601
738
  * @param image Image source as a buffer, URL, file path, or base64 string.
602
739
  * @param options Optional checks and extra instructions for the layout prompt.
@@ -610,7 +747,8 @@ interface VisualAIClient {
610
747
  */
611
748
  layout(image: ImageInput, options?: LayoutOptions): Promise<CheckResult>;
612
749
  /**
613
- * Runs the built-in page-load template against an image.
750
+ * Runs the built-in page-load template against an image. Image input only —
751
+ * template helpers do not accept video input.
614
752
  *
615
753
  * @param image Image source as a buffer, URL, file path, or base64 string.
616
754
  * @param options Optional page-load expectations and extra instructions.
@@ -624,7 +762,8 @@ interface VisualAIClient {
624
762
  */
625
763
  pageLoad(image: ImageInput, options?: PageLoadOptions): Promise<CheckResult>;
626
764
  /**
627
- * Runs the built-in content template against an image.
765
+ * Runs the built-in content template against an image. Image input only —
766
+ * template helpers do not accept video input.
628
767
  *
629
768
  * @param image Image source as a buffer, URL, file path, or base64 string.
630
769
  * @param options Optional content checks and extra instructions.
@@ -672,7 +811,7 @@ declare function visualAI(config?: VisualAIConfig): VisualAIClient;
672
811
  /**
673
812
  * Discrete error codes exposed by visual-ai-assertions for programmatic handling.
674
813
  */
675
- type VisualAIErrorCode = "VISUAL_AI_ERROR" | "AUTH_FAILED" | "RATE_LIMITED" | "PROVIDER_ERROR" | "IMAGE_INVALID" | "RESPONSE_PARSE_FAILED" | "RESPONSE_TRUNCATED" | "CONFIG_INVALID" | "ASSERTION_FAILED";
814
+ type VisualAIErrorCode = "VISUAL_AI_ERROR" | "AUTH_FAILED" | "RATE_LIMITED" | "PROVIDER_ERROR" | "IMAGE_INVALID" | "VIDEO_INVALID" | "RESPONSE_PARSE_FAILED" | "RESPONSE_TRUNCATED" | "CONFIG_INVALID" | "ASSERTION_FAILED";
676
815
  /**
677
816
  * Base class for all library errors.
678
817
  *
@@ -745,6 +884,20 @@ declare class VisualAIImageError extends VisualAIError<"IMAGE_INVALID"> {
745
884
  readonly code: "IMAGE_INVALID";
746
885
  constructor(message: string);
747
886
  }
887
+ /**
888
+ * Thrown when a video input cannot be loaded, decoded, or sampled — including
889
+ * when the optional ffmpeg peer dependencies are missing, the source is corrupt,
890
+ * or the duration exceeds the configured cap.
891
+ *
892
+ * @example
893
+ * ```ts
894
+ * throw new VisualAIVideoError("Video duration 14.2s exceeds limit of 10s");
895
+ * ```
896
+ */
897
+ declare class VisualAIVideoError extends VisualAIError<"VIDEO_INVALID"> {
898
+ readonly code: "VIDEO_INVALID";
899
+ constructor(message: string);
900
+ }
748
901
  /**
749
902
  * Thrown when a provider response cannot be parsed into the library result schema.
750
903
  *
@@ -807,7 +960,7 @@ declare class VisualAIAssertionError extends VisualAIError<"ASSERTION_FAILED"> {
807
960
  /**
808
961
  * Union of all concrete error subclasses exposed by the library.
809
962
  */
810
- type VisualAIKnownError = VisualAIAuthError | VisualAIRateLimitError | VisualAIProviderError | VisualAIImageError | VisualAIResponseParseError | VisualAITruncationError | VisualAIConfigError | VisualAIAssertionError;
963
+ type VisualAIKnownError = VisualAIAuthError | VisualAIRateLimitError | VisualAIProviderError | VisualAIImageError | VisualAIVideoError | VisualAIResponseParseError | VisualAITruncationError | VisualAIConfigError | VisualAIAssertionError;
811
964
  /**
812
965
  * Narrows an unknown thrown value to the concrete visual-ai-assertions error union.
813
966
  *
@@ -886,4 +1039,4 @@ declare function assertVisualResult(result: CheckResult, label?: string): void;
886
1039
  */
887
1040
  declare function assertVisualCompareResult(result: CompareResult, label?: string): void;
888
1041
 
889
- export { Accessibility, type AccessibilityCheckName, type AccessibilityOptions, type AskOptions, type AskResult, AskResultSchema, type ChangeEntry, ChangeEntrySchema, type CheckOptions, type CheckResult, CheckResultSchema, type CompareOptions, type CompareResult, CompareResultSchema, type Confidence, ConfidenceSchema, Content, type ContentCheckName, type ContentOptions, DEFAULT_MODELS, type DiffImageResult, type ElementsVisibilityOptions, type ImageInput, type Issue, type IssueCategory, IssueCategorySchema, type IssuePriority, IssuePrioritySchema, IssueSchema, type KnownModelName, Layout, type LayoutCheckName, type LayoutOptions, Model, type PageLoadOptions, Provider, type ProviderName, ReasoningEffort, type ReasoningEffortLevel, type StatementResult, StatementResultSchema, type SupportedMimeType, type UsageInfo, UsageInfoSchema, VisualAIAssertionError, VisualAIAuthError, type VisualAIClient, type VisualAIConfig, VisualAIConfigError, VisualAIError, type VisualAIErrorCode, VisualAIImageError, type VisualAIKnownError, VisualAIProviderError, VisualAIRateLimitError, VisualAIResponseParseError, VisualAITruncationError, assertVisualCompareResult, assertVisualResult, formatCheckResult, formatCompareResult, isVisualAIKnownError, visualAI };
1042
+ export { Accessibility, type AccessibilityCheckName, type AccessibilityOptions, type AskOptions, type AskResult, AskResultSchema, type ChangeEntry, ChangeEntrySchema, type CheckOptions, type CheckResult, CheckResultSchema, type CompareOptions, type CompareResult, CompareResultSchema, type Confidence, ConfidenceSchema, Content, type ContentCheckName, type ContentOptions, DEFAULT_MODELS, type DiffImageResult, type ElementsVisibilityOptions, type Frame, type ImageInput, type Issue, type IssueCategory, IssueCategorySchema, type IssuePriority, IssuePrioritySchema, IssueSchema, type KnownModelName, Layout, type LayoutCheckName, type LayoutOptions, type MediaInput, Model, type PageLoadOptions, Provider, type ProviderName, ReasoningEffort, type ReasoningEffortLevel, type StatementResult, StatementResultSchema, type SupportedMimeType, type SupportedVideoMimeType, type UsageInfo, UsageInfoSchema, type VideoFramesMetadata, type VideoSamplingOptions, VisualAIAssertionError, VisualAIAuthError, type VisualAIClient, type VisualAIConfig, VisualAIConfigError, VisualAIError, type VisualAIErrorCode, VisualAIImageError, type VisualAIKnownError, VisualAIProviderError, VisualAIRateLimitError, VisualAIResponseParseError, VisualAITruncationError, VisualAIVideoError, assertVisualCompareResult, assertVisualResult, formatCheckResult, formatCompareResult, isVisualAIKnownError, visualAI };