@agent-native/core 0.213.1 → 0.216.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 (169) 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/appearance/actions/get-theme-family.d.ts +8 -0
  27. package/dist/appearance/actions/get-theme-family.js +38 -0
  28. package/dist/appearance/actions/set-theme-family.d.ts +7 -0
  29. package/dist/appearance/actions/set-theme-family.js +33 -0
  30. package/dist/appearance/theme-family.d.ts +13 -0
  31. package/dist/appearance/theme-family.js +38 -0
  32. package/dist/application-state/store.d.ts +5 -0
  33. package/dist/application-state/store.js +26 -0
  34. package/dist/chat-threads/schema-migrations.js +17 -0
  35. package/dist/chat-threads/store.d.ts +21 -1
  36. package/dist/chat-threads/store.js +223 -41
  37. package/dist/cli/skills-content/turn-into-app-skill.d.ts +1 -1
  38. package/dist/cli/skills-content/turn-into-app-skill.js +20 -18
  39. package/dist/cli/templates-meta.js +14 -0
  40. package/dist/client/analytics.js +167 -17
  41. package/dist/client/chat/agentkit-agent-native.js +79 -3
  42. package/dist/client/chat/agentkit-protocol.js +80 -42
  43. package/dist/client/chat/runtime.d.ts +5 -1
  44. package/dist/client/chat/runtime.js +46 -3
  45. package/dist/client/consent.d.ts +36 -0
  46. package/dist/client/consent.js +283 -0
  47. package/dist/client/review/use-review.d.ts +2 -0
  48. package/dist/client/review/use-review.js +28 -1
  49. package/dist/client/sharing/useResourceAccessGate.d.ts +3 -2
  50. package/dist/client/sharing/useResourceAccessGate.js +9 -1
  51. package/dist/client/theme-family.d.ts +35 -0
  52. package/dist/client/theme-family.js +223 -0
  53. package/dist/client/theme.d.ts +1 -1
  54. package/dist/client/theme.js +5 -2
  55. package/dist/client/ui/index.d.ts +1 -0
  56. package/dist/client/ui/index.js +1 -0
  57. package/dist/client/use-chat-thread-list.d.ts +2 -0
  58. package/dist/client/use-chat-thread-list.js +12 -2
  59. package/dist/client/use-chat-threads.d.ts +1 -0
  60. package/dist/client/use-chat-threads.js +2 -0
  61. package/dist/connections/catalog.d.ts +5 -5
  62. package/dist/connections/catalog.js +22 -3
  63. package/dist/data-widgets/index.d.ts +374 -5
  64. package/dist/data-widgets/index.js +242 -11
  65. package/dist/db/migrations.js +4 -1
  66. package/dist/db/schema-snapshot.generated.js +8 -1
  67. package/dist/feature-flags/actions/set-feature-flag.js +5 -0
  68. package/dist/feature-flags/index.d.ts +1 -1
  69. package/dist/feature-flags/index.js +1 -1
  70. package/dist/feature-flags/store.d.ts +12 -0
  71. package/dist/feature-flags/store.js +79 -7
  72. package/dist/file-upload/actions/manage-file-storage.js +5 -0
  73. package/dist/file-upload/actions/upload-image.js +5 -0
  74. package/dist/framework-tools.js +2 -0
  75. package/dist/history/actions/create-resource-version.js +5 -0
  76. package/dist/history/actions/restore-resource-version.js +5 -0
  77. package/dist/ingestion/index.d.ts +1 -1
  78. package/dist/ingestion/index.js +1 -1
  79. package/dist/ingestion/pptx.d.ts +11 -0
  80. package/dist/ingestion/pptx.js +81 -1
  81. package/dist/integrations/actions/manage-messaging-channel.js +5 -0
  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/mcp/screen-memory-stdio.d.ts +7 -7
  86. package/dist/observability/actions/save-observability-instruction-update.js +5 -0
  87. package/dist/observability/actions/save-observability-review-summary.js +5 -0
  88. package/dist/provider-api/actions/custom-provider-registration.d.ts +19 -19
  89. package/dist/provider-api/actions/provider-api.d.ts +10 -10
  90. package/dist/provider-api/index.js +9 -2
  91. package/dist/review/actions/consume-review-feedback.js +5 -0
  92. package/dist/review/actions/create-review-comment.js +5 -0
  93. package/dist/review/actions/delete-review-comment.js +5 -0
  94. package/dist/review/actions/react-to-review-comment.js +5 -0
  95. package/dist/review/actions/reply-review-comment.js +5 -0
  96. package/dist/review/actions/resolve-review-thread.js +5 -0
  97. package/dist/review/actions/send-review-thread-to-agent.js +5 -0
  98. package/dist/review/actions/set-review-status.js +5 -0
  99. package/dist/review/actions/set-review-thread-muted.js +5 -0
  100. package/dist/review/actions/set-review-thread-unread.js +5 -0
  101. package/dist/review/actions/set-review-threads-unread.js +5 -0
  102. package/dist/review/actions/update-review-comment-anchor.js +5 -0
  103. package/dist/review/actions/update-review-comment.js +5 -0
  104. package/dist/review/suggestions/actions.js +60 -21
  105. package/dist/review/suggestions/store.d.ts +2 -0
  106. package/dist/review/suggestions/store.js +28 -0
  107. package/dist/secrets/actions/delete-api-key.js +5 -0
  108. package/dist/secrets/routes.d.ts +10 -10
  109. package/dist/server/action-discovery.js +8 -0
  110. package/dist/server/agent-chat/context-tools.js +105 -2
  111. package/dist/server/agent-chat-plugin.d.ts +2 -0
  112. package/dist/server/agent-chat-plugin.js +242 -54
  113. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  114. package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
  115. package/dist/server/application-state-maintenance.d.ts +2 -0
  116. package/dist/server/application-state-maintenance.js +2 -0
  117. package/dist/server/attribution.d.ts +14 -0
  118. package/dist/server/attribution.js +62 -2
  119. package/dist/server/auth.js +7 -0
  120. package/dist/server/consent-route.d.ts +41 -0
  121. package/dist/server/consent-route.js +102 -0
  122. package/dist/server/first-touch-route.d.ts +39 -0
  123. package/dist/server/first-touch-route.js +115 -0
  124. package/dist/server/index.d.ts +1 -0
  125. package/dist/server/index.js +1 -0
  126. package/dist/server/queued-submission-inbox-drain.d.ts +9 -0
  127. package/dist/server/queued-submission-inbox-drain.js +12 -0
  128. package/dist/server/request-origin.d.ts +6 -0
  129. package/dist/server/request-origin.js +12 -0
  130. package/dist/settings/org-settings.d.ts +2 -1
  131. package/dist/settings/org-settings.js +4 -1
  132. package/dist/settings/store.d.ts +8 -0
  133. package/dist/settings/store.js +14 -5
  134. package/dist/shared/consent.d.ts +31 -0
  135. package/dist/shared/consent.js +145 -0
  136. package/dist/shared/first-touch-persistence.d.ts +31 -0
  137. package/dist/shared/first-touch-persistence.js +53 -0
  138. package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
  139. package/dist/sharing/actions/set-resource-visibility.js +5 -0
  140. package/dist/sharing/actions/share-resource.js +5 -0
  141. package/dist/sharing/actions/unshare-resource.js +5 -0
  142. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  143. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  144. package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  145. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  146. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  147. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  148. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  149. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
  150. package/dist/usage/actions/get-usage-metrics.js +27 -4
  151. package/dist/usage/actions/manage-usage-alert.js +5 -0
  152. package/dist/vite/client.js +8 -6
  153. package/dist/workspace-connections/actions/bulk-update-workspace-user-groups.js +5 -0
  154. package/dist/workspace-connections/actions/delete-workspace-user-group.js +5 -0
  155. package/dist/workspace-connections/actions/upsert-workspace-user-group.js +5 -0
  156. package/docs/content/actions-access-control.mdx +8 -8
  157. package/docs/content/actions-defining.mdx +9 -8
  158. package/docs/content/template-design-developers.mdx +9 -9
  159. package/docs/content/template-design-features.mdx +1 -3
  160. package/docs/content/turn-into-app.mdx +4 -0
  161. package/package.json +4 -3
  162. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  163. package/src/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  164. package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  165. package/src/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  166. package/src/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  167. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  168. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  169. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
