@umbraco-ai/core 1.10.1 → 1.12.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umbraco-ai/core",
3
- "version": "1.10.1",
3
+ "version": "1.12.0",
4
4
  "type": "module",
5
5
  "types": "./types/umbraco-ai-public-types.d.ts",
6
6
  "files": [
@@ -8,8 +8,8 @@
8
8
  "README.md"
9
9
  ],
10
10
  "peerDependencies": {
11
- "@umbraco-cms/backoffice": "^17.3.0",
11
+ "@umbraco-cms/backoffice": "^17.4.0",
12
12
  "chart.js": "^4.5.1",
13
- "diff": "^8.0.3"
13
+ "diff": "^9.0.0"
14
14
  }
15
15
  }
@@ -24,32 +24,220 @@ import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
24
24
  import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
25
25
  import { UUIFormControlMixinElement } from '@umbraco-ui/uui-base';
26
26
 
27
- declare interface AiHttpClient {
28
- setConfig: (config: any) => unknown;
29
- interceptors: {
30
- response: {
31
- use: (fn: (response: Response, request: Request, opts?: unknown) => Response | Promise<Response>) => unknown;
32
- };
27
+ export declare type AiDocumentMetadataModel = {
28
+ contentTypeKey: string;
29
+ variants: Array<AiVariantIdModel>;
30
+ isVariant: boolean;
31
+ isSegmented: boolean;
32
+ name?: string | null;
33
+ };
34
+
35
+ export declare type AiDocumentMetadataModelWritable = {
36
+ contentTypeKey: string;
37
+ variants: Array<AiVariantIdModelWritable>;
38
+ isVariant: boolean;
39
+ isSegmented: boolean;
40
+ name?: string | null;
41
+ };
42
+
43
+ export declare type AiPropertyOperationModel = 'AddItem' | 'RemoveItem' | 'MoveItem' | 'SetValue' | 'ClearValue';
44
+
45
+ declare type AiPropertyPathSegmentModel = {
46
+ [key: string]: never;
47
+ };
48
+
49
+ export declare type AiPropertyValueOperationErrorModel = {
50
+ code: string;
51
+ message: string;
52
+ details?: {
53
+ [key: string]: JsonNode;
54
+ } | null;
55
+ };
56
+
57
+ export declare type AiVariantIdModel = {
58
+ culture?: string | null;
59
+ segment?: string | null;
60
+ readonly isInvariant: boolean;
61
+ };
62
+
63
+ export declare type AiVariantIdModelWritable = {
64
+ culture?: string | null;
65
+ segment?: string | null;
66
+ };
67
+
68
+ declare type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited';
69
+
70
+ declare interface Auth {
71
+ /**
72
+ * Which part of the request do we use to send the auth?
73
+ *
74
+ * @default 'header'
75
+ */
76
+ in?: 'header' | 'query' | 'cookie';
77
+ /**
78
+ * Header or query parameter name.
79
+ *
80
+ * @default 'Authorization'
81
+ */
82
+ name?: string;
83
+ scheme?: 'basic' | 'bearer';
84
+ type: 'apiKey' | 'http';
85
+ }
86
+
87
+ declare type AuthToken = string | undefined;
88
+
89
+ declare type BodySerializer = (body: unknown) => unknown;
90
+
91
+ declare type BuildUrlFn = <TData extends {
92
+ body?: unknown;
93
+ path?: Record<string, unknown>;
94
+ query?: Record<string, unknown>;
95
+ url: string;
96
+ }>(options: TData & Options_2<TData>) => string;
97
+
98
+ declare type Client = Client_2<RequestFn, Config, MethodFn, BuildUrlFn, SseFn> & {
99
+ interceptors: Middleware<Request, Response, unknown, ResolvedRequestOptions>;
100
+ };
101
+
102
+ declare type Client_2<RequestFn = never, Config = unknown, MethodFn = never, BuildUrlFn = never, SseFn = never> = {
103
+ /**
104
+ * Returns the final request URL.
105
+ */
106
+ buildUrl: BuildUrlFn;
107
+ getConfig: () => Config;
108
+ request: RequestFn;
109
+ setConfig: (config: Config) => Config;
110
+ } & {
111
+ [K in HttpMethod]: MethodFn;
112
+ } & ([SseFn] extends [never] ? {
113
+ sse?: never;
114
+ } : {
115
+ sse: {
116
+ [K in HttpMethod]: SseFn;
33
117
  };
118
+ });
119
+
120
+ declare interface ClientOptions {
121
+ baseUrl?: string;
122
+ responseStyle?: ResponseStyle;
123
+ throwOnError?: boolean;
124
+ }
125
+
126
+ declare interface Config<T extends ClientOptions = ClientOptions> extends Omit<RequestInit, 'body' | 'headers' | 'method'>, Config_2 {
127
+ /**
128
+ * Base URL for all requests made by this client.
129
+ */
130
+ baseUrl?: T['baseUrl'];
131
+ /**
132
+ * Fetch API implementation. You can use this option to provide a custom
133
+ * fetch instance.
134
+ *
135
+ * @default globalThis.fetch
136
+ */
137
+ fetch?: typeof fetch;
138
+ /**
139
+ * Please don't use the Fetch client for Next.js applications. The `next`
140
+ * options won't have any effect.
141
+ *
142
+ * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead.
143
+ */
144
+ next?: never;
145
+ /**
146
+ * Return the response data parsed in a specified format. By default, `auto`
147
+ * will infer the appropriate method from the `Content-Type` response header.
148
+ * You can override this behavior with any of the {@link Body} methods.
149
+ * Select `stream` if you don't want to parse response data at all.
150
+ *
151
+ * @default 'auto'
152
+ */
153
+ parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text';
154
+ /**
155
+ * Should we return only data or multiple fields (data, error, response, etc.)?
156
+ *
157
+ * @default 'fields'
158
+ */
159
+ responseStyle?: ResponseStyle;
160
+ /**
161
+ * Throw an error instead of returning it in the response?
162
+ *
163
+ * @default false
164
+ */
165
+ throwOnError?: T['throwOnError'];
166
+ }
167
+
168
+ declare interface Config_2 {
169
+ /**
170
+ * Auth token or a function returning auth token. The resolved value will be
171
+ * added to the request payload as defined by its `security` array.
172
+ */
173
+ auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken;
174
+ /**
175
+ * A function for serializing request body parameter. By default,
176
+ * {@link JSON.stringify()} will be used.
177
+ */
178
+ bodySerializer?: BodySerializer | null;
179
+ /**
180
+ * An object containing any HTTP headers that you want to pre-populate your
181
+ * `Headers` object with.
182
+ *
183
+ * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
184
+ */
185
+ headers?: RequestInit['headers'] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined | unknown>;
186
+ /**
187
+ * The request method.
188
+ *
189
+ * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
190
+ */
191
+ method?: Uppercase<HttpMethod>;
192
+ /**
193
+ * A function for serializing request query parameters. By default, arrays
194
+ * will be exploded in form style, objects will be exploded in deepObject
195
+ * style, and reserved characters are percent-encoded.
196
+ *
197
+ * This method will have no effect if the native `paramsSerializer()` Axios
198
+ * API function is used.
199
+ *
200
+ * {@link https://swagger.io/docs/specification/serialization/#query View examples}
201
+ */
202
+ querySerializer?: QuerySerializer | QuerySerializerOptions;
203
+ /**
204
+ * A function validating request data. This is useful if you want to ensure
205
+ * the request conforms to the desired shape, so it can be safely sent to
206
+ * the server.
207
+ */
208
+ requestValidator?: (data: unknown) => Promise<unknown>;
209
+ /**
210
+ * A function transforming response data before it's returned. This is useful
211
+ * for post-processing data, e.g., converting ISO strings into Date objects.
212
+ */
213
+ responseTransformer?: (data: unknown) => Promise<unknown>;
214
+ /**
215
+ * A function validating response data. This is useful if you want to ensure
216
+ * the response conforms to the desired shape, so it can be safely passed to
217
+ * the transformers and returned to the user.
218
+ */
219
+ responseValidator?: (data: unknown) => Promise<unknown>;
34
220
  }
35
221
 
36
222
  /**
37
- * Configures a generated hey-api client with the backoffice auth callback
38
- * and attaches a silent 401 recovery interceptor.
223
+ * Configures a generated hey-api client for authenticated calls to the
224
+ * Umbraco backoffice Management API.
39
225
  *
40
- * The interceptor calls `authContext.makeRefreshTokenRequest()` on a 401
41
- * and retries the request once. This is a workaround for CMS issue
42
- * https://github.com/umbraco/Umbraco-CMS/issues/22647 the default
43
- * `UmbApiInterceptorController.bindDefaultInterceptors` is unusable from
44
- * third-party entry-point hosts because its `UmbAuthSignalerContext`
45
- * ends up scoped below `umb-app` and emissions never reach `UmbAuthContext`.
226
+ * Delegates to `authContext.configureClient(client)`, which:
227
+ * - Sets `baseUrl`, `credentials: 'include'`, and an `auth` callback that
228
+ * gates each request on `#ensureTokenReady` (inline refresh + cross-tab
229
+ * Web Lock coordination).
230
+ * - Binds the default response interceptors (401 retry, 403 handling,
231
+ * error normalization, server notifications) with the auth context's
232
+ * own host so the `UmbAuthSignalerContext` is registered at `umb-app`
233
+ * and emissions reach `UmbAuthContext` correctly.
46
234
  *
47
235
  * @param host The entry point's `host` parameter (`UmbElement`).
48
236
  * @param client The generated hey-api client to configure.
49
237
  * @returns A Promise that resolves once auth is configured on the client.
50
238
  * @public
51
239
  */
52
- export declare function configureAiClient(host: UmbElement, client: AiHttpClient): Promise<void>;
240
+ export declare function configureAiClient(host: UmbElement, client: unknown): Promise<void>;
53
241
 
54
242
  export declare const coreClientReady: Promise<void>;
55
243
 
@@ -101,6 +289,8 @@ declare type EntityVersionResponseModel = {
101
289
  changeDescription?: string | null;
102
290
  };
103
291
 
292
+ declare type ErrInterceptor<Err, Res, Req, Options> = (error: Err, response: Res, request: Req, options: Options) => Err | Promise<Err>;
293
+
104
294
  export declare function formatDateTime(input: string | Date, locale?: string): string;
105
295
 
106
296
  /**
@@ -111,6 +301,57 @@ export declare function formatDateTime(input: string | Date, locale?: string): s
111
301
  */
112
302
  export declare function hasEntityAdapter(entityType: string): boolean;
113
303
 
304
+ declare type HttpMethod = 'connect' | 'delete' | 'get' | 'head' | 'options' | 'patch' | 'post' | 'put' | 'trace';
305
+
306
+ declare class Interceptors<Interceptor> {
307
+ fns: Array<Interceptor | null>;
308
+ clear(): void;
309
+ eject(id: number | Interceptor): void;
310
+ exists(id: number | Interceptor): boolean;
311
+ getInterceptorIndex(id: number | Interceptor): number;
312
+ update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false;
313
+ use(fn: Interceptor): number;
314
+ }
315
+
316
+ declare type InvokeData = {
317
+ body?: PropertyValueOperationRequestModelWritable;
318
+ path?: never;
319
+ query?: never;
320
+ url: '/umbraco/ai/management/api/v1/property-value-operation';
321
+ };
322
+
323
+ declare type InvokeErrors = {
324
+ /**
325
+ * Bad Request
326
+ */
327
+ 400: unknown;
328
+ /**
329
+ * The resource is protected and requires an authentication token
330
+ */
331
+ 401: unknown;
332
+ };
333
+
334
+ declare type InvokeResponses = {
335
+ /**
336
+ * OK
337
+ */
338
+ 200: PropertyValueOperationResponseModel;
339
+ };
340
+
341
+ declare type JsonNode = {
342
+ options?: JsonNodeOptions | null;
343
+ parent?: JsonNode | null;
344
+ root: JsonNode;
345
+ };
346
+
347
+ declare type JsonNodeOptions = {
348
+ propertyNameCaseInsensitive: boolean;
349
+ };
350
+
351
+ declare type JsonNodeWritable = {
352
+ [key: string]: never;
353
+ };
354
+
114
355
  /**
115
356
  * Manifest for entity adapter extensions.
116
357
  */
@@ -124,6 +365,27 @@ export declare interface ManifestEntityAdapter extends ManifestBase {
124
365
  }>;
125
366
  }
126
367
 
368
+ /**
369
+ * Manifest for property value preparer extensions.
370
+ *
371
+ * Registered preparers are looked up by `forPropertyEditorSchemaAlias` whenever the entity
372
+ * adapter is about to call `setPropertyValue`. The first matching preparer's `prepare` is
373
+ * invoked; editors with no registered preparer use a small default that attempts JSON.parse on
374
+ * string input and returns the result unchanged.
375
+ */
376
+ export declare interface ManifestUaiPropertyValuePreparer extends ManifestBase {
377
+ type: typeof UAI_PROPERTY_VALUE_PREPARER_EXTENSION_TYPE;
378
+ /**
379
+ * The CMS property editor schema alias this preparer handles (e.g. `Umbraco.BlockList`).
380
+ * Matched case-insensitively against the property editor of the value being applied.
381
+ */
382
+ forPropertyEditorSchemaAlias: string;
383
+ /** The preparer API class loader. */
384
+ api: () => Promise<{
385
+ default: new () => UaiPropertyValuePreparerApi;
386
+ }>;
387
+ }
388
+
127
389
  /**
128
390
  * Manifest for request context contributor extensions.
129
391
  *
@@ -188,6 +450,131 @@ export declare interface ManifestUaiTestFeatureEntityRepository extends Manifest
188
450
  };
189
451
  }
190
452
 
453
+ declare type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
454
+
455
+ declare interface Middleware<Req, Res, Err, Options> {
456
+ error: Interceptors<ErrInterceptor<Err, Res, Req, Options>>;
457
+ request: Interceptors<ReqInterceptor<Req, Options>>;
458
+ response: Interceptors<ResInterceptor<Res, Req, Options>>;
459
+ }
460
+
461
+ declare type ObjectStyle = 'form' | 'deepObject';
462
+
463
+ declare type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>;
464
+
465
+ declare type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown> = Options_2<TData, ThrowOnError, TResponse> & {
466
+ /**
467
+ * You can provide a client instance returned by `createClient()` instead of
468
+ * individual options. This might be also useful if you want to implement a
469
+ * custom client.
470
+ */
471
+ client?: Client;
472
+ /**
473
+ * You can pass arbitrary values through the `meta` object. This can be
474
+ * used to access values that aren't defined as part of the SDK function.
475
+ */
476
+ meta?: Record<string, unknown>;
477
+ };
478
+
479
+ declare type Options_2<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown, TResponseStyle extends ResponseStyle = 'fields'> = OmitKeys<RequestOptions<TResponse, TResponseStyle, ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & ([TData] extends [never] ? unknown : Omit<TData, 'url'>);
480
+
481
+ export declare type PropertyValueOperationRequestModel = {
482
+ path: Array<AiPropertyPathSegmentModel>;
483
+ operation: AiPropertyOperationModel;
484
+ args?: JsonNode | null;
485
+ rootValue?: JsonNode | null;
486
+ rootEditorSchemaAlias: string;
487
+ documentMetadata: AiDocumentMetadataModel;
488
+ };
489
+
490
+ export declare type PropertyValueOperationRequestModelWritable = {
491
+ path: Array<AiPropertyPathSegmentModel>;
492
+ operation: AiPropertyOperationModel;
493
+ args?: JsonNodeWritable | null;
494
+ rootValue?: JsonNodeWritable | null;
495
+ rootEditorSchemaAlias: string;
496
+ documentMetadata: AiDocumentMetadataModelWritable;
497
+ };
498
+
499
+ export declare type PropertyValueOperationResponseModel = {
500
+ success: boolean;
501
+ newRootValue?: JsonNode | null;
502
+ blockKey?: string | null;
503
+ error?: AiPropertyValueOperationErrorModel | null;
504
+ };
505
+
506
+ export declare class PropertyValueOperationsService {
507
+ static invoke<ThrowOnError extends boolean = false>(options?: Options<InvokeData, ThrowOnError>): RequestResult<InvokeResponses, InvokeErrors, ThrowOnError, "fields">;
508
+ }
509
+
510
+ declare type QuerySerializer = (query: Record<string, unknown>) => string;
511
+
512
+ declare type QuerySerializerOptions = QuerySerializerOptionsObject & {
513
+ /**
514
+ * Per-parameter serialization overrides. When provided, these settings
515
+ * override the global array/object settings for specific parameter names.
516
+ */
517
+ parameters?: Record<string, QuerySerializerOptionsObject>;
518
+ };
519
+
520
+ declare type QuerySerializerOptionsObject = {
521
+ allowReserved?: boolean;
522
+ array?: Partial<SerializerOptions<ArrayStyle>>;
523
+ object?: Partial<SerializerOptions<ObjectStyle>>;
524
+ };
525
+
526
+ declare type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;
527
+
528
+ declare type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'> & Pick<Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
529
+
530
+ declare interface RequestOptions<TData = unknown, TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<{
531
+ responseStyle: TResponseStyle;
532
+ throwOnError: ThrowOnError;
533
+ }>, Pick<ServerSentEventsOptions<TData>, 'onRequest' | 'onSseError' | 'onSseEvent' | 'sseDefaultRetryDelay' | 'sseMaxRetryAttempts' | 'sseMaxRetryDelay'> {
534
+ /**
535
+ * Any body that you want to add to your request.
536
+ *
537
+ * {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
538
+ */
539
+ body?: unknown;
540
+ path?: Record<string, unknown>;
541
+ query?: Record<string, unknown>;
542
+ /**
543
+ * Security mechanism(s) to use for the request.
544
+ */
545
+ security?: ReadonlyArray<Auth>;
546
+ url: Url;
547
+ }
548
+
549
+ declare type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = ThrowOnError extends true ? Promise<TResponseStyle extends 'data' ? TData extends Record<string, unknown> ? TData[keyof TData] : TData : {
550
+ data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
551
+ request: Request;
552
+ response: Response;
553
+ }> : Promise<TResponseStyle extends 'data' ? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined : ({
554
+ data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
555
+ error: undefined;
556
+ } | {
557
+ data: undefined;
558
+ error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
559
+ }) & {
560
+ request: Request;
561
+ response: Response;
562
+ }>;
563
+
564
+ declare type ResInterceptor<Res, Req, Options> = (response: Res, request: Req, options: Options) => Res | Promise<Res>;
565
+
566
+ /**
567
+ * Looks up the preparer registered for a given editor schema alias and runs it. Editors with no
568
+ * registered preparer fall back to a permissive default that attempts JSON.parse on string input
569
+ * and returns the result unchanged.
570
+ */
571
+ export declare function resolveAndPrepareValue(value: unknown, editorAlias: string | undefined, currentValue: unknown): Promise<unknown>;
572
+
573
+ declare interface ResolvedRequestOptions<TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string> extends RequestOptions<unknown, TResponseStyle, ThrowOnError, Url> {
574
+ headers: Headers;
575
+ serializedBody?: string;
576
+ }
577
+
191
578
  /**
192
579
  * Resolve an entity adapter by entity type.
193
580
  *
@@ -208,6 +595,98 @@ export declare interface ManifestUaiTestFeatureEntityRepository extends Manifest
208
595
  */
