@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.
- package/dist/action.js +54 -1
- package/dist/agent/actions/disconnect-chatgpt-subscription.js +5 -0
- package/dist/agent/actions/get-agentkit-capabilities.js +3 -3
- package/dist/agent/actions/manage-builder-connection.js +5 -0
- package/dist/agent/actions/manage-provider-key-policy.js +5 -0
- package/dist/agent/actions/manage-provider-models.js +5 -0
- package/dist/agent/actions/manage-service-providers.js +5 -0
- package/dist/agent/actions/select-chatgpt-subscription-account.js +5 -0
- package/dist/agent/context-xray/actions/context-evict.js +5 -0
- package/dist/agent/context-xray/actions/context-pin.js +5 -0
- package/dist/agent/context-xray/actions/context-report.js +5 -0
- package/dist/agent/context-xray/actions/context-restore.js +5 -0
- package/dist/agent/execution-fence.d.ts +1 -0
- package/dist/agent/execution-fence.js +5 -0
- package/dist/agent/production-agent.d.ts +35 -2
- package/dist/agent/production-agent.js +629 -32
- package/dist/agent/run-manager.d.ts +2 -0
- package/dist/agent/run-manager.js +397 -115
- package/dist/agent/run-slot-lock.d.ts +2 -0
- package/dist/agent/run-slot-lock.js +6 -0
- package/dist/agent/run-store.d.ts +5 -0
- package/dist/agent/run-store.js +423 -156
- package/dist/agent/thread-data-builder.js +27 -5
- package/dist/agent/types.d.ts +6 -12
- package/dist/agentkit/capabilities.d.ts +1 -1
- package/dist/appearance/actions/get-theme-family.d.ts +8 -0
- package/dist/appearance/actions/get-theme-family.js +38 -0
- package/dist/appearance/actions/set-theme-family.d.ts +7 -0
- package/dist/appearance/actions/set-theme-family.js +33 -0
- package/dist/appearance/theme-family.d.ts +13 -0
- package/dist/appearance/theme-family.js +38 -0
- package/dist/application-state/store.d.ts +5 -0
- package/dist/application-state/store.js +26 -0
- package/dist/chat-threads/schema-migrations.js +17 -0
- package/dist/chat-threads/store.d.ts +21 -1
- package/dist/chat-threads/store.js +223 -41
- package/dist/cli/skills-content/turn-into-app-skill.d.ts +1 -1
- package/dist/cli/skills-content/turn-into-app-skill.js +20 -18
- package/dist/cli/templates-meta.js +14 -0
- package/dist/client/analytics.js +167 -17
- package/dist/client/chat/agentkit-agent-native.js +79 -3
- package/dist/client/chat/agentkit-protocol.js +80 -42
- package/dist/client/chat/runtime.d.ts +5 -1
- package/dist/client/chat/runtime.js +46 -3
- package/dist/client/consent.d.ts +36 -0
- package/dist/client/consent.js +283 -0
- package/dist/client/review/use-review.d.ts +2 -0
- package/dist/client/review/use-review.js +28 -1
- package/dist/client/sharing/useResourceAccessGate.d.ts +3 -2
- package/dist/client/sharing/useResourceAccessGate.js +9 -1
- package/dist/client/theme-family.d.ts +35 -0
- package/dist/client/theme-family.js +223 -0
- package/dist/client/theme.d.ts +1 -1
- package/dist/client/theme.js +5 -2
- package/dist/client/ui/index.d.ts +1 -0
- package/dist/client/ui/index.js +1 -0
- package/dist/client/use-chat-thread-list.d.ts +2 -0
- package/dist/client/use-chat-thread-list.js +12 -2
- package/dist/client/use-chat-threads.d.ts +1 -0
- package/dist/client/use-chat-threads.js +2 -0
- package/dist/connections/catalog.d.ts +5 -5
- package/dist/connections/catalog.js +22 -3
- package/dist/data-widgets/index.d.ts +374 -5
- package/dist/data-widgets/index.js +242 -11
- package/dist/db/migrations.js +4 -1
- package/dist/db/schema-snapshot.generated.js +8 -1
- package/dist/feature-flags/actions/set-feature-flag.js +5 -0
- package/dist/feature-flags/index.d.ts +1 -1
- package/dist/feature-flags/index.js +1 -1
- package/dist/feature-flags/store.d.ts +12 -0
- package/dist/feature-flags/store.js +79 -7
- package/dist/file-upload/actions/manage-file-storage.js +5 -0
- package/dist/file-upload/actions/upload-image.js +5 -0
- package/dist/framework-tools.js +2 -0
- package/dist/history/actions/create-resource-version.js +5 -0
- package/dist/history/actions/restore-resource-version.js +5 -0
- package/dist/ingestion/index.d.ts +1 -1
- package/dist/ingestion/index.js +1 -1
- package/dist/ingestion/pptx.d.ts +11 -0
- package/dist/ingestion/pptx.js +81 -1
- package/dist/integrations/actions/manage-messaging-channel.js +5 -0
- package/dist/jobs/scheduler.js +17 -1
- package/dist/labs/actions/set-lab.js +5 -0
- package/dist/localization/actions/set-localization-preference.js +5 -0
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/observability/actions/save-observability-instruction-update.js +5 -0
- package/dist/observability/actions/save-observability-review-summary.js +5 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +19 -19
- package/dist/provider-api/actions/provider-api.d.ts +10 -10
- package/dist/provider-api/index.js +9 -2
- package/dist/review/actions/consume-review-feedback.js +5 -0
- package/dist/review/actions/create-review-comment.js +5 -0
- package/dist/review/actions/delete-review-comment.js +5 -0
- package/dist/review/actions/react-to-review-comment.js +5 -0
- package/dist/review/actions/reply-review-comment.js +5 -0
- package/dist/review/actions/resolve-review-thread.js +5 -0
- package/dist/review/actions/send-review-thread-to-agent.js +5 -0
- package/dist/review/actions/set-review-status.js +5 -0
- package/dist/review/actions/set-review-thread-muted.js +5 -0
- package/dist/review/actions/set-review-thread-unread.js +5 -0
- package/dist/review/actions/set-review-threads-unread.js +5 -0
- package/dist/review/actions/update-review-comment-anchor.js +5 -0
- package/dist/review/actions/update-review-comment.js +5 -0
- package/dist/review/suggestions/actions.js +60 -21
- package/dist/review/suggestions/store.d.ts +2 -0
- package/dist/review/suggestions/store.js +28 -0
- package/dist/secrets/actions/delete-api-key.js +5 -0
- package/dist/secrets/routes.d.ts +10 -10
- package/dist/server/action-discovery.js +8 -0
- package/dist/server/agent-chat/context-tools.js +105 -2
- package/dist/server/agent-chat-plugin.d.ts +2 -0
- package/dist/server/agent-chat-plugin.js +242 -54
- package/dist/server/agent-engine-default-model-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/application-state-maintenance.d.ts +2 -0
- package/dist/server/application-state-maintenance.js +2 -0
- package/dist/server/attribution.d.ts +14 -0
- package/dist/server/attribution.js +62 -2
- package/dist/server/auth.js +7 -0
- package/dist/server/consent-route.d.ts +41 -0
- package/dist/server/consent-route.js +102 -0
- package/dist/server/first-touch-route.d.ts +39 -0
- package/dist/server/first-touch-route.js +115 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/queued-submission-inbox-drain.d.ts +9 -0
- package/dist/server/queued-submission-inbox-drain.js +12 -0
- package/dist/server/request-origin.d.ts +6 -0
- package/dist/server/request-origin.js +12 -0
- package/dist/settings/org-settings.d.ts +2 -1
- package/dist/settings/org-settings.js +4 -1
- package/dist/settings/store.d.ts +8 -0
- package/dist/settings/store.js +14 -5
- package/dist/shared/consent.d.ts +31 -0
- package/dist/shared/consent.js +145 -0
- package/dist/shared/first-touch-persistence.d.ts +31 -0
- package/dist/shared/first-touch-persistence.js +53 -0
- package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
- package/dist/sharing/actions/set-resource-visibility.js +5 -0
- package/dist/sharing/actions/share-resource.js +5 -0
- package/dist/sharing/actions/unshare-resource.js +5 -0
- package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
- package/dist/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
- package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
- package/dist/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
- package/dist/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
- package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
- package/dist/usage/actions/get-usage-metrics.js +27 -4
- package/dist/usage/actions/manage-usage-alert.js +5 -0
- package/dist/vite/client.js +8 -6
- package/dist/workspace-connections/actions/bulk-update-workspace-user-groups.js +5 -0
- package/dist/workspace-connections/actions/delete-workspace-user-group.js +5 -0
- package/dist/workspace-connections/actions/upsert-workspace-user-group.js +5 -0
- package/docs/content/actions-access-control.mdx +8 -8
- package/docs/content/actions-defining.mdx +9 -8
- package/docs/content/template-design-developers.mdx +9 -9
- package/docs/content/template-design-features.mdx +1 -3
- package/docs/content/turn-into-app.mdx +4 -0
- package/package.json +4 -3
- package/src/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
- package/src/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
- package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
- package/src/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
- package/src/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
- package/src/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
- package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
- 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
|
|
52
|
-
return
|
|
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 (
|
|
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:
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
482
|
+
chartSeries: boundedDataChartWidgetSchema.optional(),
|
|
252
483
|
})
|
|
253
484
|
.passthrough()
|
|
254
485
|
.refine((value) => value.table || value.chartSeries, {
|
package/dist/db/migrations.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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) {
|
package/dist/framework-tools.js
CHANGED
|
@@ -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";
|
package/dist/ingestion/index.js
CHANGED
|
@@ -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";
|
package/dist/ingestion/pptx.d.ts
CHANGED
|
@@ -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;
|