@@ -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;
@@ -39,27 +104,132 @@ export function isDataChartWidget(value) {
39
104
  if (!isRecord(value))
40
105
  return false;
41
106
  return ((value.type === "bar" || value.type === "line" || value.type === "area") &&
107
+ (value.layout === undefined ||
108
+ value.layout === "horizontal" ||
109
+ value.layout === "vertical") &&
110
+ (value.xAxisTitle === undefined || typeof value.xAxisTitle === "string") &&
111
+ (value.yAxisTitle === undefined || typeof value.yAxisTitle === "string") &&
112
+ (value.showValueLabels === undefined ||
113
+ typeof value.showValueLabels === "boolean") &&
114
+ (value.contentHeight === undefined ||
115
+ (typeof value.contentHeight === "number" &&
116
+ Number.isFinite(value.contentHeight) &&
117
+ value.contentHeight > 0 &&
118
+ value.contentHeight <= 1200)) &&
119
+ (value.contentPadding === undefined ||
120
+ (typeof value.contentPadding === "number" &&
121
+ Number.isFinite(value.contentPadding) &&
122
+ value.contentPadding >= 0 &&
123
+ value.contentPadding <= 64)) &&
124
+ (value.labelFontFamily === undefined ||
125
+ value.labelFontFamily === "sans" ||
126
+ value.labelFontFamily === "serif" ||
127
+ value.labelFontFamily === "mono") &&
128
+ (value.labelFontSize === undefined ||
129
+ (typeof value.labelFontSize === "number" &&
130
+ Number.isInteger(value.labelFontSize) &&
131
+ value.labelFontSize >= 8 &&
132
+ value.labelFontSize <= 24)) &&
133
+ (value.axisTitleFontSize === undefined ||
134
+ (typeof value.axisTitleFontSize === "number" &&
135
+ Number.isInteger(value.axisTitleFontSize) &&
136
+ value.axisTitleFontSize >= 8 &&
137
+ value.axisTitleFontSize <= 24)) &&
138
+ (value.axisTitleFontWeight === undefined ||
139
+ value.axisTitleFontWeight === 400 ||
140
+ value.axisTitleFontWeight === 500) &&
141
+ (value.valueLabelFontSize === undefined ||
142
+ (typeof value.valueLabelFontSize === "number" &&
143
+ Number.isInteger(value.valueLabelFontSize) &&
144
+ value.valueLabelFontSize >= 8 &&
145
+ value.valueLabelFontSize <= 24)) &&
146
+ (value.valueLabelFontWeight === undefined ||
147
+ value.valueLabelFontWeight === 400 ||
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) &&
42
157
  isString(value.xKey) &&
43
158
  Array.isArray(value.series) &&
44
159
  value.series.every((series) => isRecord(series) &&
45
160
  isString(series.key) &&
46
161
  isString(series.label) &&
47
162
  (series.color === undefined || typeof series.color === "string")) &&
163
+ (value.actions === undefined ||
164
+ (Array.isArray(value.actions) &&
165
+ value.actions.every(isDataWidgetChartAction))) &&
48
166
  Array.isArray(value.data) &&
49
167
  value.data.every(isRecord));
50
168
  }
