@objectstack/service-ai 6.8.1 → 7.0.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
@@ -308,6 +308,20 @@ declare class AIService implements IAIService {
308
308
  private readonly pendingDispatchers;
309
309
  /** Data engine for `ai_pending_actions` persistence. */
310
310
  private readonly dataEngine?;
311
+ /**
312
+ * Auto-title configuration. When `enabled`, the first `chatWithTools` /
313
+ * `streamChatWithTools` call against a still-untitled conversation
314
+ * triggers a one-shot LLM call (fire-and-forget) that summarises the
315
+ * exchange into a short title and PATCHes it onto the conversation row.
316
+ *
317
+ * Defaults to disabled — `AIServicePlugin` flips this on (with values
318
+ * read from the `ai` settings namespace) once the kernel is ready.
319
+ * Keeping the default off means unit tests don't accidentally make
320
+ * extra adapter calls.
321
+ */
322
+ private titleGeneration;
323
+ /** Tracks conversations we've already attempted to title to avoid duplicate LLM calls. */
324
+ private readonly titledConversations;
311
325
  constructor(config?: AIServiceConfig);
312
326
  /** The name of the active LLM adapter. */
313
327
  get adapterName(): string;
@@ -318,6 +332,36 @@ declare class AIService implements IAIService {
318
332
  * subsequent calls go through the new adapter.
319
333
  */
320
334
  setAdapter(next: LLMAdapter): void;
335
+ /**
336
+ * Configure conversation auto-titling. Called by `AIServicePlugin`
337
+ * when the `ai` settings namespace is bound (so admins can toggle
338
+ * the feature live from the Setup app without a restart).
339
+ *
340
+ * - `enabled=false` is the safe default for unit tests and the
341
+ * memory adapter (which would just echo the prompt back as a title).
342
+ * - `maxLength` is enforced both in the prompt and as a hard server-side
343
+ * `slice()` so a misbehaving model can't write a 4 KB "title".
344
+ */
345
+ setTitleGenerationConfig(config: {
346
+ enabled: boolean;
347
+ maxLength?: number;
348
+ }): void;
349
+ /**
350
+ * Best-effort title generation for a conversation. Idempotent per
351
+ * `AIService` instance — once attempted, the id is recorded in
352
+ * `titledConversations` so subsequent chats don't burn extra tokens
353
+ * re-summarising the same thread.
354
+ *
355
+ * Skips when:
356
+ * - feature disabled
357
+ * - conversation already has a non-empty title
358
+ * - conversation has fewer than 2 messages (no exchange to summarise)
359
+ * - conversation has no user message
360
+ *
361
+ * Failures are logged at debug level and swallowed — title generation
362
+ * is purely cosmetic and must never break chat.
363
+ */
364
+ summarizeConversation(conversationId: string): Promise<void>;
321
365
  /**
322
366
  * Best-effort auto-creation of a conversation when the caller did not
323
367
  * supply one but did supply an actor we can attribute the chat to.
@@ -2258,6 +2302,14 @@ declare const AiConversationObject: Omit<{
2258
2302
  } | undefined;
2259
2303
  recordTypes?: string[] | undefined;
2260
2304
  sharingModel?: "private" | "read" | "full" | "read_write" | undefined;
2305
+ publicSharing?: {
2306
+ enabled: boolean;
2307
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
2308
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
2309
+ maxExpiryDays?: number | undefined;
2310
+ redactFields?: string[] | undefined;
2311
+ eligibility?: string | undefined;
2312
+ } | undefined;
2261
2313
  keyPrefix?: string | undefined;
2262
2314
  detail?: {
2263
2315
  [x: string]: unknown;
@@ -2272,7 +2324,7 @@ declare const AiConversationObject: Omit<{
2272
2324
  refreshAfter: boolean;
2273
2325
  objectName?: string | undefined;
2274
2326
  icon?: string | undefined;
2275
- locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "global_nav")[] | undefined;
2327
+ locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "record_section" | "global_nav")[] | undefined;
2276
2328
  component?: "action:button" | "action:icon" | "action:menu" | "action:group" | undefined;
2277
2329
  target?: string | undefined;
2278
2330
  body?: {
@@ -2305,6 +2357,17 @@ declare const AiConversationObject: Omit<{
2305
2357
  variant?: "link" | "primary" | "secondary" | "danger" | "ghost" | undefined;
2306
2358
  confirmText?: string | undefined;
2307
2359
  successMessage?: string | undefined;
2360
+ resultDialog?: {
2361
+ title?: string | undefined;
2362
+ description?: string | undefined;
2363
+ acknowledge?: string | undefined;
2364
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
2365
+ fields?: {
2366
+ path: string;
2367
+ label?: string | undefined;
2368
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
2369
+ }[] | undefined;
2370
+ } | undefined;
2308
2371
  visible?: {
2309
2372
  dialect: "cel" | "js" | "cron" | "template";
2310
2373
  source?: string | undefined;
@@ -2348,6 +2411,13 @@ declare const AiConversationObject: Omit<{
2348
2411
  readonly icon: "message-square";
2349
2412
  readonly isSystem: true;
2350
2413
  readonly description: "Persistent AI conversation metadata";
2414
+ readonly publicSharing: {
2415
+ readonly enabled: true;
2416
+ readonly allowedAudiences: ["link_only", "signed_in"];
2417
+ readonly allowedPermissions: ["view"];
2418
+ readonly maxExpiryDays: 90;
2419
+ readonly redactFields: ["metadata"];
2420
+ };
2351
2421
  readonly fields: {
2352
2422
  readonly id: {
2353
2423
  readonly readonly?: boolean | undefined;
@@ -4187,6 +4257,14 @@ declare const AiMessageObject: Omit<{
4187
4257
  } | undefined;
4188
4258
  recordTypes?: string[] | undefined;
4189
4259
  sharingModel?: "private" | "read" | "full" | "read_write" | undefined;
4260
+ publicSharing?: {
4261
+ enabled: boolean;
4262
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
4263
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
4264
+ maxExpiryDays?: number | undefined;
4265
+ redactFields?: string[] | undefined;
4266
+ eligibility?: string | undefined;
4267
+ } | undefined;
4190
4268
  keyPrefix?: string | undefined;
4191
4269
  detail?: {
4192
4270
  [x: string]: unknown;
@@ -4201,7 +4279,7 @@ declare const AiMessageObject: Omit<{
4201
4279
  refreshAfter: boolean;
4202
4280
  objectName?: string | undefined;
4203
4281
  icon?: string | undefined;
4204
- locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "global_nav")[] | undefined;
4282
+ locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "record_section" | "global_nav")[] | undefined;
4205
4283
  component?: "action:button" | "action:icon" | "action:menu" | "action:group" | undefined;
4206
4284
  target?: string | undefined;
4207
4285
  body?: {
@@ -4234,6 +4312,17 @@ declare const AiMessageObject: Omit<{
4234
4312
  variant?: "link" | "primary" | "secondary" | "danger" | "ghost" | undefined;
4235
4313
  confirmText?: string | undefined;
4236
4314
  successMessage?: string | undefined;
4315
+ resultDialog?: {
4316
+ title?: string | undefined;
4317
+ description?: string | undefined;
4318
+ acknowledge?: string | undefined;
4319
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
4320
+ fields?: {
4321
+ path: string;
4322
+ label?: string | undefined;
4323
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
4324
+ }[] | undefined;
4325
+ } | undefined;
4237
4326
  visible?: {
4238
4327
  dialect: "cel" | "js" | "cron" | "template";
4239
4328
  source?: string | undefined;
@@ -6118,6 +6207,14 @@ declare const AiTraceObject: Omit<{
6118
6207
  } | undefined;
6119
6208
  recordTypes?: string[] | undefined;
6120
6209
  sharingModel?: "private" | "read" | "full" | "read_write" | undefined;
6210
+ publicSharing?: {
6211
+ enabled: boolean;
6212
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
6213
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
6214
+ maxExpiryDays?: number | undefined;
6215
+ redactFields?: string[] | undefined;
6216
+ eligibility?: string | undefined;
6217
+ } | undefined;
6121
6218
  keyPrefix?: string | undefined;
6122
6219
  detail?: {
6123
6220
  [x: string]: unknown;
@@ -6132,7 +6229,7 @@ declare const AiTraceObject: Omit<{
6132
6229
  refreshAfter: boolean;
6133
6230
  objectName?: string | undefined;
6134
6231
  icon?: string | undefined;
6135
- locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "global_nav")[] | undefined;
6232
+ locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "record_section" | "global_nav")[] | undefined;
6136
6233
  component?: "action:button" | "action:icon" | "action:menu" | "action:group" | undefined;
6137
6234
  target?: string | undefined;
6138
6235
  body?: {
@@ -6165,6 +6262,17 @@ declare const AiTraceObject: Omit<{
6165
6262
  variant?: "link" | "primary" | "secondary" | "danger" | "ghost" | undefined;
6166
6263
  confirmText?: string | undefined;
6167
6264
  successMessage?: string | undefined;
6265
+ resultDialog?: {
6266
+ title?: string | undefined;
6267
+ description?: string | undefined;
6268
+ acknowledge?: string | undefined;
6269
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
6270
+ fields?: {
6271
+ path: string;
6272
+ label?: string | undefined;
6273
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
6274
+ }[] | undefined;
6275
+ } | undefined;
6168
6276
  visible?: {
6169
6277
  dialect: "cel" | "js" | "cron" | "template";
6170
6278
  source?: string | undefined;
@@ -9670,6 +9778,7 @@ declare const AiTraceView: {
9670
9778
  collapsed: boolean;
9671
9779
  columns: 1 | 2 | 3 | 4;
9672
9780
  fields: any[];
9781
+ name?: string | undefined;
9673
9782
  label?: string | undefined;
9674
9783
  description?: string | undefined;
9675
9784
  visibleOn?: {
@@ -9695,6 +9804,7 @@ declare const AiTraceView: {
9695
9804
  collapsed: boolean;
9696
9805
  columns: 1 | 2 | 3 | 4;
9697
9806
  fields: any[];
9807
+ name?: string | undefined;
9698
9808
  label?: string | undefined;
9699
9809
  description?: string | undefined;
9700
9810
  visibleOn?: {
@@ -10018,6 +10128,7 @@ declare const AiTraceView: {
10018
10128
  collapsed: boolean;
10019
10129
  columns: 1 | 2 | 3 | 4;
10020
10130
  fields: any[];
10131
+ name?: string | undefined;
10021
10132
  label?: string | undefined;
10022
10133
  description?: string | undefined;
10023
10134
  visibleOn?: {
@@ -10043,6 +10154,7 @@ declare const AiTraceView: {
10043
10154
  collapsed: boolean;
10044
10155
  columns: 1 | 2 | 3 | 4;
10045
10156
  fields: any[];
10157
+ name?: string | undefined;
10046
10158
  label?: string | undefined;
10047
10159
  description?: string | undefined;
10048
10160
  visibleOn?: {
package/dist/index.d.ts CHANGED
@@ -308,6 +308,20 @@ declare class AIService implements IAIService {
308
308
  private readonly pendingDispatchers;
309
309
  /** Data engine for `ai_pending_actions` persistence. */
310
310
  private readonly dataEngine?;
311
+ /**
312
+ * Auto-title configuration. When `enabled`, the first `chatWithTools` /
313
+ * `streamChatWithTools` call against a still-untitled conversation
314
+ * triggers a one-shot LLM call (fire-and-forget) that summarises the
315
+ * exchange into a short title and PATCHes it onto the conversation row.
316
+ *
317
+ * Defaults to disabled — `AIServicePlugin` flips this on (with values
318
+ * read from the `ai` settings namespace) once the kernel is ready.
319
+ * Keeping the default off means unit tests don't accidentally make
320
+ * extra adapter calls.
321
+ */
322
+ private titleGeneration;
323
+ /** Tracks conversations we've already attempted to title to avoid duplicate LLM calls. */
324
+ private readonly titledConversations;
311
325
  constructor(config?: AIServiceConfig);
312
326
  /** The name of the active LLM adapter. */
313
327
  get adapterName(): string;
@@ -318,6 +332,36 @@ declare class AIService implements IAIService {
318
332
  * subsequent calls go through the new adapter.
319
333
  */
320
334
  setAdapter(next: LLMAdapter): void;
335
+ /**
336
+ * Configure conversation auto-titling. Called by `AIServicePlugin`
337
+ * when the `ai` settings namespace is bound (so admins can toggle
338
+ * the feature live from the Setup app without a restart).
339
+ *
340
+ * - `enabled=false` is the safe default for unit tests and the
341
+ * memory adapter (which would just echo the prompt back as a title).
342
+ * - `maxLength` is enforced both in the prompt and as a hard server-side
343
+ * `slice()` so a misbehaving model can't write a 4 KB "title".
344
+ */
345
+ setTitleGenerationConfig(config: {
346
+ enabled: boolean;
347
+ maxLength?: number;
348
+ }): void;
349
+ /**
350
+ * Best-effort title generation for a conversation. Idempotent per
351
+ * `AIService` instance — once attempted, the id is recorded in
352
+ * `titledConversations` so subsequent chats don't burn extra tokens
353
+ * re-summarising the same thread.
354
+ *
355
+ * Skips when:
356
+ * - feature disabled
357
+ * - conversation already has a non-empty title
358
+ * - conversation has fewer than 2 messages (no exchange to summarise)
359
+ * - conversation has no user message
360
+ *
361
+ * Failures are logged at debug level and swallowed — title generation
362
+ * is purely cosmetic and must never break chat.
363
+ */
364
+ summarizeConversation(conversationId: string): Promise<void>;
321
365
  /**
322
366
  * Best-effort auto-creation of a conversation when the caller did not
323
367
  * supply one but did supply an actor we can attribute the chat to.
@@ -2258,6 +2302,14 @@ declare const AiConversationObject: Omit<{
2258
2302
  } | undefined;
2259
2303
  recordTypes?: string[] | undefined;
2260
2304
  sharingModel?: "private" | "read" | "full" | "read_write" | undefined;
2305
+ publicSharing?: {
2306
+ enabled: boolean;
2307
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
2308
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
2309
+ maxExpiryDays?: number | undefined;
2310
+ redactFields?: string[] | undefined;
2311
+ eligibility?: string | undefined;
2312
+ } | undefined;
2261
2313
  keyPrefix?: string | undefined;
2262
2314
  detail?: {
2263
2315
  [x: string]: unknown;
@@ -2272,7 +2324,7 @@ declare const AiConversationObject: Omit<{
2272
2324
  refreshAfter: boolean;
2273
2325
  objectName?: string | undefined;
2274
2326
  icon?: string | undefined;
2275
- locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "global_nav")[] | undefined;
2327
+ locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "record_section" | "global_nav")[] | undefined;
2276
2328
  component?: "action:button" | "action:icon" | "action:menu" | "action:group" | undefined;
2277
2329
  target?: string | undefined;
2278
2330
  body?: {
@@ -2305,6 +2357,17 @@ declare const AiConversationObject: Omit<{
2305
2357
  variant?: "link" | "primary" | "secondary" | "danger" | "ghost" | undefined;
2306
2358
  confirmText?: string | undefined;
2307
2359
  successMessage?: string | undefined;
2360
+ resultDialog?: {
2361
+ title?: string | undefined;
2362
+ description?: string | undefined;
2363
+ acknowledge?: string | undefined;
2364
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
2365
+ fields?: {
2366
+ path: string;
2367
+ label?: string | undefined;
2368
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
2369
+ }[] | undefined;
2370
+ } | undefined;
2308
2371
  visible?: {
2309
2372
  dialect: "cel" | "js" | "cron" | "template";
2310
2373
  source?: string | undefined;
@@ -2348,6 +2411,13 @@ declare const AiConversationObject: Omit<{
2348
2411
  readonly icon: "message-square";
2349
2412
  readonly isSystem: true;
2350
2413
  readonly description: "Persistent AI conversation metadata";
2414
+ readonly publicSharing: {
2415
+ readonly enabled: true;
2416
+ readonly allowedAudiences: ["link_only", "signed_in"];
2417
+ readonly allowedPermissions: ["view"];
2418
+ readonly maxExpiryDays: 90;
2419
+ readonly redactFields: ["metadata"];
2420
+ };
2351
2421
  readonly fields: {
2352
2422
  readonly id: {
2353
2423
  readonly readonly?: boolean | undefined;
@@ -4187,6 +4257,14 @@ declare const AiMessageObject: Omit<{
4187
4257
  } | undefined;
4188
4258
  recordTypes?: string[] | undefined;
4189
4259
  sharingModel?: "private" | "read" | "full" | "read_write" | undefined;
4260
+ publicSharing?: {
4261
+ enabled: boolean;
4262
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
4263
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
4264
+ maxExpiryDays?: number | undefined;
4265
+ redactFields?: string[] | undefined;
4266
+ eligibility?: string | undefined;
4267
+ } | undefined;
4190
4268
  keyPrefix?: string | undefined;
4191
4269
  detail?: {
4192
4270
  [x: string]: unknown;
@@ -4201,7 +4279,7 @@ declare const AiMessageObject: Omit<{
4201
4279
  refreshAfter: boolean;
4202
4280
  objectName?: string | undefined;
4203
4281
  icon?: string | undefined;
4204
- locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "global_nav")[] | undefined;
4282
+ locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "record_section" | "global_nav")[] | undefined;
4205
4283
  component?: "action:button" | "action:icon" | "action:menu" | "action:group" | undefined;
4206
4284
  target?: string | undefined;
4207
4285
  body?: {
@@ -4234,6 +4312,17 @@ declare const AiMessageObject: Omit<{
4234
4312
  variant?: "link" | "primary" | "secondary" | "danger" | "ghost" | undefined;
4235
4313
  confirmText?: string | undefined;
4236
4314
  successMessage?: string | undefined;
4315
+ resultDialog?: {
4316
+ title?: string | undefined;
4317
+ description?: string | undefined;
4318
+ acknowledge?: string | undefined;
4319
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
4320
+ fields?: {
4321
+ path: string;
4322
+ label?: string | undefined;
4323
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
4324
+ }[] | undefined;
4325
+ } | undefined;
4237
4326
  visible?: {
4238
4327
  dialect: "cel" | "js" | "cron" | "template";
4239
4328
  source?: string | undefined;
@@ -6118,6 +6207,14 @@ declare const AiTraceObject: Omit<{
6118
6207
  } | undefined;
6119
6208
  recordTypes?: string[] | undefined;
6120
6209
  sharingModel?: "private" | "read" | "full" | "read_write" | undefined;
6210
+ publicSharing?: {
6211
+ enabled: boolean;
6212
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
6213
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
6214
+ maxExpiryDays?: number | undefined;
6215
+ redactFields?: string[] | undefined;
6216
+ eligibility?: string | undefined;
6217
+ } | undefined;
6121
6218
  keyPrefix?: string | undefined;
6122
6219
  detail?: {
6123
6220
  [x: string]: unknown;
@@ -6132,7 +6229,7 @@ declare const AiTraceObject: Omit<{
6132
6229
  refreshAfter: boolean;
6133
6230
  objectName?: string | undefined;
6134
6231
  icon?: string | undefined;
6135
- locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "global_nav")[] | undefined;
6232
+ locations?: ("list_toolbar" | "list_item" | "record_header" | "record_more" | "record_related" | "record_section" | "global_nav")[] | undefined;
6136
6233
  component?: "action:button" | "action:icon" | "action:menu" | "action:group" | undefined;
6137
6234
  target?: string | undefined;
6138
6235
  body?: {
@@ -6165,6 +6262,17 @@ declare const AiTraceObject: Omit<{
6165
6262
  variant?: "link" | "primary" | "secondary" | "danger" | "ghost" | undefined;
6166
6263
  confirmText?: string | undefined;
6167
6264
  successMessage?: string | undefined;
6265
+ resultDialog?: {
6266
+ title?: string | undefined;
6267
+ description?: string | undefined;
6268
+ acknowledge?: string | undefined;
6269
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
6270
+ fields?: {
6271
+ path: string;
6272
+ label?: string | undefined;
6273
+ format?: "secret" | "text" | "json" | "qrcode" | "code-list" | undefined;
6274
+ }[] | undefined;
6275
+ } | undefined;
6168
6276
  visible?: {
6169
6277
  dialect: "cel" | "js" | "cron" | "template";
6170
6278
  source?: string | undefined;
@@ -9670,6 +9778,7 @@ declare const AiTraceView: {
9670
9778
  collapsed: boolean;
9671
9779
  columns: 1 | 2 | 3 | 4;
9672
9780
  fields: any[];
9781
+ name?: string | undefined;
9673
9782
  label?: string | undefined;
9674
9783
  description?: string | undefined;
9675
9784
  visibleOn?: {
@@ -9695,6 +9804,7 @@ declare const AiTraceView: {
9695
9804
  collapsed: boolean;
9696
9805
  columns: 1 | 2 | 3 | 4;
9697
9806
  fields: any[];
9807
+ name?: string | undefined;
9698
9808
  label?: string | undefined;
9699
9809
  description?: string | undefined;
9700
9810
  visibleOn?: {
@@ -10018,6 +10128,7 @@ declare const AiTraceView: {
10018
10128
  collapsed: boolean;
10019
10129
  columns: 1 | 2 | 3 | 4;
10020
10130
  fields: any[];
10131
+ name?: string | undefined;
10021
10132
  label?: string | undefined;
10022
10133
  description?: string | undefined;
10023
10134
  visibleOn?: {
@@ -10043,6 +10154,7 @@ declare const AiTraceView: {
10043
10154
  collapsed: boolean;
10044
10155
  columns: 1 | 2 | 3 | 4;
10045
10156
  fields: any[];
10157
+ name?: string | undefined;
10046
10158
  label?: string | undefined;
10047
10159
  description?: string | undefined;
10048
10160
  visibleOn?: {