209
596
  export declare function resolveEntityAdapterByType(entityType: string): Promise<UaiEntityAdapterApi | undefined>;
210
597
 
598
+ declare type ResponseStyle = 'data' | 'fields';
599
+
600
+ declare interface SerializerOptions<T> {
601
+ /**
602
+ * @default true
603
+ */
604
+ explode: boolean;
605
+ style: T;
606
+ }
607
+
608
+ declare type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, 'method'> & Pick<Config_2, 'method' | 'responseTransformer' | 'responseValidator'> & {
609
+ /**
610
+ * Fetch API implementation. You can use this option to provide a custom
611
+ * fetch instance.
612
+ *
613
+ * @default globalThis.fetch
614
+ */
615
+ fetch?: typeof fetch;
616
+ /**
617
+ * Implementing clients can call request interceptors inside this hook.
618
+ */
619
+ onRequest?: (url: string, init: RequestInit) => Promise<Request>;
620
+ /**
621
+ * Callback invoked when a network or parsing error occurs during streaming.
622
+ *
623
+ * This option applies only if the endpoint returns a stream of events.
624
+ *
625
+ * @param error The error that occurred.
626
+ */
627
+ onSseError?: (error: unknown) => void;
628
+ /**
629
+ * Callback invoked when an event is streamed from the server.
630
+ *
631
+ * This option applies only if the endpoint returns a stream of events.
632
+ *
633
+ * @param event Event streamed from the server.
634
+ * @returns Nothing (void).
635
+ */
636
+ onSseEvent?: (event: StreamEvent<TData>) => void;
637
+ serializedBody?: RequestInit['body'];
638
+ /**
639
+ * Default retry delay in milliseconds.
640
+ *
641
+ * This option applies only if the endpoint returns a stream of events.
642
+ *
643
+ * @default 3000
644
+ */
645
+ sseDefaultRetryDelay?: number;
646
+ /**
647
+ * Maximum number of retry attempts before giving up.
648
+ */
649
+ sseMaxRetryAttempts?: number;
650
+ /**
651
+ * Maximum retry delay in milliseconds.
652
+ *
653
+ * Applies only when exponential backoff is used.
654
+ *
655
+ * This option applies only if the endpoint returns a stream of events.
656
+ *
657
+ * @default 30000
658
+ */
659
+ sseMaxRetryDelay?: number;
660
+ /**
661
+ * Optional sleep function for retry backoff.
662
+ *
663
+ * Defaults to using `setTimeout`.
664
+ */
665
+ sseSleepFn?: (ms: number) => Promise<void>;
666
+ url: string;
667
+ };
668
+
669
+ declare type ServerSentEventsResult<TData = unknown, TReturn = void, TNext = unknown> = {
670
+ stream: AsyncGenerator<TData extends Record<string, unknown> ? TData[keyof TData] : TData, TReturn, TNext>;
671
+ };
672
+
673
+ declare type SseFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<never, TResponseStyle, ThrowOnError>, 'method'>) => Promise<ServerSentEventsResult<TData, TError>>;
674
+
675
+ declare interface StreamEvent<TData = unknown> {
676
+ data: TData;
677
+ event?: string;
678
+ id?: string;
679
+ retry?: number;
680
+ }
681
+
682
+ declare interface TDataShape {
683
+ body?: unknown;
684
+ headers?: unknown;
685
+ path?: unknown;
686
+ query?: unknown;
687
+ url: string;
688
+ }
689
+
211
690
  /**
212
691
  * Converts a string to camelCase by splitting on separators (-, _, ., spaces).
213
692
  * Used for converting tool/scope IDs to localization key format.
@@ -245,6 +724,11 @@ export declare const UAI_ITEM_PICKER_MODAL: UmbModalToken<UaiItemPickerModalData
245
724
 
246
725
  export declare const UAI_MONITORING_MENU_ALIAS = "Uai.Menu.Monitoring";
247
726
 
727
+ /**
728
+ * Extension type alias for property value preparers.
729
+ */
730
+ export declare const UAI_PROPERTY_VALUE_PREPARER_EXTENSION_TYPE = "uaiPropertyValuePreparer";
731
+
248
732
  /**
249
733
  * Extension type alias for request context contributors.
250
734
  */
