@agent-native/core 0.214.0 → 0.217.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.
Files changed (196) hide show
  1. package/dist/action.js +54 -1
  2. package/dist/agent/actions/disconnect-chatgpt-subscription.js +5 -0
  3. package/dist/agent/actions/get-agentkit-capabilities.js +3 -3
  4. package/dist/agent/actions/manage-builder-connection.js +5 -0
  5. package/dist/agent/actions/manage-provider-key-policy.js +5 -0
  6. package/dist/agent/actions/manage-provider-models.js +5 -0
  7. package/dist/agent/actions/manage-service-providers.js +5 -0
  8. package/dist/agent/actions/select-chatgpt-subscription-account.js +5 -0
  9. package/dist/agent/context-xray/actions/context-evict.js +5 -0
  10. package/dist/agent/context-xray/actions/context-pin.js +5 -0
  11. package/dist/agent/context-xray/actions/context-report.js +5 -0
  12. package/dist/agent/context-xray/actions/context-restore.js +5 -0
  13. package/dist/agent/execution-fence.d.ts +1 -0
  14. package/dist/agent/execution-fence.js +5 -0
  15. package/dist/agent/production-agent.d.ts +35 -2
  16. package/dist/agent/production-agent.js +629 -32
  17. package/dist/agent/run-manager.d.ts +2 -0
  18. package/dist/agent/run-manager.js +397 -115
  19. package/dist/agent/run-slot-lock.d.ts +2 -0
  20. package/dist/agent/run-slot-lock.js +6 -0
  21. package/dist/agent/run-store.d.ts +5 -0
  22. package/dist/agent/run-store.js +423 -156
  23. package/dist/agent/thread-data-builder.js +27 -5
  24. package/dist/agent/types.d.ts +6 -12
  25. package/dist/agentkit/capabilities.d.ts +1 -1
  26. package/dist/app-config/analytics.js +1 -1
  27. package/dist/application-state/store.d.ts +5 -0
  28. package/dist/application-state/store.js +26 -0
  29. package/dist/automation/index.d.ts +1 -1
  30. package/dist/chat-threads/schema-migrations.js +17 -0
  31. package/dist/chat-threads/store.d.ts +21 -1
  32. package/dist/chat-threads/store.js +223 -41
  33. package/dist/cli/skills-content/turn-into-app-skill.d.ts +1 -1
  34. package/dist/cli/skills-content/turn-into-app-skill.js +20 -18
  35. package/dist/cli/templates-meta.js +14 -0
  36. package/dist/client/analytics-session.d.ts +7 -0
  37. package/dist/client/analytics-session.js +27 -1
  38. package/dist/client/analytics.js +276 -31
  39. package/dist/client/chat/agentkit-agent-native.js +79 -3
  40. package/dist/client/chat/agentkit-protocol.js +80 -42
  41. package/dist/client/chat/runtime.d.ts +5 -1
  42. package/dist/client/chat/runtime.js +46 -3
  43. package/dist/client/consent.d.ts +48 -0
  44. package/dist/client/consent.js +413 -0
  45. package/dist/client/onboarding/index.d.ts +1 -0
  46. package/dist/client/onboarding/index.js +1 -0
  47. package/dist/client/onboarding/use-onboarding-checklist.d.ts +23 -0
  48. package/dist/client/onboarding/use-onboarding-checklist.js +115 -0
  49. package/dist/client/review/use-review.d.ts +2 -0
  50. package/dist/client/review/use-review.js +28 -1
  51. package/dist/client/session-replay.d.ts +1 -1
  52. package/dist/client/session-replay.js +142 -3
  53. package/dist/client/sharing/useResourceAccessGate.d.ts +3 -2
  54. package/dist/client/sharing/useResourceAccessGate.js +9 -1
  55. package/dist/client/use-chat-thread-list.d.ts +2 -0
  56. package/dist/client/use-chat-thread-list.js +12 -2
  57. package/dist/client/use-chat-threads.d.ts +1 -0
  58. package/dist/client/use-chat-threads.js +2 -0
  59. package/dist/collab/awareness.d.ts +2 -2
  60. package/dist/connections/catalog.d.ts +5 -5
  61. package/dist/connections/catalog.js +22 -3
  62. package/dist/data-widgets/index.d.ts +36 -2
  63. package/dist/data-widgets/index.js +94 -6
  64. package/dist/db/migrations.js +4 -1
  65. package/dist/db/schema-snapshot.generated.js +8 -1
  66. package/dist/feature-flags/actions/set-feature-flag.js +5 -0
  67. package/dist/feature-flags/index.d.ts +1 -1
  68. package/dist/feature-flags/index.js +1 -1
  69. package/dist/feature-flags/store.d.ts +12 -0
  70. package/dist/feature-flags/store.js +79 -7
  71. package/dist/file-upload/actions/manage-file-storage.js +5 -0
  72. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  73. package/dist/file-upload/actions/upload-image.js +5 -0
  74. package/dist/history/actions/create-resource-version.js +5 -0
  75. package/dist/history/actions/restore-resource-version.js +5 -0
  76. package/dist/ingestion/index.d.ts +1 -1
  77. package/dist/ingestion/index.js +1 -1
  78. package/dist/ingestion/pptx.d.ts +11 -0
  79. package/dist/ingestion/pptx.js +81 -1
  80. package/dist/integrations/actions/manage-messaging-channel.js +5 -0
  81. package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
  82. package/dist/jobs/scheduler.js +17 -1
  83. package/dist/labs/actions/set-lab.js +5 -0
  84. package/dist/localization/actions/set-localization-preference.js +5 -0
  85. package/dist/localization/consent-banner-messages.d.ts +16 -0
  86. package/dist/localization/consent-banner-messages.js +149 -0
  87. package/dist/localization/core-messages.js +4 -0
  88. package/dist/localization/default-messages.d.ts +1 -0
  89. package/dist/localization/default-messages.js +2 -0
  90. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  91. package/dist/notifications/routes.d.ts +2 -2
  92. package/dist/observability/actions/save-observability-instruction-update.js +5 -0
  93. package/dist/observability/actions/save-observability-review-summary.js +5 -0
  94. package/dist/observability/routes.d.ts +6 -6
  95. package/dist/onboarding/index.d.ts +2 -1
  96. package/dist/onboarding/index.js +1 -0
  97. package/dist/onboarding/plugin.js +55 -46
  98. package/dist/onboarding/status.d.ts +15 -0
  99. package/dist/onboarding/status.js +59 -0
  100. package/dist/onboarding/types.d.ts +12 -0
  101. package/dist/onboarding/types.js +2 -1
  102. package/dist/org/workspace-app-access.js +19 -9
  103. package/dist/progress/routes.d.ts +1 -1
  104. package/dist/provider-api/actions/custom-provider-registration.d.ts +16 -16
  105. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  106. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  107. package/dist/provider-api/index.js +9 -2
  108. package/dist/resources/handlers.d.ts +1 -1
  109. package/dist/review/actions/consume-review-feedback.js +5 -0
  110. package/dist/review/actions/create-review-comment.js +5 -0
  111. package/dist/review/actions/delete-review-comment.js +5 -0
  112. package/dist/review/actions/react-to-review-comment.js +5 -0
  113. package/dist/review/actions/reply-review-comment.js +5 -0
  114. package/dist/review/actions/resolve-review-thread.js +5 -0
  115. package/dist/review/actions/send-review-thread-to-agent.js +5 -0
  116. package/dist/review/actions/set-review-status.js +5 -0
  117. package/dist/review/actions/set-review-thread-muted.js +5 -0
  118. package/dist/review/actions/set-review-thread-unread.js +5 -0
  119. package/dist/review/actions/set-review-threads-unread.js +5 -0
  120. package/dist/review/actions/update-review-comment-anchor.js +5 -0
  121. package/dist/review/actions/update-review-comment.js +5 -0
  122. package/dist/review/suggestions/actions.js +60 -21
  123. package/dist/review/suggestions/store.d.ts +2 -0
  124. package/dist/review/suggestions/store.js +28 -0
  125. package/dist/secrets/actions/delete-api-key.js +5 -0
  126. package/dist/secrets/routes.d.ts +6 -6
  127. package/dist/server/agent-capabilities.js +13 -6
  128. package/dist/server/agent-chat/context-tools.js +63 -2
  129. package/dist/server/agent-chat-plugin.d.ts +2 -0
  130. package/dist/server/agent-chat-plugin.js +242 -54
  131. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  132. package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
  133. package/dist/server/analytics.d.ts +0 -1
  134. package/dist/server/analytics.js +81 -20
  135. package/dist/server/application-state-maintenance.d.ts +2 -0
  136. package/dist/server/application-state-maintenance.js +2 -0
  137. package/dist/server/attribution.d.ts +14 -0
  138. package/dist/server/attribution.js +62 -2
  139. package/dist/server/auth.js +7 -0
  140. package/dist/server/builder-api-auth.d.ts +7 -0
  141. package/dist/server/builder-api-auth.js +24 -0
  142. package/dist/server/builder-oauth.d.ts +5 -1
  143. package/dist/server/builder-oauth.js +5 -0
  144. package/dist/server/consent-route.d.ts +41 -0
  145. package/dist/server/consent-route.js +102 -0
  146. package/dist/server/core-routes-plugin.d.ts +1 -1
  147. package/dist/server/first-touch-route.d.ts +39 -0
  148. package/dist/server/first-touch-route.js +115 -0
  149. package/dist/server/index.d.ts +2 -1
  150. package/dist/server/index.js +2 -1
  151. package/dist/server/queued-submission-inbox-drain.d.ts +9 -0
  152. package/dist/server/queued-submission-inbox-drain.js +12 -0
  153. package/dist/server/request-origin.d.ts +6 -0
  154. package/dist/server/request-origin.js +12 -0
  155. package/dist/settings/org-settings.d.ts +2 -1
  156. package/dist/settings/org-settings.js +4 -1
  157. package/dist/settings/store.d.ts +8 -0
  158. package/dist/settings/store.js +14 -5
  159. package/dist/shared/consent.d.ts +33 -0
  160. package/dist/shared/consent.js +149 -0
  161. package/dist/shared/first-touch-persistence.d.ts +31 -0
  162. package/dist/shared/first-touch-persistence.js +53 -0
  163. package/dist/sharing/actions/set-resource-visibility.js +5 -0
  164. package/dist/sharing/actions/share-resource.js +5 -0
  165. package/dist/sharing/actions/unshare-resource.js +5 -0
  166. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  167. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  168. package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  169. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  170. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  171. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  172. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  173. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
  174. package/dist/triggers/actions/manage-automation.d.ts +4 -4
  175. package/dist/usage/actions/get-usage-metrics.js +27 -4
  176. package/dist/usage/actions/manage-usage-alert.js +5 -0
  177. package/dist/vite/client.js +8 -6
  178. package/dist/workspace-connections/actions/bulk-update-workspace-user-groups.js +5 -0
  179. package/dist/workspace-connections/actions/delete-workspace-user-group.js +5 -0
  180. package/dist/workspace-connections/actions/upsert-workspace-user-group.js +5 -0
  181. package/docs/content/actions-access-control.mdx +8 -8
  182. package/docs/content/actions-defining.mdx +9 -8
  183. package/docs/content/deployment-environment-variables.mdx +1 -1
  184. package/docs/content/environment-variables.mdx +1 -1
  185. package/docs/content/template-design-developers.mdx +9 -9
  186. package/docs/content/template-design-features.mdx +1 -3
  187. package/docs/content/turn-into-app.mdx +4 -0
  188. package/package.json +6 -3
  189. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  190. package/src/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  191. package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  192. package/src/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  193. package/src/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  194. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  195. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  196. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
