@agent-native/core 0.214.0 → 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/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/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/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +5 -5
- package/dist/connections/catalog.js +22 -3
- package/dist/data-widgets/index.d.ts +36 -2
- package/dist/data-widgets/index.js +94 -6
- 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.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.js +5 -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/observability/actions/save-observability-instruction-update.js +5 -0
- package/dist/observability/actions/save-observability-review-summary.js +5 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +18 -18
- package/dist/provider-api/actions/provider-api.d.ts +14 -14
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- 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 +6 -6
- package/dist/server/agent-chat/context-tools.js +63 -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-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +2 -2
- 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/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/triggers/actions/manage-automation.d.ts +1 -1
- 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
|
@@ -92,7 +92,13 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
|
|
|
92
92
|
],
|
|
93
93
|
},
|
|
94
94
|
capabilities: ["search", "import", "docs"],
|
|
95
|
-
recommendedTemplateUses: [
|
|
95
|
+
recommendedTemplateUses: [
|
|
96
|
+
"brain",
|
|
97
|
+
"design",
|
|
98
|
+
"slides",
|
|
99
|
+
"slides-2",
|
|
100
|
+
"content",
|
|
101
|
+
],
|
|
96
102
|
}),
|
|
97
103
|
defineWorkspaceConnectionProvider({
|
|
98
104
|
id: "notion",
|
|
@@ -161,6 +167,7 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
|
|
|
161
167
|
"brain",
|
|
162
168
|
"content",
|
|
163
169
|
"slides",
|
|
170
|
+
"slides-2",
|
|
164
171
|
"dispatch",
|
|
165
172
|
"analytics",
|
|
166
173
|
],
|
|
@@ -176,7 +183,13 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
|
|
|
176
183
|
description: "Google Docs files for source material, document search, and agent-assisted writing workflows.",
|
|
177
184
|
credentialKeys: GOOGLE_CREDENTIAL_KEYS,
|
|
178
185
|
capabilities: ["search", "import", "docs"],
|
|
179
|
-
recommendedTemplateUses: [
|
|
186
|
+
recommendedTemplateUses: [
|
|
187
|
+
"brain",
|
|
188
|
+
"content",
|
|
189
|
+
"slides",
|
|
190
|
+
"slides-2",
|
|
191
|
+
"dispatch",
|
|
192
|
+
],
|
|
180
193
|
oauth: googleOAuth([
|
|
181
194
|
...GOOGLE_IDENTITY_SCOPES,
|
|
182
195
|
"https://www.googleapis.com/auth/documents.readonly",
|
|
@@ -197,7 +210,13 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
|
|
|
197
210
|
description: "Google Slides presentations for reference imports, visual context, and presentation workflows.",
|
|
198
211
|
credentialKeys: GOOGLE_CREDENTIAL_KEYS,
|
|
199
212
|
capabilities: ["search", "import", "docs"],
|
|
200
|
-
recommendedTemplateUses: [
|
|
213
|
+
recommendedTemplateUses: [
|
|
214
|
+
"brain",
|
|
215
|
+
"content",
|
|
216
|
+
"slides",
|
|
217
|
+
"slides-2",
|
|
218
|
+
"dispatch",
|
|
219
|
+
],
|
|
201
220
|
oauth: googleOAuth([
|
|
202
221
|
...GOOGLE_IDENTITY_SCOPES,
|
|
203
222
|
"https://www.googleapis.com/auth/presentations.readonly",
|
|
@@ -27,6 +27,9 @@ export interface DataWidgetAction {
|
|
|
27
27
|
href: string;
|
|
28
28
|
icon?: DataWidgetActionIcon;
|
|
29
29
|
}
|
|
30
|
+
export interface DataWidgetChartAction extends DataWidgetAction {
|
|
31
|
+
presentation?: "icon";
|
|
32
|
+
}
|
|
30
33
|
export interface DataChartWidget {
|
|
31
34
|
type: "bar" | "line" | "area";
|
|
32
35
|
title?: string;
|
|
@@ -46,11 +49,15 @@ export interface DataChartWidget {
|
|
|
46
49
|
axisTitleFontWeight?: 400 | 500;
|
|
47
50
|
valueLabelFontSize?: number;
|
|
48
51
|
valueLabelFontWeight?: 400 | 500;
|
|
52
|
+
valueAxisTickInterval?: number;
|
|
53
|
+
/** Fraction of each horizontal-bar category slot left empty; defaults to the existing spacing. */
|
|
54
|
+
horizontalCategoryGapRatio?: number;
|
|
49
55
|
xKey: string;
|
|
50
56
|
series: DataChartSeriesDefinition[];
|
|
51
57
|
data: Array<Record<string, unknown>>;
|
|
52
58
|
sampled?: boolean;
|
|
53
|
-
|
|
59
|
+
truncated?: boolean;
|
|
60
|
+
actions?: DataWidgetChartAction[];
|
|
54
61
|
}
|
|
55
62
|
export interface DataWidgetDisplay {
|
|
56
63
|
title?: string;
|
|
@@ -70,6 +77,7 @@ export type DataWidgetDisplayAction = {
|
|
|
70
77
|
label: string;
|
|
71
78
|
href: string;
|
|
72
79
|
icon?: DataWidgetActionIcon;
|
|
80
|
+
presentation?: "icon";
|
|
73
81
|
} | {
|
|
74
82
|
id?: string;
|
|
75
83
|
type: "copy";
|
|
@@ -109,6 +117,7 @@ export type DataInsightsWidgetResult<Input extends DataInsightsWidgetResultInput
|
|
|
109
117
|
widget: typeof DATA_INSIGHTS_WIDGET;
|
|
110
118
|
};
|
|
111
119
|
export type DataWidgetResult = DataTableWidgetResult | DataChartWidgetResult | DataInsightsWidgetResult;
|
|
120
|
+
export declare const DATA_WIDGET_MAX_CHART_POINTS = 200;
|
|
112
121
|
export declare function normalizeDataWidgetKind(value: unknown): DataWidgetKind | null;
|
|
113
122
|
export declare function isDataTableWidget(value: unknown): value is DataTableWidget;
|
|
114
123
|
export declare function isDataChartWidget(value: unknown): value is DataChartWidget;
|
|
@@ -126,7 +135,6 @@ export declare function createDataInsightsWidgetResult<const Input extends DataI
|
|
|
126
135
|
export declare function normalizeDataWidgetResult(value: unknown): DataWidgetResult | null;
|
|
127
136
|
export declare function isDataWidgetResult(value: unknown): value is DataWidgetResult;
|
|
128
137
|
export declare const DATA_WIDGET_MAX_ROWS = 50;
|
|
129
|
-
export declare const DATA_WIDGET_MAX_CHART_POINTS = 200;
|
|
130
138
|
export declare function clampDataWidgetRows(result: DataWidgetResult): DataWidgetResult;
|
|
131
139
|
export declare const dataTableWidgetSchema: z.ZodObject<{
|
|
132
140
|
title: z.ZodOptional<z.ZodString>;
|
|
@@ -169,6 +177,8 @@ export declare const dataChartWidgetSchema: z.ZodObject<{
|
|
|
169
177
|
axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
170
178
|
valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
|
|
171
179
|
valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
180
|
+
valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
|
|
181
|
+
horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
|
|
172
182
|
xKey: z.ZodString;
|
|
173
183
|
series: z.ZodArray<z.ZodObject<{
|
|
174
184
|
key: z.ZodString;
|
|
@@ -177,6 +187,7 @@ export declare const dataChartWidgetSchema: z.ZodObject<{
|
|
|
177
187
|
}, z.core.$loose>>;
|
|
178
188
|
data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
179
189
|
sampled: z.ZodOptional<z.ZodBoolean>;
|
|
190
|
+
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
180
191
|
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
181
192
|
label: z.ZodString;
|
|
182
193
|
href: z.ZodString;
|
|
@@ -185,6 +196,7 @@ export declare const dataChartWidgetSchema: z.ZodObject<{
|
|
|
185
196
|
explore: "explore";
|
|
186
197
|
notebook: "notebook";
|
|
187
198
|
}>>;
|
|
199
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
188
200
|
}, z.core.$loose>>>;
|
|
189
201
|
}, z.core.$loose>;
|
|
190
202
|
export declare const dataTableWidgetResultSchema: z.ZodObject<{
|
|
@@ -218,6 +230,7 @@ export declare const dataTableWidgetResultSchema: z.ZodObject<{
|
|
|
218
230
|
explore: "explore";
|
|
219
231
|
notebook: "notebook";
|
|
220
232
|
}>>;
|
|
233
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
221
234
|
}, z.core.$loose>, z.ZodObject<{
|
|
222
235
|
id: z.ZodOptional<z.ZodString>;
|
|
223
236
|
type: z.ZodLiteral<"copy">;
|
|
@@ -273,6 +286,7 @@ export declare const dataChartWidgetResultSchema: z.ZodObject<{
|
|
|
273
286
|
explore: "explore";
|
|
274
287
|
notebook: "notebook";
|
|
275
288
|
}>>;
|
|
289
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
276
290
|
}, z.core.$loose>, z.ZodObject<{
|
|
277
291
|
id: z.ZodOptional<z.ZodString>;
|
|
278
292
|
type: z.ZodLiteral<"copy">;
|
|
@@ -307,6 +321,8 @@ export declare const dataChartWidgetResultSchema: z.ZodObject<{
|
|
|
307
321
|
axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
308
322
|
valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
|
|
309
323
|
valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
324
|
+
valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
|
|
325
|
+
horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
|
|
310
326
|
xKey: z.ZodString;
|
|
311
327
|
series: z.ZodArray<z.ZodObject<{
|
|
312
328
|
key: z.ZodString;
|
|
@@ -315,6 +331,7 @@ export declare const dataChartWidgetResultSchema: z.ZodObject<{
|
|
|
315
331
|
}, z.core.$loose>>;
|
|
316
332
|
data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
317
333
|
sampled: z.ZodOptional<z.ZodBoolean>;
|
|
334
|
+
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
318
335
|
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
319
336
|
label: z.ZodString;
|
|
320
337
|
href: z.ZodString;
|
|
@@ -323,6 +340,7 @@ export declare const dataChartWidgetResultSchema: z.ZodObject<{
|
|
|
323
340
|
explore: "explore";
|
|
324
341
|
notebook: "notebook";
|
|
325
342
|
}>>;
|
|
343
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
326
344
|
}, z.core.$loose>>>;
|
|
327
345
|
}, z.core.$loose>;
|
|
328
346
|
}, z.core.$loose>;
|
|
@@ -357,6 +375,7 @@ export declare const dataInsightsWidgetResultSchema: z.ZodObject<{
|
|
|
357
375
|
explore: "explore";
|
|
358
376
|
notebook: "notebook";
|
|
359
377
|
}>>;
|
|
378
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
360
379
|
}, z.core.$loose>, z.ZodObject<{
|
|
361
380
|
id: z.ZodOptional<z.ZodString>;
|
|
362
381
|
type: z.ZodLiteral<"copy">;
|
|
@@ -406,6 +425,8 @@ export declare const dataInsightsWidgetResultSchema: z.ZodObject<{
|
|
|
406
425
|
axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
407
426
|
valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
|
|
408
427
|
valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
428
|
+
valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
|
|
429
|
+
horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
|
|
409
430
|
xKey: z.ZodString;
|
|
410
431
|
series: z.ZodArray<z.ZodObject<{
|
|
411
432
|
key: z.ZodString;
|
|
@@ -414,6 +435,7 @@ export declare const dataInsightsWidgetResultSchema: z.ZodObject<{
|
|
|
414
435
|
}, z.core.$loose>>;
|
|
415
436
|
data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
416
437
|
sampled: z.ZodOptional<z.ZodBoolean>;
|
|
438
|
+
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
417
439
|
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
418
440
|
label: z.ZodString;
|
|
419
441
|
href: z.ZodString;
|
|
@@ -422,6 +444,7 @@ export declare const dataInsightsWidgetResultSchema: z.ZodObject<{
|
|
|
422
444
|
explore: "explore";
|
|
423
445
|
notebook: "notebook";
|
|
424
446
|
}>>;
|
|
447
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
425
448
|
}, z.core.$loose>>>;
|
|
426
449
|
}, z.core.$loose>>;
|
|
427
450
|
}, z.core.$loose>;
|
|
@@ -456,6 +479,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
456
479
|
explore: "explore";
|
|
457
480
|
notebook: "notebook";
|
|
458
481
|
}>>;
|
|
482
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
459
483
|
}, z.core.$loose>, z.ZodObject<{
|
|
460
484
|
id: z.ZodOptional<z.ZodString>;
|
|
461
485
|
type: z.ZodLiteral<"copy">;
|
|
@@ -510,6 +534,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
510
534
|
explore: "explore";
|
|
511
535
|
notebook: "notebook";
|
|
512
536
|
}>>;
|
|
537
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
513
538
|
}, z.core.$loose>, z.ZodObject<{
|
|
514
539
|
id: z.ZodOptional<z.ZodString>;
|
|
515
540
|
type: z.ZodLiteral<"copy">;
|
|
@@ -544,6 +569,8 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
544
569
|
axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
545
570
|
valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
|
|
546
571
|
valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
572
|
+
valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
|
|
573
|
+
horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
|
|
547
574
|
xKey: z.ZodString;
|
|
548
575
|
series: z.ZodArray<z.ZodObject<{
|
|
549
576
|
key: z.ZodString;
|
|
@@ -552,6 +579,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
552
579
|
}, z.core.$loose>>;
|
|
553
580
|
data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
554
581
|
sampled: z.ZodOptional<z.ZodBoolean>;
|
|
582
|
+
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
555
583
|
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
556
584
|
label: z.ZodString;
|
|
557
585
|
href: z.ZodString;
|
|
@@ -560,6 +588,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
560
588
|
explore: "explore";
|
|
561
589
|
notebook: "notebook";
|
|
562
590
|
}>>;
|
|
591
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
563
592
|
}, z.core.$loose>>>;
|
|
564
593
|
}, z.core.$loose>;
|
|
565
594
|
}, z.core.$loose>, z.ZodObject<{
|
|
@@ -593,6 +622,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
593
622
|
explore: "explore";
|
|
594
623
|
notebook: "notebook";
|
|
595
624
|
}>>;
|
|
625
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
596
626
|
}, z.core.$loose>, z.ZodObject<{
|
|
597
627
|
id: z.ZodOptional<z.ZodString>;
|
|
598
628
|
type: z.ZodLiteral<"copy">;
|
|
@@ -642,6 +672,8 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
642
672
|
axisTitleFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
643
673
|
valueLabelFontSize: z.ZodOptional<z.ZodNumber>;
|
|
644
674
|
valueLabelFontWeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<400>, z.ZodLiteral<500>]>>;
|
|
675
|
+
valueAxisTickInterval: z.ZodOptional<z.ZodNumber>;
|
|
676
|
+
horizontalCategoryGapRatio: z.ZodOptional<z.ZodNumber>;
|
|
645
677
|
xKey: z.ZodString;
|
|
646
678
|
series: z.ZodArray<z.ZodObject<{
|
|
647
679
|
key: z.ZodString;
|
|
@@ -650,6 +682,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
650
682
|
}, z.core.$loose>>;
|
|
651
683
|
data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
652
684
|
sampled: z.ZodOptional<z.ZodBoolean>;
|
|
685
|
+
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
653
686
|
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
654
687
|
label: z.ZodString;
|
|
655
688
|
href: z.ZodString;
|
|
@@ -658,6 +691,7 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
658
691
|
explore: "explore";
|
|
659
692
|
notebook: "notebook";
|
|
660
693
|
}>>;
|
|
694
|
+
presentation: z.ZodOptional<z.ZodLiteral<"icon">>;
|
|
661
695
|
}, z.core.$loose>>>;
|
|
662
696
|
}, z.core.$loose>>;
|
|
663
697
|
}, z.core.$loose>]>;
|
|
@@ -13,6 +13,71 @@ function isRecord(value) {
|
|
|
13
13
|
function isString(value) {
|
|
14
14
|
return typeof value === "string" && value.length > 0;
|
|
15
15
|
}
|
|
16
|
+
const MAX_DATA_CHART_AXIS_TICKS = 100;
|
|
17
|
+
export const DATA_WIDGET_MAX_CHART_POINTS = 200;
|
|
18
|
+
function chartRowsForRender(rows) {
|
|
19
|
+
return rows.slice(0, DATA_WIDGET_MAX_CHART_POINTS);
|
|
20
|
+
}
|
|
21
|
+
function numericWidgetValue(value) {
|
|
22
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
23
|
+
return value;
|
|
24
|
+
if (typeof value !== "string" || !value.trim())
|
|
25
|
+
return null;
|
|
26
|
+
const parsed = Number(value);
|
|
27
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
28
|
+
}
|
|
29
|
+
function hasBoundedValueAxisTicks(chart) {
|
|
30
|
+
const interval = chart.valueAxisTickInterval;
|
|
31
|
+
if (interval === undefined)
|
|
32
|
+
return true;
|
|
33
|
+
if (typeof interval !== "number" ||
|
|
34
|
+
!Number.isFinite(interval) ||
|
|
35
|
+
interval < 1e-12) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const series = Array.isArray(chart.series) ? chart.series : [];
|
|
39
|
+
const rows = Array.isArray(chart.data) ? chartRowsForRender(chart.data) : [];
|
|
40
|
+
let min = Number.POSITIVE_INFINITY;
|
|
41
|
+
let max = Number.NEGATIVE_INFINITY;
|
|
42
|
+
for (const row of rows) {
|
|
43
|
+
if (!isRecord(row))
|
|
44
|
+
continue;
|
|
45
|
+
for (const item of series) {
|
|
46
|
+
if (!isRecord(item) || !isString(item.key))
|
|
47
|
+
continue;
|
|
48
|
+
const value = numericWidgetValue(row[item.key]);
|
|
49
|
+
if (value === null)
|
|
50
|
+
continue;
|
|
51
|
+
min = Math.min(min, value);
|
|
52
|
+
max = Math.max(max, value);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!Number.isFinite(min) || !Number.isFinite(max)) {
|
|
56
|
+
min = 0;
|
|
57
|
+
max = 1;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
if (chart.type === "bar" || chart.type === "area") {
|
|
61
|
+
min = Math.min(0, min);
|
|
62
|
+
max = Math.max(0, max);
|
|
63
|
+
}
|
|
64
|
+
if (min === max) {
|
|
65
|
+
const padding = Math.abs(max || 1) * 0.2;
|
|
66
|
+
min -= padding;
|
|
67
|
+
max += padding;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!Number.isFinite(max - min))
|
|
71
|
+
return false;
|
|
72
|
+
const firstTick = Math.ceil(min / interval - 1e-9);
|
|
73
|
+
const lastTick = Math.floor(max / interval + 1e-9);
|
|
74
|
+
const tickCount = lastTick - firstTick + 1;
|
|
75
|
+
return (Number.isSafeInteger(firstTick) &&
|
|
76
|
+
Number.isSafeInteger(lastTick) &&
|
|
77
|
+
Number.isSafeInteger(tickCount) &&
|
|
78
|
+
tickCount > 0 &&
|
|
79
|
+
tickCount <= MAX_DATA_CHART_AXIS_TICKS);
|
|
80
|
+
}
|
|
16
81
|
export function normalizeDataWidgetKind(value) {
|
|
17
82
|
if (value === DATA_TABLE_WIDGET)
|
|
18
83
|
return DATA_TABLE_WIDGET;
|
|
@@ -81,6 +146,14 @@ export function isDataChartWidget(value) {
|
|
|
81
146
|
(value.valueLabelFontWeight === undefined ||
|
|
82
147
|
value.valueLabelFontWeight === 400 ||
|
|
83
148
|
value.valueLabelFontWeight === 500) &&
|
|
149
|
+
(value.horizontalCategoryGapRatio === undefined ||
|
|
150
|
+
(typeof value.horizontalCategoryGapRatio === "number" &&
|
|
151
|
+
Number.isFinite(value.horizontalCategoryGapRatio) &&
|
|
152
|
+
value.horizontalCategoryGapRatio >= 0 &&
|
|
153
|
+
value.horizontalCategoryGapRatio <= 0.9)) &&
|
|
154
|
+
(value.sampled === undefined || typeof value.sampled === "boolean") &&
|
|
155
|
+
(value.truncated === undefined || typeof value.truncated === "boolean") &&
|
|
156
|
+
hasBoundedValueAxisTicks(value) &&
|
|
84
157
|
isString(value.xKey) &&
|
|
85
158
|
Array.isArray(value.series) &&
|
|
86
159
|
value.series.every((series) => isRecord(series) &&
|
|
@@ -89,7 +162,7 @@ export function isDataChartWidget(value) {
|
|
|
89
162
|
(series.color === undefined || typeof series.color === "string")) &&
|
|
90
163
|
(value.actions === undefined ||
|
|
91
164
|
(Array.isArray(value.actions) &&
|
|
92
|
-
value.actions.every(
|
|
165
|
+
value.actions.every(isDataWidgetChartAction))) &&
|
|
93
166
|
Array.isArray(value.data) &&
|
|
94
167
|
value.data.every(isRecord));
|
|
95
168
|
}
|
|
@@ -102,6 +175,11 @@ function isDataWidgetAction(value) {
|
|
|
102
175
|
isString(value.href) &&
|
|
103
176
|
(value.icon === undefined || isDataWidgetActionIcon(value.icon)));
|
|
104
177
|
}
|
|
178
|
+
function isDataWidgetChartAction(value) {
|
|
179
|
+
const presentation = isRecord(value) ? value.presentation : undefined;
|
|
180
|
+
return (isDataWidgetAction(value) &&
|
|
181
|
+
(presentation === undefined || presentation === "icon"));
|
|
182
|
+
}
|
|
105
183
|
function normalizePrimaryAction(value) {
|
|
106
184
|
if (!isRecord(value) || !isString(value.label) || !isString(value.href)) {
|
|
107
185
|
return undefined;
|
|
@@ -126,7 +204,8 @@ function isDataWidgetDisplayAction(value) {
|
|
|
126
204
|
}
|
|
127
205
|
if (value.type === "link") {
|
|
128
206
|
return (isString(value.href) &&
|
|
129
|
-
(value.icon === undefined || isDataWidgetActionIcon(value.icon))
|
|
207
|
+
(value.icon === undefined || isDataWidgetActionIcon(value.icon)) &&
|
|
208
|
+
(value.presentation === undefined || value.presentation === "icon"));
|
|
130
209
|
}
|
|
131
210
|
if (value.type === "copy")
|
|
132
211
|
return isString(value.text);
|
|
@@ -242,7 +321,6 @@ export function isDataWidgetResult(value) {
|
|
|
242
321
|
return normalizeDataWidgetResult(value) !== null;
|
|
243
322
|
}
|
|
244
323
|
export const DATA_WIDGET_MAX_ROWS = 50;
|
|
245
|
-
export const DATA_WIDGET_MAX_CHART_POINTS = 200;
|
|
246
324
|
export function clampDataWidgetRows(result) {
|
|
247
325
|
const source = result;
|
|
248
326
|
const table = source.table;
|
|
@@ -259,8 +337,9 @@ export function clampDataWidgetRows(result) {
|
|
|
259
337
|
const clampedChart = chartSeries && chartSeries.data.length > DATA_WIDGET_MAX_CHART_POINTS
|
|
260
338
|
? {
|
|
261
339
|
...chartSeries,
|
|
262
|
-
data: chartSeries.data
|
|
340
|
+
data: chartRowsForRender(chartSeries.data),
|
|
263
341
|
sampled: true,
|
|
342
|
+
truncated: true,
|
|
264
343
|
}
|
|
265
344
|
: chartSeries;
|
|
266
345
|
if (clampedTable === table && clampedChart === chartSeries)
|
|
@@ -300,6 +379,7 @@ const dataWidgetActionSchema = z
|
|
|
300
379
|
label: z.string().min(1),
|
|
301
380
|
href: z.string().min(1),
|
|
302
381
|
icon: z.enum(["explore", "camera", "notebook"]).optional(),
|
|
382
|
+
presentation: z.literal("icon").optional(),
|
|
303
383
|
})
|
|
304
384
|
.passthrough();
|
|
305
385
|
export const dataChartWidgetSchema = z
|
|
@@ -318,13 +398,20 @@ export const dataChartWidgetSchema = z
|
|
|
318
398
|
axisTitleFontWeight: z.union([z.literal(400), z.literal(500)]).optional(),
|
|
319
399
|
valueLabelFontSize: z.number().int().min(8).max(24).optional(),
|
|
320
400
|
valueLabelFontWeight: z.union([z.literal(400), z.literal(500)]).optional(),
|
|
401
|
+
valueAxisTickInterval: z.number().finite().min(1e-12).optional(),
|
|
402
|
+
horizontalCategoryGapRatio: z.number().finite().min(0).max(0.9).optional(),
|
|
321
403
|
xKey: z.string().min(1),
|
|
322
404
|
series: z.array(dataChartSeriesDefinitionSchema).min(1),
|
|
323
405
|
data: z.array(z.record(z.string(), z.unknown())),
|
|
324
406
|
sampled: z.boolean().optional(),
|
|
407
|
+
truncated: z.boolean().optional(),
|
|
325
408
|
actions: z.array(dataWidgetActionSchema).optional(),
|
|
326
409
|
})
|
|
327
410
|
.passthrough();
|
|
411
|
+
const boundedDataChartWidgetSchema = dataChartWidgetSchema.refine(hasBoundedValueAxisTicks, {
|
|
412
|
+
path: ["valueAxisTickInterval"],
|
|
413
|
+
message: `valueAxisTickInterval must produce between 1 and ${MAX_DATA_CHART_AXIS_TICKS} ticks.`,
|
|
414
|
+
});
|
|
328
415
|
const primaryActionSchema = z
|
|
329
416
|
.object({
|
|
330
417
|
label: z.string().min(1),
|
|
@@ -347,6 +434,7 @@ const dataWidgetDisplayActionSchema = z.discriminatedUnion("type", [
|
|
|
347
434
|
label: z.string().min(1),
|
|
348
435
|
href: z.string().min(1),
|
|
349
436
|
icon: z.enum(["explore", "camera", "notebook"]).optional(),
|
|
437
|
+
presentation: z.literal("icon").optional(),
|
|
350
438
|
})
|
|
351
439
|
.passthrough(),
|
|
352
440
|
z
|
|
@@ -384,14 +472,14 @@ export const dataTableWidgetResultSchema = dataWidgetBaseSchema
|
|
|
384
472
|
export const dataChartWidgetResultSchema = dataWidgetBaseSchema
|
|
385
473
|
.extend({
|
|
386
474
|
widget: z.literal(DATA_CHART_WIDGET),
|
|
387
|
-
chartSeries:
|
|
475
|
+
chartSeries: boundedDataChartWidgetSchema,
|
|
388
476
|
})
|
|
389
477
|
.passthrough();
|
|
390
478
|
export const dataInsightsWidgetResultSchema = dataWidgetBaseSchema
|
|
391
479
|
.extend({
|
|
392
480
|
widget: z.literal(DATA_INSIGHTS_WIDGET),
|
|
393
481
|
table: dataTableWidgetSchema.optional(),
|
|
394
|
-
chartSeries:
|
|
482
|
+
chartSeries: boundedDataChartWidgetSchema.optional(),
|
|
395
483
|
})
|
|
396
484
|
.passthrough()
|
|
397
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));
|