@@ -591,6 +1075,19 @@ export declare class UaiDocumentAdapter implements UaiEntityAdapterApi {
591
1075
  * Only supports text-based properties (TextBox, TextArea) for now.
592
1076
  */
593
1077
  applyValueChange(workspaceContext: unknown, change: UaiValueChange): Promise<UaiValueChangeResult>;
1078
+ /**
1079
+ * Persist staged changes to the document (equivalent to clicking Save).
1080
+ * Delegates to the workspace's `requestSubmit()`; any validation failure thrown by the
1081
+ * workspace is converted into a structured error so the LLM can read it.
1082
+ */
1083
+ save(workspaceContext: unknown): Promise<UaiPersistResult>;
1084
+ /**
1085
+ * Save the document and publish it. Resolves the document publishing workspace context as a
1086
+ * sibling of the workspace context (both register against the same host) and delegates to
1087
+ * `saveAndPublish()`. On multi-variant documents this can surface the CMS's variant-picker
1088
+ * modal — same UX as clicking the Save and publish button.
1089
+ */
1090
+ publish(workspaceContext: unknown): Promise<UaiPersistResult>;
594
1091
  /**
595
1092
  * Cleanup method required by UmbApi base type.
596
1093
  * Currently no resources to clean up as the adapter is stateless.
@@ -745,6 +1242,19 @@ export declare interface UaiEntityAdapterApi extends UmbApi {
745
1242
  * @returns Result indicating success or failure with error message
746
1243
  */
747
1244
  applyValueChange?(workspaceContext: unknown, change: UaiValueChange): Promise<UaiValueChangeResult>;
1245
+ /**
1246
+ * Persist the workspace's staged changes (the equivalent of clicking the workspace's Save
1247
+ * button). Optional — entity types that don't own their own save (e.g. blocks, whose changes
1248
+ * save with the parent document) should omit this so the caller can return a clear "not
1249
+ * supported" error.
1250
+ */
1251
+ save?(workspaceContext: unknown): Promise<UaiPersistResult>;
1252
+ /**
1253
+ * Persist the workspace's staged changes and publish them. Optional — only entity types with
1254
+ * a publish concept (documents) implement this; media and other always-live entities should
1255
+ * omit it.
1256
+ */
1257
+ publish?(workspaceContext: unknown): Promise<UaiPersistResult>;
748
1258
  }