@@ -27,6 +27,9 @@ export interface DataWidgetAction {
27
27
  href: string;
28
28
  icon?: DataWidgetActionIcon;
29
29
  }
30
+ export interface DataWidgetChartAction extends DataWidgetAction {
31
+ presentation?: "icon";
32
+ }
30
33
  export interface DataChartWidget {
31
34
  type: "bar" | "line" | "area";
32
35
  title?: string;
@@ -46,11 +49,15 @@ export interface DataChartWidget {
46
49
  axisTitleFontWeight?: 400 | 500;
47
50
  valueLabelFontSize?: number;
48
51
  valueLabelFontWeight?: 400 | 500;
52
+ valueAxisTickInterval?: number;
53
+ /** Fraction of each horizontal-bar category slot left empty; defaults to the existing spacing. */
54
+ horizontalCategoryGapRatio?: number;
49
55
  xKey: string;
50
56
  series: DataChartSeriesDefinition[];
51
57
  data: Array<Record<string, unknown>>;
52
58
  sampled?: boolean;
53
- actions?: DataWidgetAction[];
59
+ truncated?: boolean;
60
+ actions?: DataWidgetChartAction[];
54
61
  }
55
62
  export interface DataWidgetDisplay {
56
63
  title?: string;
@@ -70,6 +77,7 @@ export type DataWidgetDisplayAction = {
70
77
  label: string;
71
78
  href: string;
72
79
  icon?: DataWidgetActionIcon;
80
+ presentation?: "icon";
73
81
  } | {
74
82
  id?: string;
75
83
  type: "copy";
@@ -109,6 +117,7 @@ export type DataInsightsWidgetResult<Input extends DataInsightsWidgetResultInput
109
117
  widget: typeof DATA_INSIGHTS_WIDGET;
110
118
  };
111
119
  export type DataWidgetResult = DataTableWidgetResult | DataChartWidgetResult | DataInsightsWidgetResult;
120
+ export declare const DATA_WIDGET_MAX_CHART_POINTS = 200;
112
121
  export declare function normalizeDataWidgetKind(value: unknown): DataWidgetKind | null;
113
122
  export declare function isDataTableWidget(value: unknown): value is DataTableWidget;
114
123
  export declare function isDataChartWidget(value: unknown): value is DataChartWidget;
@@ -126,7 +135,6 @@ export declare function createDataInsightsWidgetResult<const Input extends DataI
126
135
  export declare function normalizeDataWidgetResult(value: unknown): DataWidgetResult | null;
127
136
  export declare function isDataWidgetResult(value: unknown): value is DataWidgetResult;
128
137
  export declare const DATA_WIDGET_MAX_ROWS = 50;
129
- export declare const DATA_WIDGET_MAX_CHART_POINTS = 200;
130
138
  export declare function clampDataWidgetRows(result: DataWidgetResult): DataWidgetResult;
131
139
  export declare const dataTableWidgetSchema: z.ZodObject<{
132
140
  title: z.ZodOptional<z.ZodString>;
@@ -169,6 +177,8 @@ export declare const dataChartWidgetSchema: z.ZodObject<{
169
177
  axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
170
178
  valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
171
179
  valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
180
+ valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
181
+ horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
172
182
  xKey: z.ZodString;
173
183
  series: z.ZodArray<z.ZodObject<{
174
184
  key: z.ZodString;
@@ -177,6 +187,7 @@ export declare const dataChartWidgetSchema: z.ZodObject<{
177
187
  }, z.core.$loose>>;
178
188
  data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
179
189
  sampled: z.ZodOptional<z.ZodBoolean>;
190
+ truncated: z.ZodOptional<z.ZodBoolean>;
180
191
  actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
181
192
  label: z.ZodString;
182
193
  href: z.ZodString;
@@ -185,6 +196,7 @@ export declare const dataChartWidgetSchema: z.ZodObject<{
185
196
  explore: "explore";
186
197
  notebook: "notebook";
187
198
  }>>;
199
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
188
200
  }, z.core.$loose>>>;
189
201
  }, z.core.$loose>;
190
202
  export declare const dataTableWidgetResultSchema: z.ZodObject<{
@@ -218,6 +230,7 @@ export declare const dataTableWidgetResultSchema: z.ZodObject<{
218
230
  explore: "explore";
219
231
  notebook: "notebook";
220
232
  }>>;
233
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
221
234
  }, z.core.$loose>, z.ZodObject<{
222
235
  id: z.ZodOptional<z.ZodString>;
223
236
  type: z.ZodLiteral<"copy">;
@@ -273,6 +286,7 @@ export declare const dataChartWidgetResultSchema: z.ZodObject<{
273
286
  explore: "explore";
274
287
  notebook: "notebook";
275
288
  }>>;
289
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
276
290
  }, z.core.$loose>, z.ZodObject<{
277
291
  id: z.ZodOptional<z.ZodString>;
278
292
  type: z.ZodLiteral<"copy">;
@@ -307,6 +321,8 @@ export declare const dataChartWidgetResultSchema: z.ZodObject<{
307
321
  axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
308
322
  valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
309
323
  valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
324
+ valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
325
+ horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
310
326
  xKey: z.ZodString;
311
327
  series: z.ZodArray<z.ZodObject<{
312
328
  key: z.ZodString;
@@ -315,6 +331,7 @@ export declare const dataChartWidgetResultSchema: z.ZodObject<{
315
331
  }, z.core.$loose>>;
316
332
  data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
317
333
  sampled: z.ZodOptional<z.ZodBoolean>;
334
+ truncated: z.ZodOptional<z.ZodBoolean>;
318
335
  actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
319
336
  label: z.ZodString;
320
337
  href: z.ZodString;
@@ -323,6 +340,7 @@ export declare const dataChartWidgetResultSchema: z.ZodObject<{
323
340
  explore: "explore";
324
341
  notebook: "notebook";
325
342
  }>>;
343
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
326
344
  }, z.core.$loose>>>;
327
345
  }, z.core.$loose>;
328
346
  }, z.core.$loose>;
@@ -357,6 +375,7 @@ export declare const dataInsightsWidgetResultSchema: z.ZodObject<{
357
375
  explore: "explore";
358
376
  notebook: "notebook";
359
377
  }>>;
378
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
360
379
  }, z.core.$loose>, z.ZodObject<{
361
380
  id: z.ZodOptional<z.ZodString>;
362
381
  type: z.ZodLiteral<"copy">;
@@ -406,6 +425,8 @@ export declare const dataInsightsWidgetResultSchema: z.ZodObject<{
406
425
  axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
407
426
  valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
408
427
  valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
428
+ valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
429
+ horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
409
430
  xKey: z.ZodString;
410
431
  series: z.ZodArray<z.ZodObject<{
411
432
  key: z.ZodString;
@@ -414,6 +435,7 @@ export declare const dataInsightsWidgetResultSchema: z.ZodObject<{
414
435
  }, z.core.$loose>>;
415
436
  data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
416
437
  sampled: z.ZodOptional<z.ZodBoolean>;
438
+ truncated: z.ZodOptional<z.ZodBoolean>;
417
439
  actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
418
440
  label: z.ZodString;
419
441
  href: z.ZodString;
@@ -422,6 +444,7 @@ export declare const dataInsightsWidgetResultSchema: z.ZodObject<{
422
444
  explore: "explore";
423
445
  notebook: "notebook";
424
446
  }>>;
447
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
425
448
  }, z.core.$loose>>>;
426
449
  }, z.core.$loose>>;
427
450
  }, z.core.$loose>;
@@ -456,6 +479,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
456
479
  explore: "explore";
457
480
  notebook: "notebook";
458
481
  }>>;
482
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
459
483
  }, z.core.$loose>, z.ZodObject<{
460
484
  id: z.ZodOptional<z.ZodString>;
461
485
  type: z.ZodLiteral<"copy">;
@@ -510,6 +534,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
510
534
  explore: "explore";
511
535
  notebook: "notebook";
512
536
  }>>;
