@dotcms/client 1.1.1 → 1.2.0-next.10

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/README.md CHANGED
@@ -19,6 +19,7 @@ The `@dotcms/client` is a powerful JavaScript/TypeScript SDK designed to simplif
19
19
 
20
20
  > **📋 Migration Guides:**
21
21
  > - **From Alpha Version?** If you're upgrading from the alpha version of `@dotcms/client`, please see our [Migration Guide](./MIGRATION.md) for step-by-step instructions.
22
+ > - **From v1.2.x to v1.3.0?** See the [Changelog](#v130) section below for new AI Search API features.
22
23
  > - **From v1.0.x to v1.1.1?** See the [Changelog](#v111) section below for new features and improvements.
23
24
 
24
25
  ## Table of Contents
@@ -31,6 +32,7 @@ The `@dotcms/client` is a powerful JavaScript/TypeScript SDK designed to simplif
31
32
  - [How-to Guides](#how-to-guides)
32
33
  - [How to Fetch Complete Pages](#how-to-fetch-complete-pages)
33
34
  - [How to Query Content Collections](#how-to-query-content-collections)
35
+ - [How to Use AI-Powered Search](#how-to-use-ai-powered-search)
34
36
  - [How to Work with GraphQL](#how-to-work-with-graphql)
35
37
  - [How to Use with TypeScript](#how-to-use-with-typescript)
36
38
  - [How to Enable Page Editing](#how-to-enable-page-editing)
@@ -39,17 +41,18 @@ The `@dotcms/client` is a powerful JavaScript/TypeScript SDK designed to simplif
39
41
  - [HTTP Client Configuration](#http-client-configuration)
40
42
  - [page.get() Method](#pageget-method)
41
43
  - [content.getCollection() Method](#contentgetcollection-method)
44
+ - [ai.search() Method](#aisearch-method)
42
45
  - [navigation.get() Method](#navigationget-method)
43
46
  - [Error Handling](#error-handling)
44
47
  - [Concepts & Architecture](#concepts--architecture)
45
48
  - [Key Concepts](#key-concepts)
46
49
  - [Choosing the Right Method](#choosing-the-right-method)
47
50
  - [Architecture Overview](#architecture-overview)
48
- - [Support & Contributing](#support--contributing)
49
- - [dotCMS Support](#dotcms-support)
50
- - [How To Contribute](#how-to-contribute)
51
- - [Licensing Information](#licensing-information)
51
+ - [Support](#support)
52
+ - [Contributing](#contributing)
53
+ - [Licensing](#licensing)
52
54
  - [Changelog](#changelog)
55
+ - [v1.3.0](#v130)
53
56
  - [v1.1.1](#v111)
54
57
 
55
58
  ## Getting Started
@@ -215,6 +218,352 @@ const products = await client.content
215
218
  .limit(10);
216
219
  ```
217
220
 
221
+ ### How to Use AI-Powered Search
222
+
223
+ > [!WARNING]
224
+ > **Experimental Feature:** The AI API is currently experimental and may undergo breaking changes in future releases. Use with caution in production environments.
225
+
226
+ The `client.ai.search()` method enables semantic search using AI embeddings to find content based on meaning rather than exact keyword matches.
227
+
228
+ #### Prerequisites
229
+
230
+ Before using AI-powered search, ensure your dotCMS instance is properly configured:
231
+
232
+ > [!IMPORTANT]
233
+ > **Required Setup:**
234
+ > 1. **dotAI must be activated** in your dotCMS instance
235
+ > 2. **OpenAI API Key** must be configured in dotCMS
236
+ > 3. **PostgreSQL 15+ with pgvector extension** must be installed
237
+ > 4. **Content indexes** must be created and configured in dotAI
238
+ >
239
+ > For detailed setup instructions, see the [dotCMS dotAI documentation](https://dev.dotcms.com/docs/dotai).
240
+
241
+ #### Basic AI Search
242
+ ```typescript
243
+ // Search for content semantically related to your query
244
+ const response = await client.ai.search(
245
+ 'articles about machine learning',
246
+ 'content_index'
247
+ );
248
+ console.log(response.results);
249
+ ```
250
+
251
+ #### Customizing Search Parameters
252
+ ```typescript
253
+ // Fine-tune search with query parameters
254
+ const response = await client.ai.search(
255
+ 'artificial intelligence tutorials',
256
+ 'content_index',
257
+ {
258
+ query: {
259
+ limit: 20,
260
+ offset: 0,
261
+ contentType: 'BlogPost',
262
+ languageId: '1'
263
+ }
264
+ }
265
+ );
266
+ ```
267
+
268
+ #### Adjusting AI Configuration
269
+ ```typescript
270
+ import { DISTANCE_FUNCTIONS } from '@dotcms/types';
271
+
272
+ // Customize AI search behavior with threshold and distance function
273
+ const response = await client.ai.search(
274
+ 'deep learning concepts',
275
+ 'content_index',
276
+ {
277
+ config: {
278
+ threshold: 0.75, // Higher threshold = more relevant results
279
+ distanceFunction: DISTANCE_FUNCTIONS.cosine, // Distance calculation method
280
+ responseLength: 2048 // Maximum response length
281
+ }
282
+ }
283
+ );
284
+ ```
285
+
286
+ #### Complete Example with All Options
287
+ ```typescript
288
+ // Combine query and AI parameters for precise control
289
+ const response = await client.ai.search(
290
+ 'best practices for content management',
291
+ 'articles_index',
292
+ {
293
+ query: {
294
+ limit: 10,
295
+ offset: 0,
296
+ contentType: 'Article',
297
+ languageId: '1',
298
+ siteId: 'my-site'
299
+ },
300
+ config: {
301
+ threshold: 0.8,
302
+ distanceFunction: DISTANCE_FUNCTIONS.innerProduct,
303
+ responseLength: 1024
304
+ }
305
+ }
306
+ );
307
+
308
+ // Access results with match scores
309
+ resp[onse].results.forEach(result => {
310
+ console.log(result.title);
311
+ console.log('Matches:', result.matches); // Distance and extracted text
312
+ });
313
+ ```
314
+
315
+ #### Understanding Distance Functions
316
+
317
+ The SDK supports multiple distance functions for vector similarity:
318
+
319
+ ```typescript
320
+ import { DISTANCE_FUNCTIONS } from '@dotcms/types';
321
+
322
+ // Available distance functions:
323
+ DISTANCE_FUNCTIONS.cosine // '<=>' - Cosine similarity (default)
324
+ DISTANCE_FUNCTIONS.innerProduct // '<#>' - Inner product similarity
325
+ DISTANCE_FUNCTIONS.L2 // '<->' - Euclidean distance
326
+ DISTANCE_FUNCTIONS.L1 // '<+>' - Manhattan distance
327
+ DISTANCE_FUNCTIONS.hamming // '<~>' - Hamming distance
328
+ DISTANCE_FUNCTIONS.jaccard // '<%>' - Jaccard similarity
329
+ ```
330
+
331
+ ### How to Use with TypeScript
332
+
333
+ The SDK is built with TypeScript and provides comprehensive type definitions through the `@dotcms/types` package for enhanced developer experience and type safety.
334
+
335
+ #### Basic Type Usage
336
+
337
+ ```typescript
338
+ import { createDotCMSClient } from '@dotcms/client';
339
+ import type {
340
+ DotCMSPageAsset,
341
+ DotCMSPageResponse,
342
+ DotCMSBasicContentlet,
343
+ DotCMSNavigationItem,
344
+ DotCMSAISearchResponse,
345
+ DotErrorPage,
346
+ DotErrorContent,
347
+ DotErrorAISearch
348
+ } from '@dotcms/types';
349
+
350
+ const client = createDotCMSClient({
351
+ dotcmsUrl: 'https://your-dotcms-instance.com',
352
+ authToken: 'your-auth-token',
353
+ siteId: 'your-site-id'
354
+ });
355
+ ```
356
+
357
+ #### Typing Page Responses
358
+
359
+ ```typescript
360
+ import type { DotCMSPageAsset } from '@dotcms/types';
361
+
362
+ // Basic page fetch with type inference
363
+ const { pageAsset } = await client.page.get('/about-us');
364
+ // pageAsset is automatically typed as DotCMSPageAsset
365
+
366
+ // Explicit typing
367
+ const response: { pageAsset: DotCMSPageAsset } = await client.page.get('/about-us');
368
+
369
+ // Access typed properties
370
+ console.log(pageAsset.page.title); // string
371
+ console.log(pageAsset.layout.body.rows); // Row[]
372
+ console.log(pageAsset.viewAs.language); // LanguageView
373
+ ```
374
+
375
+ #### Typing Content Collections
376
+
377
+ ```typescript
378
+ import type { DotCMSBasicContentlet } from '@dotcms/types';
379
+
380
+ // Define your custom content type interface
381
+ interface BlogPost extends DotCMSBasicContentlet {
382
+ title: string;
383
+ body: string;
384
+ author: string;
385
+ publishDate: string;
386
+ tags: string[];
387
+ }
388
+
389
+ // Use the generic type parameter for type-safe content
390
+ const response = await client.content
391
+ .getCollection<BlogPost>('Blog')
392
+ .limit(10);
393
+
394
+ // Now contentlets are typed as BlogPost[]
395
+ response.contentlets.forEach(post => {
396
+ console.log(post.title); // ✅ Type-safe: string
397
+ console.log(post.author); // ✅ Type-safe: string
398
+ console.log(post.publishDate); // ✅ Type-safe: string
399
+ });
400
+ ```
401
+
402
+ #### Typing AI Search Results
403
+
404
+ ```typescript
405
+ import type {
406
+ DotCMSAISearchResponse,
407
+ DotCMSBasicContentlet,
408
+ DISTANCE_FUNCTIONS
409
+ } from '@dotcms/types';
410
+
411
+ // Define your content type
412
+ interface Article extends DotCMSBasicContentlet {
413
+ title: string;
414
+ content: string;
415
+ category: string;
416
+ }
417
+
418
+ // Type-safe AI search
419
+ const response: DotCMSAISearchResponse<Article> = await client.ai.search<Article>(
420
+ 'machine learning tutorials',
421
+ 'content_index',
422
+ {
423
+ query: {
424
+ limit: 20,
425
+ contentType: 'Article'
426
+ },
427
+ config: {
428
+ threshold: 0.75,
429
+ distanceFunction: DISTANCE_FUNCTIONS.cosine
430
+ }
431
+ }
432
+ );
433
+
434
+ // Access typed results with match information
435
+ response.results.forEach(article => {
436
+ console.log(article.title); // ✅ Type-safe: string
437
+ console.log(article.category); // ✅ Type-safe: string
438
+
439
+ // Access AI match data
440
+ article.matches?.forEach(match => {
441
+ console.log(match.distance); // ✅ Type-safe: number
442
+ console.log(match.extractedText); // ✅ Type-safe: string
443
+ });
444
+ });
445
+ ```
446
+
447
+ #### Typing Navigation
448
+
449
+ ```typescript
450
+ import type { DotCMSNavigationItem } from '@dotcms/types';
451
+
452
+ // Navigation is automatically typed
453
+ const nav: DotCMSNavigationItem[] = await client.navigation.get('/', {
454
+ depth: 2,
455
+ languageId: 1
456
+ });
457
+
458
+ // Access typed navigation properties
459
+ nav.forEach(item => {
460
+ console.log(item.title); // ✅ Type-safe: string
461
+ console.log(item.href); // ✅ Type-safe: string
462
+ console.log(item.children); // ✅ Type-safe: DotCMSNavigationItem[] | undefined
463
+ });
464
+ ```
465
+
466
+ #### Type-Safe Error Handling
467
+
468
+ ```typescript
469
+ import type {
470
+ DotHttpError,
471
+ DotErrorPage,
472
+ DotErrorContent,
473
+ DotErrorAISearch
474
+ } from '@dotcms/types';
475
+
476
+ try {
477
+ const { pageAsset } = await client.page.get('/about-us');
478
+ } catch (error) {
479
+ // Type guard for specific error types
480
+ if (error instanceof DotErrorPage) {
481
+ // TypeScript knows this is DotErrorPage
482
+ console.error('Page error:', error.message);
483
+ console.error('Context:', error.context);
484
+ if (error.httpError) {
485
+ console.error('Status:', error.httpError.status); // ✅ Type-safe
486
+ }
487
+ } else if (error instanceof DotErrorContent) {
488
+ // TypeScript knows this is DotErrorContent
489
+ console.error('Content error:', error.contentType);
490
+ console.error('Operation:', error.operation);
491
+ } else if (error instanceof DotErrorAISearch) {
492
+ // TypeScript knows this is DotErrorAISearch
493
+ console.error('AI Search error:', error.prompt);
494
+ console.error('Parameters:', error.params);
495
+ }
496
+ }
497
+ ```
498
+
499
+ #### Custom Content Types with Relationships
500
+
501
+ ```typescript
502
+ import type { DotCMSBasicContentlet } from '@dotcms/types';
503
+
504
+ // Define related content types
505
+ interface Author extends DotCMSBasicContentlet {
506
+ name: string;
507
+ email: string;
508
+ bio: string;
509
+ }
510
+
511
+ interface Category extends DotCMSBasicContentlet {
512
+ categoryName: string;
513
+ description: string;
514
+ }
515
+
516
+ // Main content type with relationships
517
+ interface BlogPost extends DotCMSBasicContentlet {
518
+ title: string;
519
+ body: string;
520
+ author: Author; // Nested type
521
+ category: Category; // Nested type
522
+ tags: string[];
523
+ publishDate: string;
524
+ }
525
+
526
+ // Fetch with depth to include relationships
527
+ const response = await client.content
528
+ .getCollection<BlogPost>('Blog')
529
+ .depth(2)
530
+ .limit(5);
531
+
532
+ // Access nested typed properties
533
+ response.contentlets.forEach(post => {
534
+ console.log(post.title); // ✅ string
535
+ console.log(post.author.name); // ✅ string
536
+ console.log(post.author.email); // ✅ string
537
+ console.log(post.category.categoryName); // ✅ string
538
+ });
539
+ ```
540
+
541
+ #### Using with Async/Await and Promises
542
+
543
+ ```typescript
544
+ import type {
545
+ DotCMSPageAsset,
546
+ GetCollectionResponse
547
+ } from '@dotcms/types';
548
+
549
+ // Async function with typed return
550
+ async function fetchBlogPosts(): Promise<GetCollectionResponse<BlogPost>> {
551
+ return await client.content
552
+ .getCollection<BlogPost>('Blog')
553
+ .limit(10);
554
+ }
555
+
556
+ // Promise chain with types
557
+ client.page.get('/about-us')
558
+ .then((response: { pageAsset: DotCMSPageAsset }) => {
559
+ console.log(response.pageAsset.page.title);
560
+ return response;
561
+ })
562
+ .catch((error: DotErrorPage) => {
563
+ console.error(error.message);
564
+ });
565
+ ```
566
+
218
567
  ### How to Work with GraphQL
219
568
 
220
569
  GraphQL allows you to fetch exactly the data you need in a single request:
@@ -421,6 +770,111 @@ getCollection<T = DotCMSBasicContentlet>(
421
770
  const blogs = await client.content.getCollection('Blog').limit(10).page(1);
422
771
  ```
423
772
 
773
+ ### ai.search() Method
774
+
775
+ > [!WARNING]
776
+ > **Experimental Feature:** The AI API is currently experimental and may undergo breaking changes in future releases. Use with caution in production environments.
777
+
778
+ Performs semantic search using AI embeddings to find content based on meaning rather than exact keyword matches.
779
+
780
+ > [!NOTE]
781
+ > **Prerequisites:** This feature requires dotAI to be activated in your dotCMS instance with a configured OpenAI API key. See the [dotAI setup documentation](https://dev.dotcms.com/docs/dotai) for configuration details.
782
+
783
+ ```typescript
784
+ search<T extends DotCMSBasicContentlet>(
785
+ prompt: string,
786
+ indexName: string,
787
+ params?: DotCMSAISearchParams
788
+ ): Promise<DotCMSAISearchResponse<T>>
789
+ ```
790
+
791
+ #### Parameters
792
+
793
+ | Parameter | Type | Required | Description |
794
+ | ----------- | --------------------- | -------- | ------------------------------------- |
795
+ | `prompt` | string | ✅ | Natural language search query |
796
+ | `indexName` | string | ✅ | Name of the AI search index to query |
797
+ | `params` | DotCMSAISearchParams | ❌ | Search configuration options |
798
+
799
+ #### Search Parameters (params.query)
800
+
801
+ | Option | Type | Description |
802
+ | ------------- | ---------------- | ---------------------------------------- |
803
+ | `limit` | number | Maximum number of results (default: 1000) |
804
+ | `offset` | number | Number of results to skip (default: 0) |
805
+ | `contentType` | string | Filter by specific content type |
806
+ | `languageId` | string | Filter by language ID |
807
+ | `siteId` | string | Filter by site ID |
808
+
809
+ #### AI Configuration (params.config)
810
+
811
+ | Option | Type | Description |
812
+ | ------------------ | ------ | ----------------------------------------------- |
813
+ | `threshold` | number | Minimum similarity score (0-1, default: 0.5) |
814
+ | `distanceFunction` | string | Distance calculation method (default: cosine) |
815
+ | `responseLength` | number | Maximum response length (default: 1024) |
816
+
817
+ #### Response
818
+
819
+ ```typescript
820
+ interface DotCMSAISearchResponse<T> {
821
+ results: Array<T & {
822
+ matches?: Array<{
823
+ distance: number; // Similarity score
824
+ extractedText: string; // Matched text excerpt
825
+ }>;
826
+ }>;
827
+ }
828
+ ```
829
+
830
+ #### Examples
831
+
832
+ **Basic Search:**
833
+ ```typescript
834
+ const results = await client.ai.search(
835
+ 'machine learning articles',
836
+ 'content_index'
837
+ );
838
+ ```
839
+
840
+ **With Parameters:**
841
+ ```typescript
842
+ import { DISTANCE_FUNCTIONS } from '@dotcms/types';
843
+
844
+ const results = await client.ai.search(
845
+ 'AI tutorials',
846
+ 'content_index',
847
+ {
848
+ query: {
849
+ limit: 20,
850
+ contentType: 'BlogPost',
851
+ languageId: '1'
852
+ },
853
+ config: {
854
+ threshold: 0.75,
855
+ distanceFunction: DISTANCE_FUNCTIONS.cosine
856
+ }
857
+ }
858
+ );
859
+ ```
860
+
861
+ **Promise-Style:**
862
+ ```typescript
863
+ client.ai.search(
864
+ 'content management best practices',
865
+ 'content_index',
866
+ {
867
+ query: { limit: 10 },
868
+ config: { threshold: 0.8 }
869
+ }
870
+ ).then((response) => {
871
+ console.log('Found:', response.results.length);
872
+ return response;
873
+ }).catch((error) => {
874
+ console.error('Search failed:', error.message);
875
+ });
876
+ ```
877
+
424
878
  ### navigation.get() Method
425
879
 
426
880
  ```typescript
@@ -458,12 +912,13 @@ The SDK provides comprehensive error handling with specific error types for diff
458
912
 
459
913
  #### Error Types
460
914
 
461
- | Error Type | When It's Thrown | Properties |
462
- | ------------------- | ------------------------------------------ | --------------------------------------------------- |
463
- | `DotHttpError` | HTTP/network failures (4xx/5xx, timeouts) | `status`, `statusText`, `headers`, `body` |
464
- | `DotErrorPage` | Page API failures | `httpError?`, `context` (query, variables) |
465
- | `DotErrorContent` | Content API failures | `contentType`, `operation`, `httpError?`, `query?` |
466
- | `DotErrorNavigation`| Navigation API failures | `path`, `httpError?` |
915
+ | Error Type | When It's Thrown | Properties |
916
+ | -------------------- | ------------------------------------------ | --------------------------------------------------- |
917
+ | `DotHttpError` | HTTP/network failures (4xx/5xx, timeouts) | `status`, `statusText`, `headers`, `body` |
918
+ | `DotErrorPage` | Page API failures | `httpError?`, `context` (query, variables) |
919
+ | `DotErrorContent` | Content API failures | `contentType`, `operation`, `httpError?`, `query?` |
920
+ | `DotErrorAISearch` | AI Search API failures | `prompt`, `params`, `httpError?` |
921
+ | `DotErrorNavigation` | Navigation API failures | `path`, `httpError?` |
467
922
 
468
923
  #### Basic Error Handling
469
924
  ```typescript
@@ -513,6 +968,23 @@ try {
513
968
  }
514
969
  ```
515
970
 
971
+ #### AI Search Error Handling
972
+ ```typescript
973
+ try {
974
+ const results = await client.ai.search('machine learning', 'content_index');
975
+ } catch (error) {
976
+ if (error instanceof DotErrorAISearch) {
977
+ console.error('AI Search error:', error.message);
978
+ console.error('Prompt:', error.prompt);
979
+ console.error('Index Name:', error.indexName);
980
+ console.error('Parameters:', error.params);
981
+ if (error.httpError) {
982
+ console.error('HTTP status:', error.httpError.status);
983
+ }
984
+ }
985
+ }
986
+ ```
987
+
516
988
  #### Promise-Style Error Handling
517
989
  ```typescript
518
990
  // Content collections support .then() with error handling
@@ -571,13 +1043,14 @@ DotHttpError: "Network request failed"
571
1043
 
572
1044
  ### Choosing the Right Method
573
1045
 
574
- The dotCMS Client SDK provides three core methods for fetching data. Use this quick guide to decide which one is best for your use case:
1046
+ The dotCMS Client SDK provides four core methods for fetching data. Use this quick guide to decide which one is best for your use case:
575
1047
 
576
- | Method | Use When You Need... | Best For |
577
- | ------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
578
- | `client.page.get()` | A full page with layout, containers, and related content | **Rendering entire pages** with a single request. Ideal for headless setups, SSR/SSG frameworks, and cases where you want everything—page structure, content, and navigation—tied to a URL path. |
1048
+ | Method | Use When You Need... | Best For |
1049
+ | -------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
1050
+ | `client.page.get()` | A full page with layout, containers, and related content | **Rendering entire pages** with a single request. Ideal for headless setups, SSR/SSG frameworks, and cases where you want everything—page structure, content, and navigation—tied to a URL path. |
579
1051
  | `client.content.getCollection()` | A filtered list of content items from a specific content type | Populating dynamic blocks, lists, search results, widgets, or reusable components. |
580
- | `client.navigation.get()` | Only the site's navigation structure (folders and links) | Standalone menus or use cases where navigation is needed outside of page context. |
1052
+ | `client.ai.search()` | Semantic/AI-powered content discovery based on natural language | **Intelligent search experiences** where users describe what they're looking for in natural language. Great for search features, content recommendations, and finding relevant content by meaning rather than exact keywords. ⚠️ **Experimental API** |
1053
+ | `client.navigation.get()` | Only the site's navigation structure (folders and links) | Standalone menus or use cases where navigation is needed outside of page context. |
581
1054
 
582
1055
  #### Start with `page.get()`: The One-Request Solution
583
1056
 
@@ -595,27 +1068,27 @@ Only use `content.getCollection()` or `navigation.get()` if you have advanced ne
595
1068
 
596
1069
  ### Architecture Overview
597
1070
 
598
- The SDK follows a client-builder pattern with three main APIs:
1071
+ The SDK follows a client-builder pattern with four main APIs:
599
1072
 
600
1073
  - **Page API** (`client.page.get()`) - Fetches complete page content with layout and containers
601
1074
  - **Content API** (`client.content.getCollection()`) - Builder pattern for querying content collections
1075
+ - **AI API** (`client.ai.search()`) - AI-powered semantic search using embeddings and vector similarity ⚠️ **Experimental**
602
1076
  - **Navigation API** (`client.navigation.get()`) - Fetches site navigation structure
603
1077
 
604
1078
  All APIs support:
605
1079
  - Type-safe responses with TypeScript
606
- - GraphQL query extensions
1080
+ - GraphQL query extensions (Page API)
607
1081
  - Localization and personalization
608
1082
  - Browser and Node.js compatibility
609
1083
 
610
- ## Support & Contributing
611
-
612
- ### dotCMS Support
1084
+ ## Support
613
1085
 
614
1086
  We offer multiple channels to get help with the dotCMS Client SDK:
615
1087
 
616
1088
  - **GitHub Issues**: For bug reports and feature requests, please [open an issue](https://github.com/dotCMS/core/issues/new/choose) in the GitHub repository.
617
1089
  - **Community Forum**: Join our [community discussions](https://community.dotcms.com/) to ask questions and share solutions.
618
1090
  - **Stack Overflow**: Use the tag `dotcms-client` when posting questions.
1091
+ - **Enterprise Support**: Enterprise customers can access premium support through the [dotCMS Support Portal](https://helpdesk.dotcms.com/support/).
619
1092
 
620
1093
  When reporting issues, please include:
621
1094
 
@@ -624,11 +1097,9 @@ When reporting issues, please include:
624
1097
  - Minimal reproduction steps
625
1098
  - Expected vs. actual behavior
626
1099
 
627
- Enterprise customers can access premium support through the [dotCMS Support Portal](https://dev.dotcms.com/docs/help).
628
-
629
- ### How To Contribute
1100
+ ## Contributing
630
1101
 
631
- GitHub pull requests are the preferred method to contribute code to dotCMS. We welcome contributions to the DotCMS UVE SDK! If you'd like to contribute, please follow these steps:
1102
+ GitHub pull requests are the preferred method to contribute code to dotCMS. We welcome contributions to the dotCMS Client SDK! If you'd like to contribute, please follow these steps:
632
1103
 
633
1104
  1. Fork the repository [dotCMS/core](https://github.com/dotCMS/core)
634
1105
  2. Create a feature branch (`git checkout -b feature/amazing-feature`)
@@ -640,6 +1111,56 @@ Please ensure your code follows the existing style and includes appropriate test
640
1111
 
641
1112
  ## Changelog
642
1113
 
1114
+ ### v1.3.0
1115
+
1116
+ #### ✨ Added - AI Search API (Experimental)
1117
+
1118
+ > **⚠️ Experimental Feature:** The AI API is experimental and may undergo breaking changes in future releases.
1119
+
1120
+ **New Features:**
1121
+ - **`client.ai.search()`** - AI-powered semantic search using embeddings and vector similarity
1122
+ - Search content by meaning rather than exact keyword matches
1123
+ - Support for custom AI search indexes
1124
+ - Configurable similarity thresholds and distance functions
1125
+ - `DotErrorAISearch` error class for AI-specific error handling with prompt and index context
1126
+
1127
+ **Prerequisites:**
1128
+ - Requires dotAI to be activated in your dotCMS instance
1129
+ - OpenAI API key must be configured
1130
+ - PostgreSQL 15+ with pgvector extension
1131
+ - Content indexes must be created in dotAI
1132
+
1133
+ **Basic Usage:**
1134
+ ```typescript
1135
+ // Semantic search with required index name
1136
+ const results = await client.ai.search(
1137
+ 'machine learning articles',
1138
+ 'content_index'
1139
+ );
1140
+
1141
+ // With advanced configuration
1142
+ const results = await client.ai.search(
1143
+ 'AI tutorials',
1144
+ 'content_index',
1145
+ {
1146
+ query: {
1147
+ limit: 20,
1148
+ contentType: 'BlogPost'
1149
+ },
1150
+ config: {
1151
+ threshold: 0.75,
1152
+ distanceFunction: DISTANCE_FUNCTIONS.cosine
1153
+ }
1154
+ }
1155
+ );
1156
+ ```
1157
+
1158
+ **Key Features:**
1159
+ - Type-safe with full TypeScript support
1160
+ - Supports multiple distance functions (cosine, L2, inner product, etc.)
1161
+ - Returns match scores and extracted text excerpts
1162
+ - Integrates seamlessly with existing content workflows
1163
+
643
1164
  ### v1.1.1
644
1165
 
645
1166
  Version 1.1.1 introduces significant improvements to error handling and HTTP client architecture. Most applications will continue to work without changes.
@@ -748,7 +1269,7 @@ import { RequestOptions } from '@dotcms/types';
748
1269
  import { DotRequestOptions } from '@dotcms/types';
749
1270
  ```
750
1271
 
751
- ### Licensing Information
1272
+ ## Licensing
752
1273
 
753
1274
  dotCMS comes in multiple editions and as such is dual-licensed. The dotCMS Community Edition is licensed under the GPL 3.0 and is freely available for download, customization, and deployment for use within organizations of all stripes. dotCMS Enterprise Editions (EE) adds several enterprise features and is available via a supported, indemnified commercial license from dotCMS. For the differences between the editions, see [the feature page](http://www.dotcms.com/cms-platform/features).
754
1275