749
1259
 
750
1260
  /**
@@ -792,6 +1302,19 @@ export declare class UaiEntityAdapterContext extends UmbControllerBase {
792
1302
  * @returns Result indicating success or failure with error message
793
1303
  */
794
1304
  applyValueChange(change: UaiValueChange): Promise<UaiValueChangeResult>;
1305
+ /**
1306
+ * Persist the currently selected entity's staged changes (equivalent of the user clicking
1307
+ * Save). Returns a structured "not supported" error when the entity type doesn't own a save
1308
+ * action — most commonly when the user has a block workspace selected, since block changes
1309
+ * save with the parent document.
1310
+ */
1311
+ saveSelectedEntity(): Promise<UaiPersistResult>;
1312
+ /**
1313
+ * Persist and publish the currently selected entity. Returns a structured "not supported"
1314
+ * error for entity types without a publish concept (media, blocks) — publishing only applies
1315
+ * to documents.
1316
+ */
1317
+ publishSelectedEntity(): Promise<UaiPersistResult>;
795
1318
  }
796
1319
 
797
1320
  /**
@@ -979,6 +1502,18 @@ export declare class UaiPartialUpdateCommand<TReceiver> extends UaiCommandBase<T
979
1502
  execute(receiver: TReceiver): void;
980
1503
  }
981
1504
 
1505
+ /**
1506
+ * Result of a save (or save-and-publish) operation triggered by an AI tool. Adapters convert
1507
+ * exceptions thrown by the underlying workspace into a structured payload so the LLM can read the
1508
+ * error message rather than treat the call as silently successful.
1509
+ */
1510
+ declare interface UaiPersistResult {
1511
+ /** Whether persistence completed successfully. */
1512
+ success: boolean;
1513
+ /** Human-readable error message if persistence failed. */
1514
+ error?: string;
1515
+ }
1516
+
982
1517
  export declare type UaiPickableItemModel = {
983
1518
  value: string;
984
1519
  label: string;
@@ -1051,6 +1586,38 @@ export declare class UaiProfilePickerElement extends UaiProfilePickerElement_bas
1051
1586
 
1052
1587
  declare const UaiProfilePickerElement_base: HTMLElementConstructor<UmbFormControlMixinElement<string | string[] | undefined>> & typeof UmbLitElement;
1053
1588
 
1589
+ /**
1590
+ * Property Value Preparer
1591
+ *
1592
+ * Editor-specific frontend adjustment applied to a property value on its way from an AI tool
1593
+ * (or any caller of `UaiEntityAdapterContext.applyValueChange`) into `workspaceContext.setPropertyValue`.
1594
+ *
1595
+ * Preparers exist because some property editor lit components have frontend-only quirks that the
1596
+ * backend dispatcher can't fix:
1597
+ * - block-shaped editors return pre-built object envelopes that must NOT be re-stringified;
1598
+ * - rich-text expects `{ markup, blocks }` and may receive a bare markup string;
1599
+ * - media picker 3's thumbnail subcomponent doesn't react to in-place `mediaKey` changes, so we
1600
+ * re-mint the entry's `key` to force lit to re-mount the subcomponent.
1601
+ *
1602
+ * Each preparer owns ALL the editor-specific behavior — including any JSON.parse on string input,
1603
+ * any shape adjustments, and any reactivity workarounds. Preparers are stateless and pure.
1604
+ *
1605
+ * Third parties register a preparer for their own editor's quirks via
1606
+ * `uaiPropertyValuePreparer` extension manifest. Editors with no registered preparer fall back to
1607
+ * a default that attempts JSON.parse on string inputs and returns the result.
1608
+ */
1609
+ export declare interface UaiPropertyValuePreparerApi {
1610
+ /**
1611
+ * Adjust a value on its way to `setPropertyValue`.
1612
+ *
1613
+ * @param value The new value being applied (whatever shape the caller produced).
1614
+ * @param currentValue The value currently staged in the workspace, if any. Used by preparers
1615
+ * that need to compare incoming entries to existing ones (e.g. to detect content changes).
1616
+ * @returns The adjusted value to pass through to `setPropertyValue`.
1617
+ */
1618
+ prepare(value: unknown, currentValue: unknown): unknown | Promise<unknown>;
1619
+ }
1620
+
1054
1621
  /**
1055
1622
  * Mutable context bag passed to each contributor.
1056
1623
  * Mirrors the backend AIRuntimeContext pattern -- contributors