537
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
513
538
  }, z.core.$loose>, z.ZodObject<{
514
539
  id: z.ZodOptional<z.ZodString>;
515
540
  type: z.ZodLiteral<"copy">;
@@ -544,6 +569,8 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
544
569
  axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
545
570
  valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
546
571
  valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
572
+ valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
573
+ horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
547
574
  xKey: z.ZodString;
548
575
  series: z.ZodArray<z.ZodObject<{
549
576
  key: z.ZodString;
@@ -552,6 +579,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
552
579
  }, z.core.$loose>>;
553
580
  data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
554
581
  sampled: z.ZodOptional<z.ZodBoolean>;
582
+ truncated: z.ZodOptional<z.ZodBoolean>;
555
583
  actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
556
584
  label: z.ZodString;
557
585
  href: z.ZodString;
@@ -560,6 +588,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
560
588
  explore: "explore";
561
589
  notebook: "notebook";
562
590
  }>>;
591
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
563
592
  }, z.core.$loose>>>;
564
593
  }, z.core.$loose>;
565
594
  }, z.core.$loose>, z.ZodObject<{
@@ -593,6 +622,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
593
622
  explore: "explore";
594
623
  notebook: "notebook";
595
624
  }>>;
625
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
596
626
  }, z.core.$loose>, z.ZodObject<{
597
627
  id: z.ZodOptional<z.ZodString>;
598
628
  type: z.ZodLiteral<"copy">;
@@ -642,6 +672,8 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
642
672
  axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
643
673
  valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
644
674
  valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
675
+ valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
676
+ horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
645
677
  xKey: z.ZodString;
646
678
  series: z.ZodArray<z.ZodObject<{
647
679
  key: z.ZodString;
@@ -650,6 +682,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
650
682
  }, z.core.$loose>>;
651
683
  data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
652
684
  sampled: z.ZodOptional<z.ZodBoolean>;
685
+ truncated: z.ZodOptional<z.ZodBoolean>;
653
686
  actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
654
687
  label: z.ZodString;
655
688
  href: z.ZodString;
@@ -658,6 +691,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
658
691
  explore: "explore";
659
692
  notebook: "notebook";
660
693
  }>>;
