@proveanything/smartlinks 2.0.32 → 2.0.34

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/openapi.yaml CHANGED
@@ -17123,12 +17123,42 @@ components:
17123
17123
  type: number
17124
17124
  required:
17125
17125
  - imageUrl
17126
- PdfCreateArgs:
17126
+ ImageOcrArgs:
17127
17127
  type: object
17128
17128
  properties:
17129
- html:
17129
+ imageUrl:
17130
+ type: string
17131
+ url:
17132
+ type: string
17133
+ page:
17134
+ type: number
17135
+ dpi:
17136
+ type: number
17137
+ clip:
17138
+ $ref: "#/components/schemas/PdfClip"
17139
+ languages:
17140
+ type: array
17141
+ items:
17142
+ type: string
17143
+ PdfClip:
17144
+ type: object
17145
+ properties:
17146
+ x0:
17130
17147
  type: object
17131
17148
  additionalProperties: true
17149
+ required:
17150
+ - x0
17151
+ PdfCreateArgs:
17152
+ type: object
17153
+ properties:
17154
+ html:
17155
+ type: string
17156
+ format:
17157
+ type: string
17158
+ landscape:
17159
+ type: boolean
17160
+ margin:
17161
+ type: string
17132
17162
  required:
17133
17163
  - html
17134
17164
  PdfFillArgs:
@@ -17160,8 +17190,13 @@ components:
17160
17190
  type: object
17161
17191
  properties:
17162
17192
  url:
17163
- type: object
17164
- additionalProperties: true
17193
+ type: string
17194
+ page:
17195
+ type: number
17196
+ dpi:
17197
+ type: number
17198
+ clip:
17199
+ $ref: "#/components/schemas/PdfClip"
17165
17200
  required:
17166
17201
  - url
17167
17202
  PdfExtractArgs:
@@ -17237,6 +17272,8 @@ components:
17237
17272
  $ref: "#/components/schemas/ImageSearchStockArgs"
17238
17273
  image.transform:
17239
17274
  $ref: "#/components/schemas/ImageTransformArgs"
17275
+ image.ocr:
17276
+ $ref: "#/components/schemas/ImageOcrArgs"
17240
17277
  pdf.create:
17241
17278
  $ref: "#/components/schemas/PdfCreateArgs"
17242
17279
  pdf.fill:
@@ -17270,6 +17307,7 @@ components:
17270
17307
  - image.fromReference
17271
17308
  - image.searchStock
17272
17309
  - image.transform
17310
+ - image.ocr
17273
17311
  - pdf.create
17274
17312
  - pdf.fill
17275
17313
  - pdf.merge
@@ -17386,6 +17424,75 @@ components:
17386
17424
  additionalProperties: true
17387
17425
  required:
17388
17426
  - url
17427
+ PdfRenderTooLarge:
17428
+ type: object
17429
+ properties:
17430
+ error:
17431
+ type: object
17432
+ additionalProperties: true
17433
+ required:
17434
+ - error
17435
+ OcrBox:
17436
+ type: object
17437
+ properties:
17438
+ x:
17439
+ type: object
17440
+ additionalProperties: true
17441
+ required:
17442
+ - x
17443
+ OcrWord:
17444
+ type: object
17445
+ properties:
17446
+ text:
17447
+ type: object
17448
+ additionalProperties: true
17449
+ required:
17450
+ - text
17451
+ OcrLine:
17452
+ type: object
17453
+ properties:
17454
+ text:
17455
+ type: object
17456
+ additionalProperties: true
17457
+ required:
17458
+ - text
17459
+ ImageOcrResult:
17460
+ type: object
17461
+ properties:
17462
+ words:
17463
+ type: array
17464
+ items:
17465
+ $ref: "#/components/schemas/OcrWord"
17466
+ lines:
17467
+ type: array
17468
+ items:
17469
+ $ref: "#/components/schemas/OcrLine"
17470
+ text:
17471
+ type: string
17472
+ width:
17473
+ type: number
17474
+ height:
17475
+ type: number
17476
+ languages:
17477
+ type: array
17478
+ items:
17479
+ type: string
17480
+ page:
17481
+ type: number
17482
+ dpi:
17483
+ type: number
17484
+ clip:
17485
+ $ref: "#/components/schemas/PdfClip"
17486
+ engine:
17487
+ type: string
17488
+ required:
17489
+ - words
17490
+ - lines
17491
+ - text
17492
+ - width
17493
+ - height
17494
+ - languages
17495
+ - engine
17389
17496
  PdfFieldMeta:
17390
17497
  type: object
17391
17498
  properties:
@@ -17513,6 +17620,7 @@ components:
17513
17620
  - image.fromReference
17514
17621
  - image.searchStock
17515
17622
  - image.transform
17623
+ - image.ocr
17516
17624
  - pdf.create
17517
17625
  - pdf.fill
17518
17626
  - pdf.merge
@@ -848,7 +848,7 @@ export interface CatalogResponse {
848
848
  /** Capability tags a tool requires; scope a run with `allowCapabilities`. */
849
849
  export type AiToolCapability = 'web:read' | 'ai:vision' | 'ai:image' | 'ai:text' | 'media:image' | 'media:pdf' | 'net:http';
850
850
  /** The names of the built-in server-side agent tools (run via `server_tools`). */
851
- export type AiToolName = 'web.fetchPage' | 'web.extractSchema' | 'web.screenshot' | 'web.search' | 'brand.assets' | 'document.read' | 'data.extract' | 'image.describe' | 'image.generate' | 'image.fromReference' | 'image.searchStock' | 'image.transform' | 'pdf.create' | 'pdf.fill' | 'pdf.merge' | 'pdf.inspect' | 'pdf.render' | 'pdf.extract' | 'pdf.decodeBarcodes' | 'pdf.inspectGraphics' | 'http.request' | 'translate';
851
+ export type AiToolName = 'web.fetchPage' | 'web.extractSchema' | 'web.screenshot' | 'web.search' | 'brand.assets' | 'document.read' | 'data.extract' | 'image.describe' | 'image.generate' | 'image.fromReference' | 'image.searchStock' | 'image.transform' | 'image.ocr' | 'pdf.create' | 'pdf.fill' | 'pdf.merge' | 'pdf.inspect' | 'pdf.render' | 'pdf.extract' | 'pdf.decodeBarcodes' | 'pdf.inspectGraphics' | 'http.request' | 'translate';
852
852
  export interface WebFetchPageArgs {
853
853
  url: string;
854
854
  type?: string;
@@ -927,10 +927,32 @@ export interface ImageTransformArgs {
927
927
  format?: 'jpeg' | 'png' | 'webp' | 'avif';
928
928
  quality?: number;
929
929
  }
930
+ /** Deterministic OCR (Google Vision; no generative model). Give `imageUrl`, or a PDF `url` (+ page/dpi/clip). */
931
+ export interface ImageOcrArgs {
932
+ imageUrl?: string;
933
+ url?: string;
934
+ /** PDF page, 1-based (default 1). */
935
+ page?: number;
936
+ /** PDF render dpi (default 300, max 600). */
937
+ dpi?: number;
938
+ /** PDF region, normalised 0–1 from the page top-left. */
939
+ clip?: PdfClip;
940
+ /** Language hints, e.g. ['en','fr','de','es','it','nl']. Optional — auto-detected otherwise. */
941
+ languages?: string[];
942
+ }
943
+ /** A region of a PDF page, normalised 0–1 from the page's top-left corner (x1 > x0, y1 > y0). */
944
+ export interface PdfClip {
945
+ x0: number;
946
+ y0: number;
947
+ x1: number;
948
+ y1: number;
949
+ }
930
950
  export interface PdfCreateArgs {
931
951
  html: string;
932
952
  format?: string;
933
953
  landscape?: boolean;
954
+ /** Page margin for all sides, e.g. "0" or "12mm" (default 18mm/14mm). Use "0" when the HTML sets its own margins. */
955
+ margin?: string;
934
956
  }
935
957
  export interface PdfFillArgs {
936
958
  url: string;
@@ -948,7 +970,10 @@ export interface PdfInspectArgs {
948
970
  export interface PdfRenderArgs {
949
971
  url: string;
950
972
  page?: number;
973
+ /** Default 150, max 600. Renders over 40 megapixels return `code: 'too_large'` with `suggestedDpi`. */
951
974
  dpi?: number;
975
+ /** Render only this region (at the requested dpi) — read a panel of a large dieline without rasterising the whole sheet. */
976
+ clip?: PdfClip;
952
977
  }
953
978
  export interface PdfExtractArgs {
954
979
  url: string;
@@ -993,6 +1018,7 @@ export interface AiToolArgsMap {
993
1018
  'image.fromReference': ImageFromReferenceArgs;
994
1019
  'image.searchStock': ImageSearchStockArgs;
995
1020
  'image.transform': ImageTransformArgs;
1021
+ 'image.ocr': ImageOcrArgs;
996
1022
  'pdf.create': PdfCreateArgs;
997
1023
  'pdf.fill': PdfFillArgs;
998
1024
  'pdf.merge': PdfMergeArgs;
@@ -1041,7 +1067,8 @@ export interface ImageDescribeResult {
1041
1067
  }
1042
1068
  /** Result of a tool that produces a hosted binary (image.transform, pdf.*). */
1043
1069
  export interface HostedAssetResult {
1044
- hostedUrl: string | null;
1070
+ hostedUrl: string | null; /** Same as hostedUrl (pdf.create). */
1071
+ url?: string | null;
1045
1072
  contentType?: string;
1046
1073
  info?: {
1047
1074
  width?: number;
@@ -1082,6 +1109,7 @@ export interface PdfInspectResult {
1082
1109
  note: string;
1083
1110
  pages: PdfInspectPage[];
1084
1111
  }
1112
+ /** Hosted URLs are permanent (safe to pass to later tools in the same run). */
1085
1113
  export interface PdfRenderResult {
1086
1114
  url: string | null;
1087
1115
  page: number;
@@ -1089,6 +1117,52 @@ export interface PdfRenderResult {
1089
1117
  dpi: number;
1090
1118
  width: number;
1091
1119
  height: number;
1120
+ clip?: PdfClip;
1121
+ }
1122
+ /** Error shape when a render would exceed the pixel cap (pdf.render / image.ocr). */
1123
+ export interface PdfRenderTooLarge {
1124
+ error: string;
1125
+ code: 'too_large';
1126
+ requestedPixels: number;
1127
+ maxPixels: number;
1128
+ suggestedDpi: number;
1129
+ width: number;
1130
+ height: number;
1131
+ }
1132
+ /** Pixel box within the OCR'd image (top-left origin). */
1133
+ export interface OcrBox {
1134
+ x: number;
1135
+ y: number;
1136
+ w: number;
1137
+ h: number;
1138
+ }
1139
+ /** One OCR word. Punctuation is usually its own word. `confidence` is 0–1 — flag low values for review. */
1140
+ export interface OcrWord {
1141
+ text: string;
1142
+ confidence: number;
1143
+ bbox: OcrBox;
1144
+ }
1145
+ /** One OCR line, with spacing as printed; `confidence` is the mean of its words. */
1146
+ export interface OcrLine {
1147
+ text: string;
1148
+ confidence: number;
1149
+ bbox: OcrBox;
1150
+ }
1151
+ export interface ImageOcrResult {
1152
+ words: OcrWord[];
1153
+ lines: OcrLine[];
1154
+ /** Full text with line breaks. */
1155
+ text: string;
1156
+ /** Pixel size of the image that was read. */
1157
+ width: number | null;
1158
+ height: number | null;
1159
+ /** Detected languages (BCP-47). */
1160
+ languages: string[];
1161
+ /** Present when a PDF page was rendered. */
1162
+ page?: number;
1163
+ dpi?: number;
1164
+ clip?: PdfClip;
1165
+ engine: string;
1092
1166
  }
1093
1167
  /** Per-field metadata from pdf.extract when includeConfidence / includeBoxes is set. */
1094
1168
  export interface PdfFieldMeta {
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 2.0.32 | Generated: 2026-10-01T17:18:44.658Z
3
+ Version: 2.0.34 | Generated: 2026-10-02T16:06:32.154Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -1447,10 +1447,32 @@ interface ImageTransformArgs {
1447
1447
  }
1448
1448
  ```
1449
1449
 
1450
+ **ImageOcrArgs** (interface)
1451
+ ```typescript
1452
+ interface ImageOcrArgs {
1453
+ imageUrl?: string
1454
+ url?: string
1455
+ page?: number
1456
+ dpi?: number
1457
+ clip?: PdfClip
1458
+ languages?: string[]
1459
+ }
1460
+ ```
1461
+
1462
+ **PdfClip** (interface)
1463
+ ```typescript
1464
+ interface PdfClip {
1465
+ x0: number; y0: number; x1: number; y1: number
1466
+ }
1467
+ ```
1468
+
1450
1469
  **PdfCreateArgs** (interface)
1451
1470
  ```typescript
1452
1471
  interface PdfCreateArgs {
1453
- html: string; format?: string; landscape?: boolean
1472
+ html: string
1473
+ format?: string
1474
+ landscape?: boolean
1475
+ margin?: string
1454
1476
  }
1455
1477
  ```
1456
1478
 
@@ -1478,7 +1500,10 @@ interface PdfInspectArgs {
1478
1500
  **PdfRenderArgs** (interface)
1479
1501
  ```typescript
1480
1502
  interface PdfRenderArgs {
1481
- url: string; page?: number; dpi?: number
1503
+ url: string
1504
+ page?: number
1505
+ dpi?: number
1506
+ clip?: PdfClip
1482
1507
  }
1483
1508
  ```
1484
1509
 
@@ -1532,6 +1557,7 @@ interface AiToolArgsMap {
1532
1557
  'image.fromReference': ImageFromReferenceArgs
1533
1558
  'image.searchStock': ImageSearchStockArgs
1534
1559
  'image.transform': ImageTransformArgs
1560
+ 'image.ocr': ImageOcrArgs
1535
1561
  'pdf.create': PdfCreateArgs
1536
1562
  'pdf.fill': PdfFillArgs
1537
1563
  'pdf.merge': PdfMergeArgs
@@ -1590,7 +1616,7 @@ interface ImageDescribeResult {
1590
1616
  **HostedAssetResult** (interface)
1591
1617
  ```typescript
1592
1618
  interface HostedAssetResult {
1593
- hostedUrl: string | null; contentType?: string; info?: { width?: number; height?: number; format?: string; size?: number }
1619
+
1594
1620
  }
1595
1621
  ```
1596
1622
 
@@ -1625,7 +1651,51 @@ interface PdfInspectResult {
1625
1651
  **PdfRenderResult** (interface)
1626
1652
  ```typescript
1627
1653
  interface PdfRenderResult {
1628
- url: string | null; page: number; pageCount: number; dpi: number; width: number; height: number
1654
+ url: string | null; page: number; pageCount: number; dpi: number; width: number; height: number; clip?: PdfClip
1655
+ }
1656
+ ```
1657
+
1658
+ **PdfRenderTooLarge** (interface)
1659
+ ```typescript
1660
+ interface PdfRenderTooLarge {
1661
+ error: string; code: 'too_large'; requestedPixels: number; maxPixels: number; suggestedDpi: number; width: number; height: number
1662
+ }
1663
+ ```
1664
+
1665
+ **OcrBox** (interface)
1666
+ ```typescript
1667
+ interface OcrBox {
1668
+ x: number; y: number; w: number; h: number
1669
+ }
1670
+ ```
1671
+
1672
+ **OcrWord** (interface)
1673
+ ```typescript
1674
+ interface OcrWord {
1675
+ text: string; confidence: number; bbox: OcrBox
1676
+ }
1677
+ ```
1678
+
1679
+ **OcrLine** (interface)
1680
+ ```typescript
1681
+ interface OcrLine {
1682
+ text: string; confidence: number; bbox: OcrBox
1683
+ }
1684
+ ```
1685
+
1686
+ **ImageOcrResult** (interface)
1687
+ ```typescript
1688
+ interface ImageOcrResult {
1689
+ words: OcrWord[]
1690
+ lines: OcrLine[]
1691
+ text: string
1692
+ width: number | null
1693
+ height: number | null
1694
+ languages: string[]
1695
+ page?: number
1696
+ dpi?: number
1697
+ clip?: PdfClip
1698
+ engine: string
1629
1699
  }
1630
1700
  ```
1631
1701
 
package/docs/ai.md CHANGED
@@ -327,7 +327,8 @@ in `input`.
327
327
  | `pdf.fill` | Fill an AcroForm PDF's fields (`{ field: value }`) → hosted URL. |
328
328
  | `pdf.merge` | Merge several PDFs into one, in order → hosted URL. |
329
329
  | `pdf.inspect` | Cheap, no-AI introspection: page count/sizes, which pages have a real text layer, raster present, and a routing hint (`text` vs `vision`). |
330
- | `pdf.render` | Rasterize one page to a PNG at a chosen DPI → hosted image URL (feed to vision, or screenshot a page). |
330
+ | `pdf.render` | Rasterize one page — or just a region (`clip: { x0, y0, x1, y1 }`, 0–1 from top-left) — to a PNG at a chosen DPI → hosted image URL (permanent). Max 40 MP per call; larger requests return `code: "too_large"` + `suggestedDpi`. |
331
+ | `image.ocr` | **Deterministic OCR** (Google Vision, no generative model): exact characters with per-word `confidence` (0–1) and pixel `bbox`, plus lines with spacing as printed. Input: `imageUrl`, or a PDF `url` + `page` + `dpi` + optional `clip`. Optional `languages` hints. Use for small print and text outlined to curves. |
331
332
  | `pdf.extract` | PDF → typed JSON in one call (schema and/or prompt). Auto-routes text vs vision. Optional per-field `confidence`/`source` (`includeConfidence`) and `bbox` (`includeBoxes`) in `fieldsMeta`. |
332
333
  | `pdf.decodeBarcodes` | Deterministically decode barcodes/QR on a page (WASM, no AI) → value + symbology + page + bbox + confidence. Use this for barcode digits, never vision. |
333
334
  | `pdf.inspectGraphics` | Prepress inspection: per-page path/image/outlined-text counts + colour spaces, plus named SPOT colours (e.g. "PANTONE 871 C"). No AI. |
@@ -341,18 +342,36 @@ in `input`.
341
342
  returns typed JSON). It routes itself, but you can drive the route yourself: call `pdf.inspect`
342
343
  first (deterministic, no AI) to see whether each page has a real text layer, then `pdf.extract`
343
344
  (cheap text path) or `pdf.render` → `image.describe`/vision for curve-only or raster artwork.
344
- - **Zoom in on small print** (INCI/allergen lists) → `pdf.render` at a high DPI (e.g. 300), then read
345
- the PNG with vision.
345
+ - **Read small print exactly** (INCI/allergen lists, net weight, text outlined to curves) → `image.ocr`
346
+ with a PDF `url`, `page`, `dpi: 300–400` and a `clip` around the panel. It returns the characters it
347
+ sees with a per-word confidence — it never "corrects" a misspelling the way a vision model can, so
348
+ flag words below ~0.9 for human review rather than re-reading them with a model.
349
+ - **Zoom in visually** (layout, artwork) → `pdf.render` with `clip` to rasterise just a region at a high
350
+ DPI, instead of the whole sheet. Renders over 40 MP return `code: "too_large"` with `suggestedDpi`
351
+ — retry at that dpi or with a smaller clip, don't blind-retry.
346
352
  - **Barcodes / QR** → `pdf.decodeBarcodes` (deterministic WASM decode) — never trust vision for barcode
347
353
  digits; it hallucinates them.
348
354
  - **Prepress / print QA** (spot colours, colour spaces, vector vs raster) → `pdf.inspectGraphics`.
349
355
  - **A review UI that flags guessed fields** → `pdf.extract` with `includeConfidence` (per-field
350
356
  confidence + source) and `includeBoxes` (per-field bbox on text-native pages) in `fieldsMeta`.
351
357
  - **Produce a PDF** → `pdf.create` (HTML → PDF), `pdf.fill` (populate an AcroForm's fields),
352
- `pdf.merge` (combine several). These return a hosted `hostedUrl`.
358
+ `pdf.merge` (combine several). These return a hosted `hostedUrl` (`pdf.create` also returns it as
359
+ `url`). `pdf.create` loads remote `<img>` URLs before rendering and honours `page-break-inside`; pass
360
+ `margin: "0"` when your HTML sets its own body margin (default page margin is 18mm/14mm).
353
361
 
354
362
  Every tool is also directly callable without the model loop via `ai.tools.run(collectionId, name,
355
- args)` — e.g. render a page or extract fields straight from a UI, no agent round-trip.
363
+ args)` — e.g. render a page or extract fields straight from a UI, no agent round-trip:
364
+
365
+ ```ts
366
+ // Read the ingredients panel of a sleeve exactly (deterministic OCR of a clipped region)
367
+ const { result } = await SL.ai.tools.run(collectionId, 'image.ocr', {
368
+ url: sleevePdfUrl, page: 1, dpi: 400,
369
+ clip: { x0: 0.40, y0: 0.20, x1: 0.60, y1: 0.40 },
370
+ languages: ['en', 'fr'],
371
+ })
372
+ // result.lines → [{ text: 'INGREDIENTS: Aqua, Glycerin, …', confidence: 0.97, bbox: {…} }]
373
+ const toReview = result.words.filter((w) => w.confidence < 0.9)
374
+ ```
356
375
 
357
376
  Discover tools two ways:
358
377
  - **Design time (typed):** import `BUILTIN_AI_TOOLS`, `AI_TOOL_NAMES`, and the per-tool arg types
@@ -747,6 +747,39 @@ const results = await app.records.list(collectionId, appId, {
747
747
 
748
748
  > `q` is not a full-text index and does not return ranked results. For ranked relevance search over large corpora, use the Elasticsearch integration.
749
749
 
750
+ **Admin: search other data fields (`qFields`).** On the admin endpoint, `qFields` chooses which top-level `data` keys `q` searches (comma-separated, max 5; default `label`):
751
+
752
+ ```typescript
753
+ const page = await app.records.list(collectionId, appId, {
754
+ recordType: 'packaging-field',
755
+ q: 'best before',
756
+ qFields: 'value,label', // match data.value OR data.label
757
+ limit: 100, offset: 0,
758
+ }, true);
759
+ ```
760
+
761
+ ### Filtering on data fields (admin)
762
+
763
+ On the admin endpoint, `dataFilter` filters on **top-level `data` keys** — an exact match, an `in:a,b,c` list, or an array (any value matches). Up to 10 keys; combine freely with `recordType`, `status`, `q`/`qFields` and pagination:
764
+
765
+ ```typescript
766
+ const page = await app.records.list(collectionId, appId, {
767
+ recordType: 'packaging-field',
768
+ dataFilter: {
769
+ versionId: 'ver_123', // data.versionId = 'ver_123'
770
+ zone: 'in:on_pack,unclear', // data.zone is one of these
771
+ },
772
+ limit: 100, offset: 0,
773
+ }, true);
774
+
775
+ page.pagination.total // matches across all pages
776
+ page.pagination.hasMore // keep paging while true
777
+ ```
778
+
779
+ - Values are compared as text (`data->>key`); nested keys and joins aren't supported.
780
+ - `limit` is capped at **100** per page — page with `offset` while `hasMore` is true.
781
+ - `status` also accepts `in:a,b` (e.g. `status: 'in:active,draft'`).
782
+
750
783
  ### External ID / ETL Workflow
751
784
 
752
785
  `customId` and `sourceSystem` provide a stable external key pair for loading records from external systems (CMS, ERP, PIM, etc.):