51
- function isPrimaryAction(value) {
52
- return isRecord(value) && isString(value.label) && isString(value.href);
169
+ function isDataWidgetActionIcon(value) {
170
+ return value === "explore" || value === "camera" || value === "notebook";
171
+ }
172
+ function isDataWidgetAction(value) {
173
+ return (isRecord(value) &&
174
+ isString(value.label) &&
175
+ isString(value.href) &&
176
+ (value.icon === undefined || isDataWidgetActionIcon(value.icon)));
177
+ }
178
+ function isDataWidgetChartAction(value) {
179
+ const presentation = isRecord(value) ? value.presentation : undefined;
180
+ return (isDataWidgetAction(value) &&
181
+ (presentation === undefined || presentation === "icon"));
182
+ }
183
+ function normalizePrimaryAction(value) {
184
+ if (!isRecord(value) || !isString(value.label) || !isString(value.href)) {
185
+ return undefined;
186
+ }
187
+ return {
188
+ label: value.label,
189
+ href: value.href,
190
+ ...(isDataWidgetActionIcon(value.icon) ? { icon: value.icon } : {}),
191
+ };
192
+ }
193
+ function isDataWidgetDataSource(value) {
194
+ return (isRecord(value) &&
195
+ isString(value.label) &&
196
+ (value.id === undefined || typeof value.id === "string") &&
197
+ (value.href === undefined || isString(value.href)));
198
+ }
199
+ function isDataWidgetDisplayAction(value) {
200
+ if (!isRecord(value) ||
201
+ !isString(value.label) ||
202
+ (value.id !== undefined && typeof value.id !== "string")) {
203
+ return false;
204
+ }
205
+ if (value.type === "link") {
206
+ return (isString(value.href) &&
207
+ (value.icon === undefined || isDataWidgetActionIcon(value.icon)) &&
208
+ (value.presentation === undefined || value.presentation === "icon"));
209
+ }
210
+ if (value.type === "copy")
211
+ return isString(value.text);
212
+ return false;
53
213
  }
54
214
  function normalizeDisplay(value) {
55
- if (!isRecord(value))
215
+ if (value === undefined)
56
216
  return undefined;
217
+ if (!isRecord(value))
218
+ return null;
219
+ if ((value.sources !== undefined &&
220
+ (!Array.isArray(value.sources) ||
221
+ !value.sources.every(isDataWidgetDataSource))) ||
222
+ (value.actions !== undefined &&
223
+ (!Array.isArray(value.actions) ||
224
+ !value.actions.every(isDataWidgetDisplayAction)))) {
225
+ return null;
226
+ }
57
227
  return {
58
228
  title: typeof value.title === "string" ? value.title : undefined,
59
229
  description: typeof value.description === "string" ? value.description : undefined,
60
- primaryAction: isPrimaryAction(value.primaryAction)
61
- ? value.primaryAction
62
- : undefined,
230
+ primaryAction: normalizePrimaryAction(value.primaryAction),
231
+ sources: value.sources,
232
+ actions: value.actions,
63
233
  };
64
234
  }
65
235
  function assertDataTableWidget(table) {
@@ -107,6 +277,9 @@ export function normalizeDataWidgetResult(value) {
107
277
  const widget = normalizeDataWidgetKind(value.widget);
108
278
  if (!widget)
109
279
  return null;
280
+ const display = normalizeDisplay(value.display);
281
+ if (display === null)
282
+ return null;
110
283
  const table = isDataTableWidget(value.table) ? value.table : undefined;
111
284
  const chartSeries = isDataChartWidget(value.chartSeries)
112
285
  ? value.chartSeries
@@ -115,7 +288,7 @@ export function normalizeDataWidgetResult(value) {
115
288
  widgetId: typeof value.widgetId === "string" ? value.widgetId : undefined,
116
289
  title: typeof value.title === "string" ? value.title : undefined,
117
290
  summary: isRecord(value.summary) ? value.summary : undefined,
118
- display: normalizeDisplay(value.display),
291
+ display,
119
292
  };
120
293
  if (widget === DATA_TABLE_WIDGET) {
121
294
  if (!table)
@@ -148,7 +321,6 @@ export function isDataWidgetResult(value) {
148
321
  return normalizeDataWidgetResult(value) !== null;
149
322
  }
150
323
  export const DATA_WIDGET_MAX_ROWS = 50;
151
- export const DATA_WIDGET_MAX_CHART_POINTS = 200;
152
324
  export function clampDataWidgetRows(result) {
153
325
  const source = result;
154
326
  const table = source.table;
@@ -165,8 +337,9 @@ export function clampDataWidgetRows(result) {
165
337
  const clampedChart = chartSeries && chartSeries.data.length > DATA_WIDGET_MAX_CHART_POINTS
166
338
  ? {
167
339
  ...chartSeries,
168
- data: chartSeries.data.slice(0, DATA_WIDGET_MAX_CHART_POINTS),
340
+ data: chartRowsForRender(chartSeries.data),
169
341
  sampled: true,
342
+ truncated: true,
170
343
  }
171
344
  : chartSeries;
172
345
  if (clampedTable === table && clampedChart === chartSeries)
@@ -201,27 +374,85 @@ const dataChartSeriesDefinitionSchema = z
201
374
  color: z.string().optional(),
202
375
  })
203
376
  .passthrough();
377
+ const dataWidgetActionSchema = z
378
+ .object({
379
+ label: z.string().min(1),
380
+ href: z.string().min(1),
381
+ icon: z.enum(["explore", "camera", "notebook"]).optional(),
382
+ presentation: z.literal("icon").optional(),
383
+ })
384
+ .passthrough();
204
385
  export const dataChartWidgetSchema = z
205
386
  .object({
206
387
  type: z.enum(["bar", "line", "area"]),
207
388
  title: z.string().optional(),
389
+ layout: z.enum(["horizontal", "vertical"]).optional(),
390
+ xAxisTitle: z.string().optional(),
391
+ yAxisTitle: z.string().optional(),
392
+ showValueLabels: z.boolean().optional(),
393
+ contentHeight: z.number().positive().max(1200).optional(),
394
+ contentPadding: z.number().min(0).max(64).optional(),
395
+ labelFontFamily: z.enum(["sans", "serif", "mono"]).optional(),
396
+ labelFontSize: z.number().int().min(8).max(24).optional(),
397
+ axisTitleFontSize: z.number().int().min(8).max(24).optional(),
398
+ axisTitleFontWeight: z.union([z.literal(400), z.literal(500)]).optional(),
399
+ valueLabelFontSize: z.number().int().min(8).max(24).optional(),
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(),
208
403
  xKey: z.string().min(1),
209
404
  series: z.array(dataChartSeriesDefinitionSchema).min(1),
210
405
  data: z.array(z.record(z.string(), z.unknown())),
211
406
  sampled: z.boolean().optional(),
407
+ truncated: z.boolean().optional(),
408
+ actions: z.array(dataWidgetActionSchema).optional(),
212
409
  })
213
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
+ });
214
415
  const primaryActionSchema = z
215
416
  .object({
216
417
  label: z.string().min(1),
217
418
  href: z.string().min(1),
419
+ icon: z.enum(["explore", "camera", "notebook"]).optional(),
218
420
  })
219
421
  .passthrough();
422
+ const dataWidgetDataSourceSchema = z
423
+ .object({
424
+ id: z.string().optional(),
425
+ label: z.string().min(1),
426
+ href: z.string().min(1).optional(),
427
+ })
428
+ .passthrough();
429
+ const dataWidgetDisplayActionSchema = z.discriminatedUnion("type", [
430
+ z
431
+ .object({
432
+ id: z.string().optional(),
433
+ type: z.literal("link"),
434
+ label: z.string().min(1),
435
+ href: z.string().min(1),
436
+ icon: z.enum(["explore", "camera", "notebook"]).optional(),
437
+ presentation: z.literal("icon").optional(),
438
+ })
439
+ .passthrough(),
440
+ z
441
+ .object({
442
+ id: z.string().optional(),
443
+ type: z.literal("copy"),
444
+ label: z.string().min(1),
445
+ text: z.string().min(1),
446
+ })
447
+ .passthrough(),
448
+ ]);
220
449
  const dataWidgetDisplaySchema = z
221
450
  .object({
222
451
  title: z.string().optional(),
223
452
  description: z.string().optional(),
224
453
  primaryAction: primaryActionSchema.optional(),
454
+ sources: z.array(dataWidgetDataSourceSchema).optional(),
455
+ actions: z.array(dataWidgetDisplayActionSchema).optional(),
225
456
  })
226
457
  .passthrough();
227
458
  const dataWidgetBaseSchema = z
@@ -241,14 +472,14 @@ export const dataTableWidgetResultSchema = dataWidgetBaseSchema
241
472
  export const dataChartWidgetResultSchema = dataWidgetBaseSchema
242
473
  .extend({
243
474
  widget: z.literal(DATA_CHART_WIDGET),
244
- chartSeries: dataChartWidgetSchema,
475
+ chartSeries: boundedDataChartWidgetSchema,
245
476
  })
246
477
  .passthrough();
247
478
  export const dataInsightsWidgetResultSchema = dataWidgetBaseSchema
248
479
  .extend({
249
480
  widget: z.literal(DATA_INSIGHTS_WIDGET),
250
481
  table: dataTableWidgetSchema.optional(),
251
- chartSeries: dataChartWidgetSchema.optional(),
482
+ chartSeries: boundedDataChartWidgetSchema.optional(),
252
483
  })
253
484
  .passthrough()
254
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) },
@@ -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) {
@@ -165,6 +165,8 @@ export const CORE_ACTION_GROUPS = {
165
165
  "change-password": "userProfile",
166
166
  "request-privacy-right": "userProfile",
167
167
  "change-appearance": "userProfile",
168
+ "get-theme-family": "userProfile",
169
+ "set-theme-family": "userProfile",
168
170
  "list-audit-events": "audit",
169
171
  "get-audit-event": "audit",
170
172
  "export-audit-events": "audit",
@@ -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");
@@ -16,6 +16,11 @@ const schema = z
16
16
  export default defineAction({
17
17
  description: "Restore a resource from a reusable version-history snapshot.",
18
18
  schema,
19
+ mcpAnnotations: {
20
+ readOnlyHint: false,
21
+ destructiveHint: true,
22
+ openWorldHint: false,
23
+ },
19
24
  run: async (args, ctx) => {
20
25
  const actionCtx = ctx;
21
26
  const scope = {
@@ -1,7 +1,7 @@
1
1
  export { acquireIngestionLease, assertInventoryComplete, consumeIngestionBudget, createIngestionBudgetState, createIngestionCheckpoint, ingestionBudgetStopReason, releaseIngestionLease, renewIngestionLease, type AcquireIngestionLeaseInput, type AcquireIngestionLeaseResult, type IngestionBudgetLimits, type IngestionBudgetState, type IngestionBudgetStopReason, type IngestionCheckpoint, type IngestionLease, type IngestionPhase, } from "./orchestration.js";
2
2
  export { detectOfficeDocumentType, normalizeDocumentText, parseOfficeDocument, type OfficeDocumentAst, type OfficeDocumentParser, type OfficeDocumentPart, type OfficeDocumentType, type ParsedOfficeDocument, type ParseOfficeDocumentInput, } from "./office.js";
3
3
  export { detectSpreadsheetDocumentType, isSpreadsheetDocument, parseSpreadsheetDocument, type ParsedSpreadsheetDocument, type ParsedSpreadsheetSheet, type ParseSpreadsheetDocumentInput, type SpreadsheetDocumentType, } from "./spreadsheet.js";
4
- export { parsePptxPresentation, type ParsedPptxImage, type ParsedPptxElement, type ParsedPptxGrid, type ParsedPptxParagraph, type ParsedPptxPresentation, type ParsedPptxSlide, type ParsedPptxTextRun, } from "./pptx.js";
4
+ export { DEFAULT_PPTX_IMAGE_BYTE_LIMITS, PptxImageByteLimitError, parsePptxPresentation, type ParsedPptxImage, type ParsedPptxElement, type ParsedPptxGrid, type ParsedPptxParagraph, type ParsedPptxPresentation, type ParsedPptxSlide, type ParsedPptxTextRun, type PptxImageByteLimits, } from "./pptx.js";
5
5
  export { extractDocxSections, parseDocxDocument, sanitizeInertDocumentHtml, type ParsedDocxDocument, type ParsedDocxSection, } from "./docx.js";
6
6
  export { compositeFigmaColors, extractFigmaTopLevelFrames, figmaColorToHex, figmaContrastRatio, summarizeFigmaFrame, summarizeFigmaNode, type FigmaContextNode, type FigmaFrameSummary, type FigmaRgba, type SummarizeFigmaNodeResult, } from "./figma.js";
7
7
  export { cssBlendMode, gradientAngleDegreesFromHandles, gradientGeometryFromTransform, gradientRayAngleDegreesFromHandles, handlePositionsFromArrayTransform, handlePositionsFromObjectTransform, invert2x3, mat2x3FromArray, remapLinearStopPosition, resolveGradientHandles, vectorLength, type BlendModeResult, type BlendVerdict, type GradientGeometry, type GradientHandles, type GradientKind, type Mat2x3Array, type Mat2x3Object, type Vec2, } from "./figma-paint-math.js";
@@ -1,7 +1,7 @@
1
1
  export { acquireIngestionLease, assertInventoryComplete, consumeIngestionBudget, createIngestionBudgetState, createIngestionCheckpoint, ingestionBudgetStopReason, releaseIngestionLease, renewIngestionLease, } from "./orchestration.js";
2
2
  export { detectOfficeDocumentType, normalizeDocumentText, parseOfficeDocument, } from "./office.js";
3
3
  export { detectSpreadsheetDocumentType, isSpreadsheetDocument, parseSpreadsheetDocument, } from "./spreadsheet.js";
4
- export { parsePptxPresentation, } from "./pptx.js";
4
+ export { DEFAULT_PPTX_IMAGE_BYTE_LIMITS, PptxImageByteLimitError, parsePptxPresentation, } from "./pptx.js";
5
5
  export { extractDocxSections, parseDocxDocument, sanitizeInertDocumentHtml, } from "./docx.js";
6
6
  export { compositeFigmaColors, extractFigmaTopLevelFrames, figmaColorToHex, figmaContrastRatio, summarizeFigmaFrame, summarizeFigmaNode, } from "./figma.js";
7
7
  export { cssBlendMode, gradientAngleDegreesFromHandles, gradientGeometryFromTransform, gradientRayAngleDegreesFromHandles, handlePositionsFromArrayTransform, handlePositionsFromObjectTransform, invert2x3, mat2x3FromArray, remapLinearStopPosition, resolveGradientHandles, vectorLength, } from "./figma-paint-math.js";
@@ -155,7 +155,18 @@ export interface ParsedPptxPresentation {
155
155
  };
156
156
  hiddenSlideCount?: number;
157
157
  }
158
+ export interface PptxImageByteLimits {
159
+ maxImageBytes: number;
160
+ maxTotalImageBytes: number;
161
+ }
162
+ export declare const DEFAULT_PPTX_IMAGE_BYTE_LIMITS: Readonly<PptxImageByteLimits>;
163
+ export declare class PptxImageByteLimitError extends Error {
164
+ readonly limit: "per-image" | "aggregate";
165
+ readonly maxBytes: number;
166
+ constructor(limit: "per-image" | "aggregate", maxBytes: number);
167
+ }
158
168
  export declare function parsePptxPresentation(fileBuffer: Uint8Array, options?: {
159
169
  includeHiddenSlides?: boolean;
170
+ imageByteLimits?: Readonly<PptxImageByteLimits>;
160
171
  }): Promise<ParsedPptxPresentation>;
161
172
  export declare function parsePptxSlideMetadata(value: unknown): ParsedPptxSlideMetadata;