694
+ presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
661
695
  }, z.core.$loose>>>;
662
696
  }, z.core.$loose>>;
663
697
  }, z.core.$loose>]>;
@@ -13,6 +13,71 @@ function isRecord(value) {
13
13
  function isString(value) {
14
14
  return typeof value === "string" && value.length > 0;
15
15
  }
16
+ const MAX_DATA_CHART_AXIS_TICKS = 100;
17
+ export const DATA_WIDGET_MAX_CHART_POINTS = 200;
18
+ function chartRowsForRender(rows) {
19
+ return rows.slice(0, DATA_WIDGET_MAX_CHART_POINTS);
20
+ }
21
+ function numericWidgetValue(value) {
22
+ if (typeof value === "number" && Number.isFinite(value))
23
+ return value;
24
+ if (typeof value !== "string" || !value.trim())
25
+ return null;
26
+ const parsed = Number(value);
27
+ return Number.isFinite(parsed) ? parsed : null;
28
+ }
29
+ function hasBoundedValueAxisTicks(chart) {
30
+ const interval = chart.valueAxisTickInterval;
31
+ if (interval === undefined)
32
+ return true;
33
+ if (typeof interval !== "number" ||
34
+ !Number.isFinite(interval) ||
35
+ interval < 1e-12) {
36
+ return false;
37
+ }
38
+ const series = Array.isArray(chart.series) ? chart.series : [];
39
+ const rows = Array.isArray(chart.data) ? chartRowsForRender(chart.data) : [];
40
+ let min = Number.POSITIVE_INFINITY;
41
+ let max = Number.NEGATIVE_INFINITY;
42
+ for (const row of rows) {
43
+ if (!isRecord(row))
44
+ continue;
45
+ for (const item of series) {
46
+ if (!isRecord(item) || !isString(item.key))
47
+ continue;
48
+ const value = numericWidgetValue(row[item.key]);
49
+ if (value === null)
50
+ continue;
51
+ min = Math.min(min, value);
52
+ max = Math.max(max, value);
53
+ }
54
+ }
55
+ if (!Number.isFinite(min) || !Number.isFinite(max)) {
56
+ min = 0;
57
+ max = 1;
58
+ }
59
+ else {
60
+ if (chart.type === "bar" || chart.type === "area") {
61
+ min = Math.min(0, min);
62
+ max = Math.max(0, max);
63
+ }
64
+ if (min === max) {
65
+ const padding = Math.abs(max || 1) * 0.2;
66
+ min -= padding;
67
+ max += padding;
68
+ }
69
+ }
70
+ if (!Number.isFinite(max - min))
71
+ return false;
72
+ const firstTick = Math.ceil(min / interval - 1e-9);
73
+ const lastTick = Math.floor(max / interval + 1e-9);
74
+ const tickCount = lastTick - firstTick + 1;
75
+ return (Number.isSafeInteger(firstTick) &&
76
+ Number.isSafeInteger(lastTick) &&
77
+ Number.isSafeInteger(tickCount) &&
78
+ tickCount > 0 &&
79
+ tickCount <= MAX_DATA_CHART_AXIS_TICKS);
80
+ }
16
81
  export function normalizeDataWidgetKind(value) {
17
82
  if (value === DATA_TABLE_WIDGET)
18
83
  return DATA_TABLE_WIDGET;
@@ -81,6 +146,14 @@ export function isDataChartWidget(value) {
81
146
  (value.valueLabelFontWeight === undefined ||
82
147
  value.valueLabelFontWeight === 400 ||
83
148
  value.valueLabelFontWeight === 500) &&
149
+ (value.horizontalCategoryGapRatio === undefined ||
150
+ (typeof value.horizontalCategoryGapRatio === "number" &&
151
+ Number.isFinite(value.horizontalCategoryGapRatio) &&
152
+ value.horizontalCategoryGapRatio >= 0 &&
153
+ value.horizontalCategoryGapRatio <= 0.9)) &&
154
+ (value.sampled === undefined || typeof value.sampled === "boolean") &&
155
+ (value.truncated === undefined || typeof value.truncated === "boolean") &&
156
+ hasBoundedValueAxisTicks(value) &&
84
157
  isString(value.xKey) &&
85
158
  Array.isArray(value.series) &&
86
159
  value.series.every((series) => isRecord(series) &&
@@ -89,7 +162,7 @@ export function isDataChartWidget(value) {
89
162
  (series.color === undefined || typeof series.color === "string")) &&
90
163
  (value.actions === undefined ||
91
164
  (Array.isArray(value.actions) &&
92
- value.actions.every(isDataWidgetAction))) &&
165
+ value.actions.every(isDataWidgetChartAction))) &&
93
166
  Array.isArray(value.data) &&
94
167
  value.data.every(isRecord));
95
168
  }
@@ -102,6 +175,11 @@ function isDataWidgetAction(value) {
102
175
  isString(value.href) &&
103
176
  (value.icon === undefined || isDataWidgetActionIcon(value.icon)));
104
177
  }
178
+ function isDataWidgetChartAction(value) {
179
+ const presentation = isRecord(value) ? value.presentation : undefined;
180
+ return (isDataWidgetAction(value) &&
181
+ (presentation === undefined || presentation === "icon"));
182
+ }
105
183
  function normalizePrimaryAction(value) {
106
184
  if (!isRecord(value) || !isString(value.label) || !isString(value.href)) {
107
185
  return undefined;
@@ -126,7 +204,8 @@ function isDataWidgetDisplayAction(value) {
126
204
  }
127
205
  if (value.type === "link") {
128
206
  return (isString(value.href) &&
129
- (value.icon === undefined || isDataWidgetActionIcon(value.icon)));
207
+ (value.icon === undefined || isDataWidgetActionIcon(value.icon)) &&
208
+ (value.presentation === undefined || value.presentation === "icon"));
130
209
  }
131
210
  if (value.type === "copy")
132
211
  return isString(value.text);
@@ -242,7 +321,6 @@ export function isDataWidgetResult(value) {
242
321
  return normalizeDataWidgetResult(value) !== null;
243
322
  }
244
323
  export const DATA_WIDGET_MAX_ROWS = 50;
245
- export const DATA_WIDGET_MAX_CHART_POINTS = 200;
246
324
  export function clampDataWidgetRows(result) {
247
325
  const source = result;
248
326
  const table = source.table;
@@ -259,8 +337,9 @@ export function clampDataWidgetRows(result) {
259
337
  const clampedChart = chartSeries && chartSeries.data.length > DATA_WIDGET_MAX_CHART_POINTS
260
338
  ? {
261
339
  ...chartSeries,
262
- data: chartSeries.data.slice(0, DATA_WIDGET_MAX_CHART_POINTS),
340
+ data: chartRowsForRender(chartSeries.data),
263
341
  sampled: true,
342
+ truncated: true,
264
343
  }
265
344
  : chartSeries;
266
345
  if (clampedTable === table && clampedChart === chartSeries)
@@ -300,6 +379,7 @@ const dataWidgetActionSchema = z
300
379
  label: z.string().min(1),
301
380
  href: z.string().min(1),
302
381
  icon: z.enum(["explore", "camera", "notebook"]).optional(),
382
+ presentation: z.literal("icon").optional(),
303
383
  })
304
384
  .passthrough();
305
385
  export const dataChartWidgetSchema = z
@@ -318,13 +398,20 @@ export const dataChartWidgetSchema = z
318
398
  axisTitleFontWeight: z.union([z.literal(400), z.literal(500)]).optional(),
319
399
  valueLabelFontSize: z.number().int().min(8).max(24).optional(),
320
400
  valueLabelFontWeight: z.union([z.literal(400), z.literal(500)]).optional(),
401
+ valueAxisTickInterval: z.number().finite().min(1e-12).optional(),
402
+ horizontalCategoryGapRatio: z.number().finite().min(0).max(0.9).optional(),
321
403
  xKey: z.string().min(1),
322
404
  series: z.array(dataChartSeriesDefinitionSchema).min(1),
323
405
  data: z.array(z.record(z.string(), z.unknown())),
324
406
  sampled: z.boolean().optional(),
407
+ truncated: z.boolean().optional(),
325
408
  actions: z.array(dataWidgetActionSchema).optional(),
326
409
  })
327
410
  .passthrough();
411
+ const boundedDataChartWidgetSchema = dataChartWidgetSchema.refine(hasBoundedValueAxisTicks, {
412
+ path: ["valueAxisTickInterval"],
413
+ message: `valueAxisTickInterval must produce between 1 and ${MAX_DATA_CHART_AXIS_TICKS} ticks.`,
414
+ });
328
415
  const primaryActionSchema = z
329
416
  .object({
330
417
  label: z.string().min(1),
@@ -347,6 +434,7 @@ const dataWidgetDisplayActionSchema = z.discriminatedUnion("type", [
347
434
  label: z.string().min(1),
348
435
  href: z.string().min(1),
349
436
  icon: z.enum(["explore", "camera", "notebook"]).optional(),
437
+ presentation: z.literal("icon").optional(),
350
438
  })
351
439
  .passthrough(),
352
440
  z
@@ -384,14 +472,14 @@ export const dataTableWidgetResultSchema = dataWidgetBaseSchema
384
472
  export const dataChartWidgetResultSchema = dataWidgetBaseSchema
385
473
  .extend({
386
474
  widget: z.literal(DATA_CHART_WIDGET),
387
- chartSeries: dataChartWidgetSchema,
475
+ chartSeries: boundedDataChartWidgetSchema,
388
476
  })
389
477
  .passthrough();
390
478
  export const dataInsightsWidgetResultSchema = dataWidgetBaseSchema
391
479
  .extend({
392
480
  widget: z.literal(DATA_INSIGHTS_WIDGET),
393
481
  table: dataTableWidgetSchema.optional(),
394
- chartSeries: dataChartWidgetSchema.optional(),
482
+ chartSeries: boundedDataChartWidgetSchema.optional(),
395
483
  })
396
484
  .passthrough()
397
485
  .refine((value) => value.table || value.chartSeries, {
@@ -251,8 +251,11 @@ export function runMigrations(migrationSource, options) {
251
251
  args: [migration.version],
252
252
  });
253
253
  }
254
+ // Callbacks are idempotent by contract (store-registry retries them
255
+ // the same way), so a concurrent CREATE TABLE losing a pg_type race
256
+ // retries instead of escaping and exiting the server.
254
257
  const runResult = migration.run
255
- ? await migration.run(exec)
258
+ ? await retryOnDdlRace(() => migration.run(exec))
256
259
  : undefined;
257
260
  if (runResult === MIGRATION_DEFERRED) {
258
261
  console.info(`[db] Deferred migration ${label}; it remains pending for a later boot`);
@@ -17,7 +17,7 @@ export const SCHEMA_SNAPSHOT = {
17
17
  'CREATE TABLE "a2a_tasks" (\n "id" text NOT NULL,\n "context_id" text,\n "status_state" text DEFAULT \'submitted\'::text NOT NULL,\n "status_message" text,\n "status_timestamp" text NOT NULL,\n "history" text DEFAULT \'[]\'::text NOT NULL,\n "artifacts" text DEFAULT \'[]\'::text NOT NULL,\n "metadata" text,\n "owner_email" text,\n "owner_scope" text DEFAULT \'\'::text NOT NULL,\n "idempotency_key" text,\n "created_at" bigint NOT NULL,\n "updated_at" bigint NOT NULL\n);',
18
18
  'CREATE TABLE "account" (\n "id" text NOT NULL,\n "account_id" text NOT NULL,\n "provider_id" text NOT NULL,\n "user_id" text NOT NULL,\n "access_token" text,\n "refresh_token" text,\n "id_token" text,\n "access_token_expires_at" timestamp with time zone,\n "refresh_token_expires_at" timestamp with time zone,\n "scope" text,\n "password" text,\n "created_at" timestamp with time zone NOT NULL,\n "updated_at" timestamp with time zone NOT NULL\n);',
19
19
  'CREATE TABLE "agent_audit_log" (\n "id" text NOT NULL,\n "created_at" bigint NOT NULL,\n "action" text NOT NULL,\n "caller" text NOT NULL,\n "actor_kind" text NOT NULL,\n "actor_email" text,\n "org_id" text,\n "thread_id" text,\n "turn_id" text,\n "target_type" text,\n "target_id" text,\n "status" text DEFAULT \'success\'::text NOT NULL,\n "summary" text,\n "input" text,\n "error_code" text,\n "owner_email" text,\n "visibility" text DEFAULT \'private\'::text NOT NULL,\n "run_id" text,\n "task_id" text,\n "parent_task_id" text,\n "source_kind" text,\n "source_platform" text,\n "source_id" text,\n "source_url" text,\n "network_protocol" text,\n "network_id" text,\n "network_peer" text,\n "app" text,\n "reported_client_name" text,\n "reported_client_version" text,\n "oauth_client_id" text,\n "approval" text,\n "identity_assurance" text\n);',
20
- 'CREATE TABLE "agent_chat_submission_inbox" (\n "thread_id" text NOT NULL,\n "message_id" text NOT NULL,\n "state" text NOT NULL,\n "actor_email" text NOT NULL,\n "actor_auth_user_id" text,\n "actor_identity_authenticated_at_ms" bigint,\n "actor_name" text,\n "actor_org_id" text,\n "actor_org_scope" text,\n "actor_anonymous" boolean DEFAULT false NOT NULL,\n "payload_hash" text NOT NULL,\n "payload_json" text NOT NULL,\n "interrupt_active_run" boolean DEFAULT false NOT NULL,\n "submitted_run_id" text,\n "queue_order" bigint DEFAULT nextval(\'agent_chat_submission_inbox_queue_order_seq\'::regclass) NOT NULL,\n "move_to_top_at" bigint,\n "retry_after" bigint,\n "created_at" bigint NOT NULL,\n "updated_at" bigint NOT NULL,\n "interrupt_run_id" text\n);',
20
+ 'CREATE TABLE "agent_chat_submission_inbox" (\n "thread_id" text NOT NULL,\n "message_id" text NOT NULL,\n "state" text NOT NULL,\n "actor_email" text NOT NULL,\n "actor_auth_user_id" text,\n "actor_identity_authenticated_at_ms" bigint,\n "actor_name" text,\n "actor_org_id" text,\n "actor_org_scope" text,\n "actor_anonymous" boolean DEFAULT false NOT NULL,\n "payload_hash" text NOT NULL,\n "payload_json" text NOT NULL,\n "interrupt_active_run" boolean DEFAULT false NOT NULL,\n "submitted_run_id" text,\n "queue_order" bigint DEFAULT nextval(\'agent_chat_submission_inbox_queue_order_seq\'::regclass) NOT NULL,\n "move_to_top_at" bigint,\n "retry_after" bigint,\n "created_at" bigint NOT NULL,\n "updated_at" bigint NOT NULL,\n "interrupt_run_id" text,\n "retry_count" integer DEFAULT 0 NOT NULL\n);',
21
21
  'CREATE TABLE "agent_checkpoints" (\n "id" text NOT NULL,\n "thread_id" text NOT NULL,\n "run_id" text,\n "commit_sha" text NOT NULL,\n "message" text DEFAULT \'\'::text NOT NULL,\n "created_at" bigint NOT NULL\n);',
22
22
  'CREATE TABLE "agent_eval_datasets" (\n "id" text NOT NULL,\n "name" text NOT NULL,\n "description" text DEFAULT \'\'::text NOT NULL,\n "entries" text DEFAULT \'[]\'::text NOT NULL,\n "created_at" bigint NOT NULL,\n "updated_at" bigint NOT NULL,\n "user_id" text,\n "idempotency_key" text\n);',
23
23
  'CREATE TABLE "agent_evals" (\n "id" text NOT NULL,\n "run_id" text NOT NULL,\n "thread_id" text,\n "user_id" text,\n "eval_type" text NOT NULL,\n "criteria" text NOT NULL,\n "score" real DEFAULT 0 NOT NULL,\n "reasoning" text,\n "metadata" text,\n "created_at" bigint NOT NULL\n);',
@@ -389,6 +389,7 @@ export const SCHEMA_SNAPSHOT = {
389
389
  "CREATE INDEX idx_audit_target ON public.agent_audit_log USING btree (target_type, target_id, created_at);",
390
390
  "CREATE INDEX idx_audit_turn ON public.agent_audit_log USING btree (turn_id);",
391
391
  "CREATE INDEX agent_chat_submission_inbox_pending_idx ON public.agent_chat_submission_inbox USING btree (state, retry_after, interrupt_active_run DESC, move_to_top_at DESC, queue_order);",
392
+ "CREATE INDEX agent_chat_submission_inbox_thread_pending_idx ON public.agent_chat_submission_inbox USING btree (thread_id, interrupt_active_run DESC, move_to_top_at DESC, queue_order) WHERE (state = 'queued'::text);",
392
393
  "CREATE INDEX agent_checkpoints_run_idx ON public.agent_checkpoints USING btree (run_id);",
393
394
  "CREATE INDEX agent_checkpoints_thread_created_idx ON public.agent_checkpoints USING btree (thread_id, created_at);",
394
395
  "CREATE UNIQUE INDEX idx_eval_datasets_idempotency ON public.agent_eval_datasets USING btree (idempotency_key);",
@@ -959,6 +960,12 @@ export const SCHEMA_SNAPSHOT = {
959
960
  "953882e24b68e4fb",
960
961
  ],
961
962
  ["chat_threads", "chat-thread-inbox-interrupt-replay", "904890f43aebd9fe"],
963
+ ["chat_threads", "chat-thread-inbox-retry-count", "b25ff25b6a61ccc9"],
964
+ [
965
+ "chat_threads",
966
+ "chat-thread-inbox-thread-order-index",
967
+ "78d46649cafade48",
968
+ ],
962
969
  ["chat_threads", "chat-thread-shares-notified-at", "f2a3dce63fe66310"],
963
970
  ["chat_threads", "chat-threads-base-tables", "bfeaaa8ca4af1288"],
964
971
  [
@@ -41,6 +41,11 @@ export default defineAction({
41
41
  }),
42
42
  summary: (args) => `Feature flag ${args.key}: ${args.operation}`,
43
43
  },
44
+ mcpAnnotations: {
45
+ readOnlyHint: false,
46
+ destructiveHint: true,
47
+ openWorldHint: false,
48
+ },
44
49
  run: async (args, ctx) => {
45
50
  const manager = await requireFeatureFlagManager(ctx ?? {});
46
51
  if (!getFeatureFlagDefinition(args.key)) {
@@ -1,2 +1,2 @@
1
1
  export { BUILDER_CREDIT_USAGE_REPORTING_FLAG, CONNECT_APPS_FLAG, defineFeatureFlag, defineFeatureFlags, getFeatureFlagDefinition, listFeatureFlags, registerFeatureFlags, SETTINGS_REDESIGN_FLAG, type FeatureFlagDefinition, } from "./registry.js";
2
- export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./store.js";
2
+ export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, FeatureFlagRulesError, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, getFeatureFlagRules, getFeatureFlagRulesStrict, normalizeFeatureFlagRules, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./store.js";
@@ -1,2 +1,2 @@
1
1
  export { BUILDER_CREDIT_USAGE_REPORTING_FLAG, CONNECT_APPS_FLAG, defineFeatureFlag, defineFeatureFlags, getFeatureFlagDefinition, listFeatureFlags, registerFeatureFlags, SETTINGS_REDESIGN_FLAG, } from "./registry.js";
2
- export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, } from "./store.js";
2
+ export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, FeatureFlagRulesError, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, getFeatureFlagRules, getFeatureFlagRulesStrict, normalizeFeatureFlagRules, } from "./store.js";
@@ -20,6 +20,18 @@ export declare const FEATURE_FLAG_SETTINGS_PREFIX = "feature-flag:";
20
20
  export declare function defaultFeatureFlagRules(): FeatureFlagRules;
21
21
  export declare function normalizeFeatureFlagRules(value: unknown): FeatureFlagRules;
22
22
  export declare function getFeatureFlagRules(key: string, scope: Pick<FeatureFlagScope, "orgId" | "transaction">): Promise<FeatureFlagRules>;
23
+ export declare class FeatureFlagRulesError extends Error {
24
+ readonly code: "unregistered" | "malformed";
25
+ readonly key: string;
26
+ constructor(code: "unregistered" | "malformed", key: string, detail: string);
27
+ }
28
+ /**
29
+ * Reads a flag's rules for callers that route data on it. Unconfigured reads
30
+ * as off, like `getFeatureFlagRules`, but an unregistered key or malformed
31
+ * stored rules throw `FeatureFlagRulesError` instead of normalizing to off:
32
+ * for a routing flag, "off" and "unreadable" choose different write paths.
33
+ */
34
+ export declare function getFeatureFlagRulesStrict(key: string, scope: Pick<FeatureFlagScope, "orgId" | "transaction">): Promise<FeatureFlagRules>;
23
35
  export declare function getFeatureFlagRulesForKeys(keys: readonly string[], scope: Pick<FeatureFlagScope, "orgId" | "transaction">): Promise<Map<string, FeatureFlagRules>>;
24
36
  /**
25
37
  * Anonymous discovery hint for a rollout that may be scoped to an org.
@@ -1,6 +1,6 @@
1
1
  import { getDbExec } from "../db/client.js";
2
- import { getOrgSetting, mutateOrgSetting } from "../settings/org-settings.js";
3
- import { getSetting, getSettings, mutateSetting } from "../settings/store.js";
2
+ import { getOrgSetting, getOrgSettingEntry, mutateOrgSetting, } from "../settings/org-settings.js";
3
+ import { getSetting, getSettingEntry, getSettings, mutateSetting, } from "../settings/store.js";
4
4
  import { getFeatureFlagDefinition, } from "./registry.js";
5
5
  export const FEATURE_FLAG_SETTINGS_PREFIX = "feature-flag:";
6
6
  const FEATURE_FLAG_ROLLOUT_INDEX_PREFIX = "feature-flag-rollout-index:";
@@ -113,17 +113,89 @@ export function normalizeFeatureFlagRules(value) {
113
113
  : null,
114
114
  };
115
115
  }
116
- export async function getFeatureFlagRules(key, scope) {
117
- if (!getFeatureFlagDefinition(key))
118
- return defaultFeatureFlagRules();
116
+ async function readStoredFeatureFlagRules(key, scope) {
119
117
  const orgId = scope.orgId?.trim();
120
118
  if (!orgId)
121
- return normalizeFeatureFlagRules(await getSetting(settingKey(key), { transaction: scope.transaction }));
119
+ return getSetting(settingKey(key), { transaction: scope.transaction });
122
120
  const [orgStored, globalStored] = await Promise.all([
123
121
  getOrgSetting(orgId, settingKey(key), { transaction: scope.transaction }),
124
122
  getSetting(settingKey(key), { transaction: scope.transaction }),
125
123
  ]);
126
- return normalizeFeatureFlagRules(orgStored ?? globalStored);
124
+ return orgStored ?? globalStored;
125
+ }
126
+ export async function getFeatureFlagRules(key, scope) {
127
+ if (!getFeatureFlagDefinition(key))
128
+ return defaultFeatureFlagRules();
129
+ return normalizeFeatureFlagRules(await readStoredFeatureFlagRules(key, scope));
130
+ }
131
+ export class FeatureFlagRulesError extends Error {
132
+ code;
133
+ key;
134
+ constructor(code, key, detail) {
135
+ super(`Feature flag ${key}: ${detail}`);
136
+ this.code = code;
137
+ this.key = key;
138
+ this.name = "FeatureFlagRulesError";
139
+ }
140
+ }
141
+ async function readStoredFeatureFlagRulesEntry(key, scope) {
142
+ const orgId = scope.orgId?.trim();
143
+ const options = { transaction: scope.transaction };
144
+ if (!orgId)
145
+ return getSettingEntry(settingKey(key), options);
146
+ const [orgEntry, globalEntry] = await Promise.all([
147
+ getOrgSettingEntry(orgId, settingKey(key), options),
148
+ getSettingEntry(settingKey(key), options),
149
+ ]);
150
+ return orgEntry.found ? orgEntry : globalEntry;
151
+ }
152
+ function storedRulesProblem(stored) {
153
+ if (!stored || typeof stored !== "object" || Array.isArray(stored))
154
+ return `stored rules are ${stored === null ? "null" : Array.isArray(stored) ? "a list" : typeof stored}, not an object`;
155
+ const value = stored;
156
+ if (value.version !== 1)
157
+ return `stored version ${JSON.stringify(value.version) ?? "undefined"} is not 1`;
158
+ if (value.mode !== "off" && value.mode !== "on" && value.mode !== "rules")
159
+ return `stored mode ${JSON.stringify(value.mode)} is not off, on, or rules`;
160
+ for (const field of ["emails", "orgIds"]) {
161
+ const list = value[field];
162
+ if (list !== undefined &&
163
+ !(Array.isArray(list) && list.every((item) => typeof item === "string")))
164
+ return `stored ${field} is not a list of strings`;
165
+ }
166
+ const percentage = value.percentage;
167
+ if (percentage !== undefined &&
168
+ !(typeof percentage === "number" &&
169
+ Number.isInteger(percentage) &&
170
+ percentage >= 0 &&
171
+ percentage <= 100))
172
+ return "stored percentage is not a whole number from 0 to 100";
173
+ return null;
174
+ }
175
+ /**
176
+ * Reads a flag's rules for callers that route data on it. Unconfigured reads
177
+ * as off, like `getFeatureFlagRules`, but an unregistered key or malformed
178
+ * stored rules throw `FeatureFlagRulesError` instead of normalizing to off:
179
+ * for a routing flag, "off" and "unreadable" choose different write paths.
180
+ */
181
+ export async function getFeatureFlagRulesStrict(key, scope) {
182
+ if (!getFeatureFlagDefinition(key))
183
+ throw new FeatureFlagRulesError("unregistered", key, "not registered");
184
+ let stored;
185
+ try {
186
+ stored = await readStoredFeatureFlagRulesEntry(key, scope);
187
+ }
188
+ catch (error) {
189
+ if (error instanceof SyntaxError)
190
+ throw new FeatureFlagRulesError("malformed", key, "stored rules are not JSON");
191
+ throw error;
192
+ }
193
+ if (!stored.found)
194
+ return defaultFeatureFlagRules();
195
+ const problem = storedRulesProblem(stored.value);
196
+ if (problem)
197
+ throw new FeatureFlagRulesError("malformed", key, problem);
198
+ return normalizeFeatureFlagRules(stored.value);
127
199
  }
128
200
  export async function getFeatureFlagRulesForKeys(keys, scope) {
129
201
  const uniqueKeys = [...new Set(keys)].filter((key) => getFeatureFlagDefinition(key));
@@ -27,6 +27,11 @@ export default defineAction({
27
27
  ? "Cleared file storage credentials"
28
28
  : "Saved file storage settings",
29
29
  }),
30
+ mcpAnnotations: {
31
+ readOnlyHint: false,
32
+ destructiveHint: true,
33
+ openWorldHint: false,
34
+ },
30
35
  run: async ({ operation, ...values }, ctx) => operation === "clear"
31
36
  ? clearFileStorage(ctx)
32
37
  : { removedKeys: [], status: await saveFileStorage(ctx, values) },
@@ -42,8 +42,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
42
42
  url: string;
43
43
  id: string;
44
44
  provider: string;
45
- error?: undefined;
46
45
  configured?: undefined;
46
+ error?: undefined;
47
47
  } | {
48
48
  url?: undefined;
49
49
  id?: undefined;
@@ -442,6 +442,11 @@ export default defineAction({
442
442
  .refine((args) => args.cleanup ? !!args.idempotencyKey : !!args.data || !!args.url, {
443
443
  message: "Either a data/url upload or an idempotencyKey cleanup is required.",
444
444
  }),
445
+ mcpAnnotations: {
446
+ readOnlyHint: false,
447
+ destructiveHint: true,
448
+ openWorldHint: true,
449
+ },
445
450
  run: async (args) => {
446
451
  const idempotencyKey = args.idempotencyKey?.trim();
447
452
  if (args.cleanup && idempotencyKey) {
@@ -13,6 +13,11 @@ const schema = z.object({
13
13
  export default defineAction({
14
14
  description: "Create a reusable version-history snapshot for a resource.",
15
15
  schema,
16
+ mcpAnnotations: {
17
+ readOnlyHint: false,
18
+ destructiveHint: false,
19
+ openWorldHint: false,
20
+ },
16
21
  run: async (args, ctx) => {
17
22
  const actionCtx = ctx;
18
23
  const access = await assertVersionedResourceAccess(args.resourceType, args.resourceId, actionCtx, "editor");