@xpert-ai/plugin-live-dashboard 0.4.1 → 0.6.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/.xpertai-plugin/plugin.json +1 -1
- package/README.md +8 -2
- package/dist/index.js +3 -1
- package/dist/lib/agent.schema.d.ts +177 -23
- package/dist/lib/agent.schema.js +11 -9
- package/dist/lib/archive.service.d.ts +169 -0
- package/dist/lib/archive.service.js +147 -0
- package/dist/lib/bounded-map.d.ts +2 -0
- package/dist/lib/bounded-map.js +25 -0
- package/dist/lib/capacity.d.ts +14 -0
- package/dist/lib/capacity.js +16 -0
- package/dist/lib/content.provider.d.ts +1 -1
- package/dist/lib/dashboard-archive.d.ts +70 -0
- package/dist/lib/dashboard-archive.js +118 -0
- package/dist/lib/dashboard-queries.d.ts +1 -1
- package/dist/lib/dashboard-queries.js +11 -6
- package/dist/lib/dashboard-receipt.js +1 -1
- package/dist/lib/dashboard-sources.d.ts +69 -0
- package/dist/lib/dashboard-sources.js +38 -0
- package/dist/lib/dashboard-view.schema.d.ts +422 -88
- package/dist/lib/dashboard.schema.d.ts +379 -58
- package/dist/lib/dashboard.schema.js +20 -2
- package/dist/lib/dashboard.service.d.ts +80 -15
- package/dist/lib/dashboard.service.js +65 -9
- package/dist/lib/definition-tools.d.ts +4 -4
- package/dist/lib/document-host.js +1 -1
- package/dist/lib/document-package.d.ts +19 -4
- package/dist/lib/editing-patch.d.ts +3 -0
- package/dist/lib/editing-patch.js +4 -2
- package/dist/lib/editing-session.d.ts +4 -4
- package/dist/lib/editing.d.ts +204 -20
- package/dist/lib/editing.js +10 -3
- package/dist/lib/filter-evidence.d.ts +28 -0
- package/dist/lib/filter-evidence.js +3 -2
- package/dist/lib/html-guidance.d.ts +1 -0
- package/dist/lib/html-guidance.js +2 -1
- package/dist/lib/html-validation-feedback.d.ts +7 -0
- package/dist/lib/html-validation-feedback.js +19 -0
- package/dist/lib/html-validation.js +3 -2
- package/dist/lib/inspection-host.d.ts +7 -0
- package/dist/lib/inspection-host.js +48 -0
- package/dist/lib/inspection-runtime.d.ts +2 -0
- package/dist/lib/inspection-runtime.js +77 -0
- package/dist/lib/json-input.d.ts +4 -0
- package/dist/lib/json-input.js +21 -0
- package/dist/lib/middleware.d.ts +3 -1
- package/dist/lib/middleware.js +92 -13
- package/dist/lib/plugin.js +3 -1
- package/dist/lib/presentation.provider.d.ts +24 -9
- package/dist/lib/presentation.provider.js +2 -1
- package/dist/lib/preview-retry.d.ts +4 -3
- package/dist/lib/preview-retry.js +13 -7
- package/dist/lib/prompt-workflows.js +1 -1
- package/dist/lib/query-session.d.ts +9 -0
- package/dist/lib/query-session.js +64 -0
- package/dist/lib/save-requests.d.ts +118 -0
- package/dist/lib/save-requests.js +199 -0
- package/dist/lib/source-executions.d.ts +437 -0
- package/dist/lib/source-executions.js +49 -0
- package/dist/lib/source-validation.d.ts +2 -0
- package/dist/lib/source-validation.js +21 -0
- package/dist/lib/view.provider.d.ts +213 -8
- package/dist/lib/view.provider.js +47 -5
- package/dist/remote/app.css +1 -1
- package/dist/remote/app.js +185 -63
- package/dist/remote/build-manifest.json +52 -33
- package/dist/sandbox-actions/action.json +1 -1
- package/dist/sandbox-actions/bundle/host.js +63 -14
- package/dist/sandbox-actions/bundle/validate.mjs +2 -2
- package/dist/validation/host-entry.d.ts +5 -1
- package/dist/validation/host-entry.js +21 -4
- package/docs/docs.json +5 -1
- package/docs/large-dashboards-acceptance.mdx +74 -0
- package/docs/large-dashboards.mdx +80 -0
- package/docs/sources-inspect-portability-acceptance.mdx +67 -0
- package/docs/sources-inspect-portability.mdx +115 -0
- package/package.json +8 -7
- package/skills/live-dashboard/SKILL.md +5 -4
- package/skills/live-dashboard/references/source-inspection.md +17 -0
package/dist/lib/editing.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DashboardSaveRequests } from './save-requests';
|
|
1
2
|
import { z } from 'zod/v3';
|
|
2
3
|
import type { AnalyticsBinding, XpertResolvedViewHostContext } from '@xpert-ai/contracts';
|
|
3
4
|
import { type IAgentMiddlewareContext } from '@xpert-ai/plugin-sdk';
|
|
@@ -6,6 +7,66 @@ import { DashboardService } from './dashboard.service';
|
|
|
6
7
|
import { type DashboardSelection } from './editing-session';
|
|
7
8
|
export { dashboardSelectionSchema, dashboardContextSchema } from './editing-session';
|
|
8
9
|
export declare const updateToolSchema: z.ZodObject<{
|
|
10
|
+
sourceMetadata: z.ZodOptional<z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodObject<{
|
|
11
|
+
bindingId: z.ZodString;
|
|
12
|
+
title: z.ZodString;
|
|
13
|
+
description: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, "strict", z.ZodTypeAny, {
|
|
15
|
+
bindingId: string;
|
|
16
|
+
title: string;
|
|
17
|
+
description?: string | undefined;
|
|
18
|
+
}, {
|
|
19
|
+
bindingId: string;
|
|
20
|
+
title: string;
|
|
21
|
+
description?: string | undefined;
|
|
22
|
+
}>, "many">, {
|
|
23
|
+
bindingId: string;
|
|
24
|
+
title: string;
|
|
25
|
+
description?: string | undefined;
|
|
26
|
+
}[], unknown>>>;
|
|
27
|
+
components: z.ZodOptional<z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodObject<{
|
|
28
|
+
id: z.ZodString;
|
|
29
|
+
elementId: z.ZodString;
|
|
30
|
+
title: z.ZodString;
|
|
31
|
+
kind: z.ZodEnum<["metric", "chart", "table", "filter", "text"]>;
|
|
32
|
+
sources: z.ZodArray<z.ZodObject<{
|
|
33
|
+
bindingId: z.ZodString;
|
|
34
|
+
fieldIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
35
|
+
}, "strict", z.ZodTypeAny, {
|
|
36
|
+
bindingId: string;
|
|
37
|
+
fieldIds?: string[] | undefined;
|
|
38
|
+
}, {
|
|
39
|
+
bindingId: string;
|
|
40
|
+
fieldIds?: string[] | undefined;
|
|
41
|
+
}>, "many">;
|
|
42
|
+
}, "strict", z.ZodTypeAny, {
|
|
43
|
+
title: string;
|
|
44
|
+
id: string;
|
|
45
|
+
elementId: string;
|
|
46
|
+
kind: "filter" | "metric" | "chart" | "table" | "text";
|
|
47
|
+
sources: {
|
|
48
|
+
bindingId: string;
|
|
49
|
+
fieldIds?: string[] | undefined;
|
|
50
|
+
}[];
|
|
51
|
+
}, {
|
|
52
|
+
title: string;
|
|
53
|
+
id: string;
|
|
54
|
+
elementId: string;
|
|
55
|
+
kind: "filter" | "metric" | "chart" | "table" | "text";
|
|
56
|
+
sources: {
|
|
57
|
+
bindingId: string;
|
|
58
|
+
fieldIds?: string[] | undefined;
|
|
59
|
+
}[];
|
|
60
|
+
}>, "many">, {
|
|
61
|
+
title: string;
|
|
62
|
+
id: string;
|
|
63
|
+
elementId: string;
|
|
64
|
+
kind: "filter" | "metric" | "chart" | "table" | "text";
|
|
65
|
+
sources: {
|
|
66
|
+
bindingId: string;
|
|
67
|
+
fieldIds?: string[] | undefined;
|
|
68
|
+
}[];
|
|
69
|
+
}[], unknown>>>;
|
|
9
70
|
controls: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodObject<{
|
|
10
71
|
controlId: z.ZodString;
|
|
11
72
|
type: z.ZodEnum<["string", "number", "boolean", "date"]>;
|
|
@@ -42,24 +103,24 @@ export declare const updateToolSchema: z.ZodObject<{
|
|
|
42
103
|
color: z.ZodOptional<z.ZodString>;
|
|
43
104
|
}, "strict", z.ZodTypeAny, {
|
|
44
105
|
type: "bar" | "line" | "area" | "pie" | "scatter";
|
|
45
|
-
id: string;
|
|
46
106
|
title: string;
|
|
107
|
+
id: string;
|
|
47
108
|
datasetId: string;
|
|
48
109
|
x: string;
|
|
49
110
|
y: string;
|
|
50
111
|
color?: string | undefined;
|
|
51
112
|
}, {
|
|
52
113
|
type: "bar" | "line" | "area" | "pie" | "scatter";
|
|
53
|
-
id: string;
|
|
54
114
|
title: string;
|
|
115
|
+
id: string;
|
|
55
116
|
datasetId: string;
|
|
56
117
|
x: string;
|
|
57
118
|
y: string;
|
|
58
119
|
color?: string | undefined;
|
|
59
120
|
}>, "many">, {
|
|
60
121
|
type: "bar" | "line" | "area" | "pie" | "scatter";
|
|
61
|
-
id: string;
|
|
62
122
|
title: string;
|
|
123
|
+
id: string;
|
|
63
124
|
datasetId: string;
|
|
64
125
|
x: string;
|
|
65
126
|
y: string;
|
|
@@ -71,18 +132,18 @@ export declare const updateToolSchema: z.ZodObject<{
|
|
|
71
132
|
datasetId: z.ZodString;
|
|
72
133
|
fields: z.ZodArray<z.ZodString, "many">;
|
|
73
134
|
}, "strict", z.ZodTypeAny, {
|
|
74
|
-
id: string;
|
|
75
135
|
title: string;
|
|
136
|
+
id: string;
|
|
76
137
|
datasetId: string;
|
|
77
138
|
fields: string[];
|
|
78
139
|
}, {
|
|
79
|
-
id: string;
|
|
80
140
|
title: string;
|
|
141
|
+
id: string;
|
|
81
142
|
datasetId: string;
|
|
82
143
|
fields: string[];
|
|
83
144
|
}>, "many">, {
|
|
84
|
-
id: string;
|
|
85
145
|
title: string;
|
|
146
|
+
id: string;
|
|
86
147
|
datasetId: string;
|
|
87
148
|
fields: string[];
|
|
88
149
|
}[], unknown>>;
|
|
@@ -94,16 +155,19 @@ export declare const updateToolSchema: z.ZodObject<{
|
|
|
94
155
|
controlIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
95
156
|
viewIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
96
157
|
htmlElementIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
158
|
+
componentIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
97
159
|
}, "strict", z.ZodTypeAny, {
|
|
98
160
|
bindingIds: string[];
|
|
99
161
|
controlIds: string[];
|
|
100
162
|
viewIds: string[];
|
|
101
163
|
htmlElementIds: string[];
|
|
164
|
+
componentIds: string[];
|
|
102
165
|
}, {
|
|
103
166
|
bindingIds?: string[] | undefined;
|
|
104
167
|
controlIds?: string[] | undefined;
|
|
105
168
|
viewIds?: string[] | undefined;
|
|
106
169
|
htmlElementIds?: string[] | undefined;
|
|
170
|
+
componentIds?: string[] | undefined;
|
|
107
171
|
}>>;
|
|
108
172
|
title: z.ZodString;
|
|
109
173
|
editId: z.ZodString;
|
|
@@ -116,6 +180,21 @@ export declare const updateToolSchema: z.ZodObject<{
|
|
|
116
180
|
expectedRevision: number;
|
|
117
181
|
expectedCurrentVersionId: string | null;
|
|
118
182
|
editId: string;
|
|
183
|
+
sourceMetadata?: {
|
|
184
|
+
bindingId: string;
|
|
185
|
+
title: string;
|
|
186
|
+
description?: string | undefined;
|
|
187
|
+
}[] | undefined;
|
|
188
|
+
components?: {
|
|
189
|
+
title: string;
|
|
190
|
+
id: string;
|
|
191
|
+
elementId: string;
|
|
192
|
+
kind: "filter" | "metric" | "chart" | "table" | "text";
|
|
193
|
+
sources: {
|
|
194
|
+
bindingId: string;
|
|
195
|
+
fieldIds?: string[] | undefined;
|
|
196
|
+
}[];
|
|
197
|
+
}[] | undefined;
|
|
119
198
|
controls?: {
|
|
120
199
|
type: "string" | "number" | "boolean" | "date";
|
|
121
200
|
controlId: string;
|
|
@@ -125,16 +204,16 @@ export declare const updateToolSchema: z.ZodObject<{
|
|
|
125
204
|
}[] | undefined;
|
|
126
205
|
charts?: {
|
|
127
206
|
type: "bar" | "line" | "area" | "pie" | "scatter";
|
|
128
|
-
id: string;
|
|
129
207
|
title: string;
|
|
208
|
+
id: string;
|
|
130
209
|
datasetId: string;
|
|
131
210
|
x: string;
|
|
132
211
|
y: string;
|
|
133
212
|
color?: string | undefined;
|
|
134
213
|
}[] | undefined;
|
|
135
214
|
tables?: {
|
|
136
|
-
id: string;
|
|
137
215
|
title: string;
|
|
216
|
+
id: string;
|
|
138
217
|
datasetId: string;
|
|
139
218
|
fields: string[];
|
|
140
219
|
}[] | undefined;
|
|
@@ -146,6 +225,7 @@ export declare const updateToolSchema: z.ZodObject<{
|
|
|
146
225
|
controlIds: string[];
|
|
147
226
|
viewIds: string[];
|
|
148
227
|
htmlElementIds: string[];
|
|
228
|
+
componentIds: string[];
|
|
149
229
|
} | undefined;
|
|
150
230
|
htmlPath?: string | undefined;
|
|
151
231
|
}, {
|
|
@@ -153,6 +233,8 @@ export declare const updateToolSchema: z.ZodObject<{
|
|
|
153
233
|
expectedRevision: number;
|
|
154
234
|
expectedCurrentVersionId: string | null;
|
|
155
235
|
editId: string;
|
|
236
|
+
sourceMetadata?: unknown;
|
|
237
|
+
components?: unknown;
|
|
156
238
|
controls?: unknown;
|
|
157
239
|
charts?: unknown;
|
|
158
240
|
tables?: unknown;
|
|
@@ -164,12 +246,13 @@ export declare const updateToolSchema: z.ZodObject<{
|
|
|
164
246
|
controlIds?: string[] | undefined;
|
|
165
247
|
viewIds?: string[] | undefined;
|
|
166
248
|
htmlElementIds?: string[] | undefined;
|
|
249
|
+
componentIds?: string[] | undefined;
|
|
167
250
|
} | undefined;
|
|
168
251
|
htmlPath?: string | undefined;
|
|
169
252
|
}>;
|
|
170
|
-
export declare const EDITING_GUIDANCE = "Opening or reading a dashboard does not modify it. A selection_required result is normal: show its message to the user and wait for an explicit selection; do not retry, infer a target from history, or create a replacement. Do not save an unchanged editing copy or reopen/update merely to confirm a successful save; use the mutation receipt. For existing dashboards, call dashboard_open first and inspect presentation.type. For standard dashboards, update definition fields directly: a rename needs only title, editId, expectedRevision and expectedCurrentVersionId. No HTML file exists; omit htmlPath and libraries. For HTML dashboards only, open prepares a unique editing copy at htmlPath. Read with sandbox_read_file. If a long HTML line is truncated, do not repeat the same read: use dashboard_read_html with editId and follow nextOffset until null to inspect the saved source, then apply exact replacements to htmlPath. Never replace a file with a truncated preview. Edit with sandbox_edit_file/multi_edit_file (sandbox_write_file is create-only), then call dashboard_update with that exact htmlPath and read revisions. If the user requests a rename, include the new title in this same update; editing the HTML heading alone does not rename the Artifact. Save each batch automatically without human confirmation. Files are not dashboard saves. Preserve Binding semantics, stable component IDs and dependency locks unless requested. Update arrays upsert by ID, preserving omitted components; removals must name explicitly requested deletions. HTML updates retain existing element IDs. For new HTML, assign stable IDs to every KPI, chart, detail table and filter. Read and patch the current file instead of rebuilding unrelated sections. On conflict retain the editing file, open the latest draft and reconcile; never silently overwrite. Historical versions are read-only references. All Agent saves are drafts; only the Workbench human publish action creates formal versions. Read the live-dashboard skill for the complete workflow.";
|
|
253
|
+
export declare const EDITING_GUIDANCE = "Opening or reading a dashboard does not modify it. A selection_required result is normal: show its message to the user and wait for an explicit selection; do not retry, infer a target from history, or create a replacement. Do not save an unchanged editing copy or reopen/update merely to confirm a successful save; use the mutation receipt. For existing dashboards, call dashboard_open first and inspect presentation.type. For standard dashboards, update definition fields directly: a rename needs only title, editId, expectedRevision and expectedCurrentVersionId. No HTML file exists; omit htmlPath and libraries. For HTML dashboards only, open prepares a unique editing copy at htmlPath. Read with sandbox_read_file. If a long HTML line is truncated, do not repeat the same read: use dashboard_read_html with editId and follow nextOffset until null to inspect the saved source, then apply exact replacements to htmlPath. Never replace a file with a truncated preview. Edit with sandbox_edit_file/multi_edit_file (sandbox_write_file is create-only), then call dashboard_update with that exact htmlPath and read revisions. If the user requests a rename, include the new title in this same update; editing the HTML heading alone does not rename the Artifact. Save each batch automatically without human confirmation. Files are not dashboard saves. Preserve Binding semantics, stable component IDs and dependency locks unless requested. To add filters to an existing Binding, copy its complete dashboard_open.bindings[] entry, retain binding.id and existing parameters[].controlId, and call dashboard_preview_binding after changing payload/parameters/defaults. Binding ID is independent of output.datasetId; simplified dashboard_preview derives the ID from datasetId and can accidentally add a new Binding instead of updating the old one. Use the stable Binding ID in HTML query/subscribe calls. Submit every intended changed/new Binding previewId and matching controls with htmlPath in the same dashboard_update. Update arrays upsert by ID, preserving omitted components; removals must name explicitly requested deletions. On preflight failure, compare expected/requested Binding IDs, repair the HTML or previews, and retain all intended previewIds, controls, title and htmlPath when retrying. Dropping previewIds does not register new HTML queries. Do not remove an existing Binding merely to suppress validation. HTML updates retain existing element IDs. For new HTML, assign stable IDs to every KPI, chart, detail table and filter. Read and patch the current file instead of rebuilding unrelated sections. On conflict retain the editing file, open the latest draft and reconcile; never silently overwrite. Historical versions are read-only references. All Agent saves are drafts; only the Workbench human publish action creates formal versions. Read the live-dashboard skill for the complete workflow.";
|
|
171
254
|
/** Run-local read receipts carry planning versions; authorization and CAS remain in the domain service. */
|
|
172
|
-
export declare function createEditingTools(service: DashboardService, scope: XpertResolvedViewHostContext, context: IAgentMiddlewareContext, resolvePreviews: (ids: string[]) => AnalyticsBinding[], validateFinal: (manifest: DashboardManifest, requirePreviews: boolean, changedBindingIds?: string[]) => void, onOpen?: (path: string, artifactId: string) => void, currentTarget?: (config: unknown) => DashboardSelection | null | undefined): (import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
255
|
+
export declare function createEditingTools(service: DashboardService, scope: XpertResolvedViewHostContext, context: IAgentMiddlewareContext, resolvePreviews: (ids: string[]) => AnalyticsBinding[], validateFinal: (manifest: DashboardManifest, requirePreviews: boolean, changedBindingIds?: string[]) => void, onOpen?: (path: string, artifactId: string) => void, currentTarget?: (config: unknown) => DashboardSelection | null | undefined, saveRequests?: DashboardSaveRequests): (import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
173
256
|
page: z.ZodDefault<z.ZodNumber>;
|
|
174
257
|
}, "strict", z.ZodTypeAny, {
|
|
175
258
|
page: number;
|
|
@@ -217,6 +300,66 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
217
300
|
}, {
|
|
218
301
|
artifactId?: string | undefined;
|
|
219
302
|
}, string> | import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
303
|
+
sourceMetadata: z.ZodOptional<z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodObject<{
|
|
304
|
+
bindingId: z.ZodString;
|
|
305
|
+
title: z.ZodString;
|
|
306
|
+
description: z.ZodOptional<z.ZodString>;
|
|
307
|
+
}, "strict", z.ZodTypeAny, {
|
|
308
|
+
bindingId: string;
|
|
309
|
+
title: string;
|
|
310
|
+
description?: string | undefined;
|
|
311
|
+
}, {
|
|
312
|
+
bindingId: string;
|
|
313
|
+
title: string;
|
|
314
|
+
description?: string | undefined;
|
|
315
|
+
}>, "many">, {
|
|
316
|
+
bindingId: string;
|
|
317
|
+
title: string;
|
|
318
|
+
description?: string | undefined;
|
|
319
|
+
}[], unknown>>>;
|
|
320
|
+
components: z.ZodOptional<z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodObject<{
|
|
321
|
+
id: z.ZodString;
|
|
322
|
+
elementId: z.ZodString;
|
|
323
|
+
title: z.ZodString;
|
|
324
|
+
kind: z.ZodEnum<["metric", "chart", "table", "filter", "text"]>;
|
|
325
|
+
sources: z.ZodArray<z.ZodObject<{
|
|
326
|
+
bindingId: z.ZodString;
|
|
327
|
+
fieldIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
328
|
+
}, "strict", z.ZodTypeAny, {
|
|
329
|
+
bindingId: string;
|
|
330
|
+
fieldIds?: string[] | undefined;
|
|
331
|
+
}, {
|
|
332
|
+
bindingId: string;
|
|
333
|
+
fieldIds?: string[] | undefined;
|
|
334
|
+
}>, "many">;
|
|
335
|
+
}, "strict", z.ZodTypeAny, {
|
|
336
|
+
title: string;
|
|
337
|
+
id: string;
|
|
338
|
+
elementId: string;
|
|
339
|
+
kind: "filter" | "metric" | "chart" | "table" | "text";
|
|
340
|
+
sources: {
|
|
341
|
+
bindingId: string;
|
|
342
|
+
fieldIds?: string[] | undefined;
|
|
343
|
+
}[];
|
|
344
|
+
}, {
|
|
345
|
+
title: string;
|
|
346
|
+
id: string;
|
|
347
|
+
elementId: string;
|
|
348
|
+
kind: "filter" | "metric" | "chart" | "table" | "text";
|
|
349
|
+
sources: {
|
|
350
|
+
bindingId: string;
|
|
351
|
+
fieldIds?: string[] | undefined;
|
|
352
|
+
}[];
|
|
353
|
+
}>, "many">, {
|
|
354
|
+
title: string;
|
|
355
|
+
id: string;
|
|
356
|
+
elementId: string;
|
|
357
|
+
kind: "filter" | "metric" | "chart" | "table" | "text";
|
|
358
|
+
sources: {
|
|
359
|
+
bindingId: string;
|
|
360
|
+
fieldIds?: string[] | undefined;
|
|
361
|
+
}[];
|
|
362
|
+
}[], unknown>>>;
|
|
220
363
|
controls: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodObject<{
|
|
221
364
|
controlId: z.ZodString;
|
|
222
365
|
type: z.ZodEnum<["string", "number", "boolean", "date"]>;
|
|
@@ -253,24 +396,24 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
253
396
|
color: z.ZodOptional<z.ZodString>;
|
|
254
397
|
}, "strict", z.ZodTypeAny, {
|
|
255
398
|
type: "bar" | "line" | "area" | "pie" | "scatter";
|
|
256
|
-
id: string;
|
|
257
399
|
title: string;
|
|
400
|
+
id: string;
|
|
258
401
|
datasetId: string;
|
|
259
402
|
x: string;
|
|
260
403
|
y: string;
|
|
261
404
|
color?: string | undefined;
|
|
262
405
|
}, {
|
|
263
406
|
type: "bar" | "line" | "area" | "pie" | "scatter";
|
|
264
|
-
id: string;
|
|
265
407
|
title: string;
|
|
408
|
+
id: string;
|
|
266
409
|
datasetId: string;
|
|
267
410
|
x: string;
|
|
268
411
|
y: string;
|
|
269
412
|
color?: string | undefined;
|
|
270
413
|
}>, "many">, {
|
|
271
414
|
type: "bar" | "line" | "area" | "pie" | "scatter";
|
|
272
|
-
id: string;
|
|
273
415
|
title: string;
|
|
416
|
+
id: string;
|
|
274
417
|
datasetId: string;
|
|
275
418
|
x: string;
|
|
276
419
|
y: string;
|
|
@@ -282,18 +425,18 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
282
425
|
datasetId: z.ZodString;
|
|
283
426
|
fields: z.ZodArray<z.ZodString, "many">;
|
|
284
427
|
}, "strict", z.ZodTypeAny, {
|
|
285
|
-
id: string;
|
|
286
428
|
title: string;
|
|
429
|
+
id: string;
|
|
287
430
|
datasetId: string;
|
|
288
431
|
fields: string[];
|
|
289
432
|
}, {
|
|
290
|
-
id: string;
|
|
291
433
|
title: string;
|
|
434
|
+
id: string;
|
|
292
435
|
datasetId: string;
|
|
293
436
|
fields: string[];
|
|
294
437
|
}>, "many">, {
|
|
295
|
-
id: string;
|
|
296
438
|
title: string;
|
|
439
|
+
id: string;
|
|
297
440
|
datasetId: string;
|
|
298
441
|
fields: string[];
|
|
299
442
|
}[], unknown>>;
|
|
@@ -305,16 +448,19 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
305
448
|
controlIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
306
449
|
viewIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
307
450
|
htmlElementIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
451
|
+
componentIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
308
452
|
}, "strict", z.ZodTypeAny, {
|
|
309
453
|
bindingIds: string[];
|
|
310
454
|
controlIds: string[];
|
|
311
455
|
viewIds: string[];
|
|
312
456
|
htmlElementIds: string[];
|
|
457
|
+
componentIds: string[];
|
|
313
458
|
}, {
|
|
314
459
|
bindingIds?: string[] | undefined;
|
|
315
460
|
controlIds?: string[] | undefined;
|
|
316
461
|
viewIds?: string[] | undefined;
|
|
317
462
|
htmlElementIds?: string[] | undefined;
|
|
463
|
+
componentIds?: string[] | undefined;
|
|
318
464
|
}>>;
|
|
319
465
|
title: z.ZodString;
|
|
320
466
|
editId: z.ZodString;
|
|
@@ -327,6 +473,21 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
327
473
|
expectedRevision: number;
|
|
328
474
|
expectedCurrentVersionId: string | null;
|
|
329
475
|
editId: string;
|
|
476
|
+
sourceMetadata?: {
|
|
477
|
+
bindingId: string;
|
|
478
|
+
title: string;
|
|
479
|
+
description?: string | undefined;
|
|
480
|
+
}[] | undefined;
|
|
481
|
+
components?: {
|
|
482
|
+
title: string;
|
|
483
|
+
id: string;
|
|
484
|
+
elementId: string;
|
|
485
|
+
kind: "filter" | "metric" | "chart" | "table" | "text";
|
|
486
|
+
sources: {
|
|
487
|
+
bindingId: string;
|
|
488
|
+
fieldIds?: string[] | undefined;
|
|
489
|
+
}[];
|
|
490
|
+
}[] | undefined;
|
|
330
491
|
controls?: {
|
|
331
492
|
type: "string" | "number" | "boolean" | "date";
|
|
332
493
|
controlId: string;
|
|
@@ -336,16 +497,16 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
336
497
|
}[] | undefined;
|
|
337
498
|
charts?: {
|
|
338
499
|
type: "bar" | "line" | "area" | "pie" | "scatter";
|
|
339
|
-
id: string;
|
|
340
500
|
title: string;
|
|
501
|
+
id: string;
|
|
341
502
|
datasetId: string;
|
|
342
503
|
x: string;
|
|
343
504
|
y: string;
|
|
344
505
|
color?: string | undefined;
|
|
345
506
|
}[] | undefined;
|
|
346
507
|
tables?: {
|
|
347
|
-
id: string;
|
|
348
508
|
title: string;
|
|
509
|
+
id: string;
|
|
349
510
|
datasetId: string;
|
|
350
511
|
fields: string[];
|
|
351
512
|
}[] | undefined;
|
|
@@ -357,6 +518,7 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
357
518
|
controlIds: string[];
|
|
358
519
|
viewIds: string[];
|
|
359
520
|
htmlElementIds: string[];
|
|
521
|
+
componentIds: string[];
|
|
360
522
|
} | undefined;
|
|
361
523
|
htmlPath?: string | undefined;
|
|
362
524
|
}, {
|
|
@@ -364,6 +526,8 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
364
526
|
expectedRevision: number;
|
|
365
527
|
expectedCurrentVersionId: string | null;
|
|
366
528
|
editId: string;
|
|
529
|
+
sourceMetadata?: unknown;
|
|
530
|
+
components?: unknown;
|
|
367
531
|
controls?: unknown;
|
|
368
532
|
charts?: unknown;
|
|
369
533
|
tables?: unknown;
|
|
@@ -375,6 +539,7 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
375
539
|
controlIds?: string[] | undefined;
|
|
376
540
|
viewIds?: string[] | undefined;
|
|
377
541
|
htmlElementIds?: string[] | undefined;
|
|
542
|
+
componentIds?: string[] | undefined;
|
|
378
543
|
} | undefined;
|
|
379
544
|
htmlPath?: string | undefined;
|
|
380
545
|
}>, {
|
|
@@ -382,6 +547,21 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
382
547
|
expectedRevision: number;
|
|
383
548
|
expectedCurrentVersionId: string | null;
|
|
384
549
|
editId: string;
|
|
550
|
+
sourceMetadata?: {
|
|
551
|
+
bindingId: string;
|
|
552
|
+
title: string;
|
|
553
|
+
description?: string | undefined;
|
|
554
|
+
}[] | undefined;
|
|
555
|
+
components?: {
|
|
556
|
+
title: string;
|
|
557
|
+
id: string;
|
|
558
|
+
elementId: string;
|
|
559
|
+
kind: "filter" | "metric" | "chart" | "table" | "text";
|
|
560
|
+
sources: {
|
|
561
|
+
bindingId: string;
|
|
562
|
+
fieldIds?: string[] | undefined;
|
|
563
|
+
}[];
|
|
564
|
+
}[] | undefined;
|
|
385
565
|
controls?: {
|
|
386
566
|
type: "string" | "number" | "boolean" | "date";
|
|
387
567
|
controlId: string;
|
|
@@ -391,16 +571,16 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
391
571
|
}[] | undefined;
|
|
392
572
|
charts?: {
|
|
393
573
|
type: "bar" | "line" | "area" | "pie" | "scatter";
|
|
394
|
-
id: string;
|
|
395
574
|
title: string;
|
|
575
|
+
id: string;
|
|
396
576
|
datasetId: string;
|
|
397
577
|
x: string;
|
|
398
578
|
y: string;
|
|
399
579
|
color?: string | undefined;
|
|
400
580
|
}[] | undefined;
|
|
401
581
|
tables?: {
|
|
402
|
-
id: string;
|
|
403
582
|
title: string;
|
|
583
|
+
id: string;
|
|
404
584
|
datasetId: string;
|
|
405
585
|
fields: string[];
|
|
406
586
|
}[] | undefined;
|
|
@@ -412,6 +592,7 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
412
592
|
controlIds: string[];
|
|
413
593
|
viewIds: string[];
|
|
414
594
|
htmlElementIds: string[];
|
|
595
|
+
componentIds: string[];
|
|
415
596
|
} | undefined;
|
|
416
597
|
htmlPath?: string | undefined;
|
|
417
598
|
}, {
|
|
@@ -419,6 +600,8 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
419
600
|
expectedRevision: number;
|
|
420
601
|
expectedCurrentVersionId: string | null;
|
|
421
602
|
editId: string;
|
|
603
|
+
sourceMetadata?: unknown;
|
|
604
|
+
components?: unknown;
|
|
422
605
|
controls?: unknown;
|
|
423
606
|
charts?: unknown;
|
|
424
607
|
tables?: unknown;
|
|
@@ -430,6 +613,7 @@ export declare function createEditingTools(service: DashboardService, scope: Xpe
|
|
|
430
613
|
controlIds?: string[] | undefined;
|
|
431
614
|
viewIds?: string[] | undefined;
|
|
432
615
|
htmlElementIds?: string[] | undefined;
|
|
616
|
+
componentIds?: string[] | undefined;
|
|
433
617
|
} | undefined;
|
|
434
618
|
htmlPath?: string | undefined;
|
|
435
619
|
}, string>)[];
|
package/dist/lib/editing.js
CHANGED
|
@@ -23,9 +23,9 @@ exports.updateToolSchema = agent_schema_1.createToolSchema.omit({ creationIntent
|
|
|
23
23
|
libraries: document_libraries_1.libraryRequestsSchema.optional().describe('Omit to preserve the saved dependency versions. Supply the complete desired library IDs to explicitly add, remove or upgrade bundled libraries.') }).strict();
|
|
24
24
|
const readHtmlSchema = v3_1.z.object({ editId: v3_1.z.string().uuid(), versionId: v3_1.z.string().uuid().optional().describe('Only for historical inspection; copy readVersionId from dashboard_open.'), offset: v3_1.z.number().int().min(0).max(300000).default(0),
|
|
25
25
|
length: v3_1.z.number().int().min(1).max(24000).default(16000) }).strict();
|
|
26
|
-
exports.EDITING_GUIDANCE = `Opening or reading a dashboard does not modify it. A selection_required result is normal: show its message to the user and wait for an explicit selection; do not retry, infer a target from history, or create a replacement. Do not save an unchanged editing copy or reopen/update merely to confirm a successful save; use the mutation receipt. For existing dashboards, call dashboard_open first and inspect presentation.type. For standard dashboards, update definition fields directly: a rename needs only title, editId, expectedRevision and expectedCurrentVersionId. No HTML file exists; omit htmlPath and libraries. For HTML dashboards only, open prepares a unique editing copy at htmlPath. Read with sandbox_read_file. If a long HTML line is truncated, do not repeat the same read: use dashboard_read_html with editId and follow nextOffset until null to inspect the saved source, then apply exact replacements to htmlPath. Never replace a file with a truncated preview. Edit with sandbox_edit_file/multi_edit_file (sandbox_write_file is create-only), then call dashboard_update with that exact htmlPath and read revisions. If the user requests a rename, include the new title in this same update; editing the HTML heading alone does not rename the Artifact. Save each batch automatically without human confirmation. Files are not dashboard saves. Preserve Binding semantics, stable component IDs and dependency locks unless requested. Update arrays upsert by ID, preserving omitted components; removals must name explicitly requested deletions. HTML updates retain existing element IDs. For new HTML, assign stable IDs to every KPI, chart, detail table and filter. Read and patch the current file instead of rebuilding unrelated sections. On conflict retain the editing file, open the latest draft and reconcile; never silently overwrite. Historical versions are read-only references. All Agent saves are drafts; only the Workbench human publish action creates formal versions. Read the live-dashboard skill for the complete workflow.`;
|
|
26
|
+
exports.EDITING_GUIDANCE = `Opening or reading a dashboard does not modify it. A selection_required result is normal: show its message to the user and wait for an explicit selection; do not retry, infer a target from history, or create a replacement. Do not save an unchanged editing copy or reopen/update merely to confirm a successful save; use the mutation receipt. For existing dashboards, call dashboard_open first and inspect presentation.type. For standard dashboards, update definition fields directly: a rename needs only title, editId, expectedRevision and expectedCurrentVersionId. No HTML file exists; omit htmlPath and libraries. For HTML dashboards only, open prepares a unique editing copy at htmlPath. Read with sandbox_read_file. If a long HTML line is truncated, do not repeat the same read: use dashboard_read_html with editId and follow nextOffset until null to inspect the saved source, then apply exact replacements to htmlPath. Never replace a file with a truncated preview. Edit with sandbox_edit_file/multi_edit_file (sandbox_write_file is create-only), then call dashboard_update with that exact htmlPath and read revisions. If the user requests a rename, include the new title in this same update; editing the HTML heading alone does not rename the Artifact. Save each batch automatically without human confirmation. Files are not dashboard saves. Preserve Binding semantics, stable component IDs and dependency locks unless requested. To add filters to an existing Binding, copy its complete dashboard_open.bindings[] entry, retain binding.id and existing parameters[].controlId, and call dashboard_preview_binding after changing payload/parameters/defaults. Binding ID is independent of output.datasetId; simplified dashboard_preview derives the ID from datasetId and can accidentally add a new Binding instead of updating the old one. Use the stable Binding ID in HTML query/subscribe calls. Submit every intended changed/new Binding previewId and matching controls with htmlPath in the same dashboard_update. Update arrays upsert by ID, preserving omitted components; removals must name explicitly requested deletions. On preflight failure, compare expected/requested Binding IDs, repair the HTML or previews, and retain all intended previewIds, controls, title and htmlPath when retrying. Dropping previewIds does not register new HTML queries. Do not remove an existing Binding merely to suppress validation. HTML updates retain existing element IDs. For new HTML, assign stable IDs to every KPI, chart, detail table and filter. Read and patch the current file instead of rebuilding unrelated sections. On conflict retain the editing file, open the latest draft and reconcile; never silently overwrite. Historical versions are read-only references. All Agent saves are drafts; only the Workbench human publish action creates formal versions. Read the live-dashboard skill for the complete workflow.`;
|
|
27
27
|
/** Run-local read receipts carry planning versions; authorization and CAS remain in the domain service. */
|
|
28
|
-
function createEditingTools(service, scope, context, resolvePreviews, validateFinal, onOpen = () => undefined, currentTarget = editing_session_1.selectionFromConfig) {
|
|
28
|
+
function createEditingTools(service, scope, context, resolvePreviews, validateFinal, onOpen = () => undefined, currentTarget = editing_session_1.selectionFromConfig, saveRequests) {
|
|
29
29
|
const target = (input, config) => {
|
|
30
30
|
const selected = currentTarget(config);
|
|
31
31
|
if (input.artifactId)
|
|
@@ -61,7 +61,7 @@ function createEditingTools(service, scope, context, resolvePreviews, validateFi
|
|
|
61
61
|
: { state: 'published', versionNumber: saved.versionNumber ?? 0, versionId: resolved.versionId }) }, config);
|
|
62
62
|
return JSON.stringify({ resourceCard, editId, expectedCurrentVersionId: saved.baseVersionId ?? saved.versionId ?? null, ...(resolved.versionId ? { readVersionId: resolved.versionId } : {}), expectedRevision: saved.draftRevision ?? 0, state: saved.isDraft ? 'draft' : 'published', artifactId: saved.artifactId, versionId: saved.versionId, versionNumber: saved.versionNumber,
|
|
63
63
|
...definition, presentation: presentation ? { type: 'html', characters: presentation.html.length, dependencies: presentation.dependencies ?? [] } : { type: 'standard' },
|
|
64
|
-
...(resolved.versionId ? { next: 'Read-only published version. To edit, select the working draft in the Workbench version selector or explicitly open this Artifact without a versionId, then use its current draft revision. Publication requires a separate human action.' } : htmlPath ? { htmlPath, saveArguments: { editId, expectedRevision: saved.draftRevision ?? 0, expectedCurrentVersionId: saved.baseVersionId ?? saved.versionId ?? null, title: saved.manifest.title, htmlPath }, editingFile: { path: htmlPath, exists: true, hasUnsavedChanges: false, writeMode: 'edit_existing', read: { tool: 'sandbox_read_file', arguments: { file_path: htmlPath } } }, next: 'Opening only prepared a copy; it did not change the dashboard and requires no save. Call dashboard_update only after applying requested changes. Copy saveArguments, replacing title with the requested new name when renaming. expectedCurrentVersionId must remain actual JSON null or the returned UUID; never a string such as None. When repairing a failed update, retain all intended
|
|
64
|
+
...(resolved.versionId ? { next: 'Read-only published version. To edit, select the working draft in the Workbench version selector or explicitly open this Artifact without a versionId, then use its current draft revision. Publication requires a separate human action.' } : htmlPath ? { htmlPath, saveArguments: { editId, expectedRevision: saved.draftRevision ?? 0, expectedCurrentVersionId: saved.baseVersionId ?? saved.versionId ?? null, title: saved.manifest.title, htmlPath }, editingFile: { path: htmlPath, exists: true, hasUnsavedChanges: false, writeMode: 'edit_existing', read: { tool: 'sandbox_read_file', arguments: { file_path: htmlPath } } }, next: 'Opening only prepared a copy; it did not change the dashboard and requires no save. Call dashboard_update only after applying requested changes. Copy saveArguments, replacing title with the requested new name when renaming. expectedCurrentVersionId must remain actual JSON null or the returned UUID; never a string such as None. When repairing a failed update, retain all intended previewIds, controls, title and htmlPath. For changed bindings, copy bindings[] and preserve binding.id via dashboard_preview_binding; omitted bindings remain saved. The editing file already exists: do not use sandbox_write_file on it. When renaming, include title and htmlPath together in one dashboard_update. A private editing copy is ready. Read it with sandbox_read_file. If long lines are truncated, use dashboard_read_html with editId and follow nextOffset until null instead of retrying file reads. This fallback reads the saved source; apply changes to htmlPath and never write a truncated preview. Edit with sandbox_edit_file/multi_edit_file, then save using dashboard_update with this htmlPath and the returned revisions. File edits alone do not save the dashboard.' } : !presentation ? { next: 'Standard dashboard: update definition fields directly. A rename requires only title plus editId, expectedRevision and expectedCurrentVersionId. No HTML editing file exists; omit htmlPath and libraries unless intentionally converting to HTML.' } : {}) });
|
|
65
65
|
}, { name: 'dashboard_open', description: 'Read one authorized saved dashboard and obtain its stable editId and current draft revision. For a current HTML dashboard also prepares a unique Workspace editing copy without changing the Artifact. Historical versions remain read-only. Omit artifactId only for the selected Workbench dashboard.',
|
|
66
66
|
schema: targetSchema, verboseParsingErrors: true, metadata: { toolName: { en_US: 'Read dashboard for editing', zh_Hans: '读取看板以继续修改' } } }),
|
|
67
67
|
(0, tools_1.tool)(async (input) => {
|
|
@@ -89,6 +89,8 @@ function createEditingTools(service, scope, context, resolvePreviews, validateFi
|
|
|
89
89
|
const changedBindings = previewIds ? resolvePreviews(previewIds) : undefined;
|
|
90
90
|
const bindings = (0, editing_patch_1.upsertComponents)(saved.manifest.bindings, changedBindings, item => item.id, removals?.bindingIds);
|
|
91
91
|
const controls = (0, editing_patch_1.upsertComponents)(saved.manifest.controls, changes.controls, item => item.controlId, removals?.controlIds);
|
|
92
|
+
const sourceMetadata = (0, editing_patch_1.upsertComponents)(saved.manifest.sourceMetadata ?? [], changes.sourceMetadata, item => item.bindingId, removals?.bindingIds.filter(id => saved.manifest.sourceMetadata?.some(item => item.bindingId === id)));
|
|
93
|
+
const components = (0, editing_patch_1.upsertComponents)(saved.manifest.components ?? [], changes.components, item => item.id, removals?.componentIds);
|
|
92
94
|
if (removals?.viewIds.some(id => ![...saved.manifest.charts, ...saved.manifest.tables].some(view => view.id === id)))
|
|
93
95
|
throw new Error('DASHBOARD_REMOVAL_INVALID: copy existing view IDs');
|
|
94
96
|
const charts = (0, editing_patch_1.upsertComponents)(saved.manifest.charts, changes.charts, item => item.id, removals?.viewIds.filter(id => saved.manifest.charts.some(item => item.id === id)));
|
|
@@ -114,8 +116,13 @@ function createEditingTools(service, scope, context, resolvePreviews, validateFi
|
|
|
114
116
|
}
|
|
115
117
|
(0, editing_patch_1.assertHtmlPreserved)(saved.manifest.presentation, presentation, removals?.htmlElementIds);
|
|
116
118
|
const manifest = dashboard_schema_1.dashboardSchema.parse({ ...saved.manifest, ...changes, bindings, controls, charts, tables,
|
|
119
|
+
...(sourceMetadata.length || saved.manifest.sourceMetadata ? { sourceMetadata } : {}), ...(components.length || saved.manifest.components ? { components } : {}),
|
|
117
120
|
...(presentation ? { presentation } : {}) });
|
|
118
121
|
validateFinal(manifest, previewIds !== undefined, changedBindings?.map(item => item.id));
|
|
122
|
+
if (saveRequests && manifest.bindings.length > 8) {
|
|
123
|
+
const key = (0, node_crypto_1.createHash)('sha256').update(JSON.stringify([editId, expectedRevision, expectedCurrentVersionId, manifest, sourceFile])).digest('hex');
|
|
124
|
+
return JSON.stringify(await saveRequests.submit(scope, manifest, expectedCurrentVersionId, expectedRevision, key, sourceFile));
|
|
125
|
+
}
|
|
119
126
|
const { schema, id, ...update } = manifest;
|
|
120
127
|
const result = await service.update(scope, editId, expectedRevision, update, expectedCurrentVersionId);
|
|
121
128
|
const resourceCard = await (0, resource_card_1.emitDashboardCard)(scope, { ...result, state: 'draft', revision: result.draftRevision }, config);
|
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
import { z } from 'zod/v3';
|
|
2
2
|
import type { AnalyticsBinding, AnalyticsValue, XpertResolvedViewHostContext } from '@xpert-ai/contracts';
|
|
3
3
|
import type { DashboardService } from './dashboard.service';
|
|
4
|
+
export declare const filterTestSchema: z.ZodObject<{
|
|
5
|
+
previewId: z.ZodString;
|
|
6
|
+
controls: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>, Record<string, string | number | boolean | null>, unknown>;
|
|
7
|
+
expectations: z.ZodEffects<z.ZodArray<z.ZodObject<{
|
|
8
|
+
fieldId: z.ZodString;
|
|
9
|
+
oneOf: z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, "many">;
|
|
10
|
+
}, "strict", z.ZodTypeAny, {
|
|
11
|
+
fieldId: string;
|
|
12
|
+
oneOf: (string | number | boolean | null)[];
|
|
13
|
+
}, {
|
|
14
|
+
fieldId: string;
|
|
15
|
+
oneOf: (string | number | boolean | null)[];
|
|
16
|
+
}>, "many">, {
|
|
17
|
+
fieldId: string;
|
|
18
|
+
oneOf: (string | number | boolean | null)[];
|
|
19
|
+
}[], unknown>;
|
|
20
|
+
}, "strict", z.ZodTypeAny, {
|
|
21
|
+
controls: Record<string, string | number | boolean | null>;
|
|
22
|
+
previewId: string;
|
|
23
|
+
expectations: {
|
|
24
|
+
fieldId: string;
|
|
25
|
+
oneOf: (string | number | boolean | null)[];
|
|
26
|
+
}[];
|
|
27
|
+
}, {
|
|
28
|
+
previewId: string;
|
|
29
|
+
controls?: unknown;
|
|
30
|
+
expectations?: unknown;
|
|
31
|
+
}>;
|
|
4
32
|
/** Model quality evidence, not authorization: every query still goes through Analytics. */
|
|
5
33
|
export declare function createFilterEvidence(service: DashboardService, scope: XpertResolvedViewHostContext, previews: Map<string, AnalyticsBinding>): {
|
|
6
34
|
requirements(binding: AnalyticsBinding, previewId: string, rows: Record<string, AnalyticsValue>[]): {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filterTestSchema = void 0;
|
|
3
4
|
exports.createFilterEvidence = createFilterEvidence;
|
|
4
5
|
const tools_1 = require("@langchain/core/tools");
|
|
5
6
|
const v3_1 = require("zod/v3");
|
|
6
7
|
const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
|
|
7
8
|
const scalar = v3_1.z.union([v3_1.z.string().max(4000), v3_1.z.number().finite(), v3_1.z.boolean(), v3_1.z.null()]);
|
|
8
|
-
|
|
9
|
+
exports.filterTestSchema = v3_1.z.object({ previewId: v3_1.z.string().min(1),
|
|
9
10
|
controls: (0, plugin_sdk_1.jsonEncodedSchema)(v3_1.z.record(scalar)),
|
|
10
11
|
expectations: (0, plugin_sdk_1.jsonEncodedSchema)(v3_1.z.array(v3_1.z.object({ fieldId: v3_1.z.string().min(1), oneOf: v3_1.z.array(scalar).min(1).max(100) }).strict()).min(1).max(24))
|
|
11
12
|
}).strict();
|
|
@@ -55,6 +56,6 @@ function createFilterEvidence(service, scope, previews) {
|
|
|
55
56
|
checked.set(input.previewId, controls);
|
|
56
57
|
return JSON.stringify({ previewId: input.previewId, passed: true, checkedControls: [...controls], remainingControls: required(binding, input.previewId).map(parameter => parameter.controlId), rows: dataset.rows.slice(0, 20), completeness: dataset.completeness });
|
|
57
58
|
}, { name: 'dashboard_test_filter', description: 'Verify a previewed Binding with concrete filter values and expected field values. For a nullable dimension selector, test a real non-null value and expect every row of the matching field to equal it before saving. Does not change defaults. A failed check must be repaired before create/update.',
|
|
58
|
-
schema, verboseParsingErrors: true, metadata: { toolName: { en_US: 'Verify filter results', zh_Hans: '验证筛选结果' } } })
|
|
59
|
+
schema: exports.filterTestSchema, verboseParsingErrors: true, metadata: { toolName: { en_US: 'Verify filter results', zh_Hans: '验证筛选结果' } } })
|
|
59
60
|
};
|
|
60
61
|
}
|
|
@@ -1 +1,2 @@
|
|
|
1
1
|
export declare const HTML_DASHBOARD_GUIDANCE = "For free-layout HTML dashboards, read the installed live-dashboard skill's references/html-runtime.md through read_skill_file, relative to its SKILL.md path in the skill catalog. Create/edit the HTML with SandboxFile; then dashboard_create_html or dashboard_update validates and saves it. Do not use generic present_files to save or preview a live dashboard. Its preview belongs to the Live dashboards Workbench. Call dashboard_libraries for packaged ECharts/Three.js. Network access is temporarily unrestricted for functional acceptance. CDN scripts/styles/fonts, CSS imports, external images and fetch/XHR are available under browser CORS and mixed-content rules. Tailwind CDN is supported; do not remove styling to avoid network validation. Platform business data remains declarative Binding queries through window.xpertLiveArtifact; never embed credentials. The page MUST declare const live = window.xpertLiveArtifact in its script (live is not a host global), register live.subscribe(bindingId, render), await live.ready(), and invoke live.query(bindingId, typedControls) for initial data and filter changes. window.__datasets and window.__refresh are not platform APIs and are never populated by the host. Read the runtime reference and its html-lifecycle.md example before writing HTML; preserve that lifecycle while freely changing the layout. Use one complete Dataset for KPI, trend and details when they share the same metric and filters; do not create a redundant unfiltered total Binding. Never let filtered and unfiltered subscriptions both write the same KPI: a refresh would race and overwrite the selected-region total. Distinct global totals need distinct, clearly labeled elements. Native data selects require data-dashboard-control=\"<controlId>\"; purely visual selects use data-dashboard-presentation. A data filter must query, not only filter cached browser rows. bindSelect controls ONE binding only. For a shared dimension filter across multiple bindings, follow the skill custom-select example and query every affected binding with the same typed controls; matching control IDs do not broadcast automatically. bindSelect derives options from Dataset fields and is only for dimension filters. Fixed query enums (days, page size, granularity) need options from parameter.allowedValues and a typed change listener calling live.query; never use date rows as numeric day-count options.";
|
|
2
|
+
export declare const HTML_QUERY_ROUNDS = "For a filter shared by multiple Bindings use await live.queryMany(affectedBindingIds, typedControls); render explicit failures from the returned {datasets, failures}. Successful subscriptions are delivered together after that round settles. Individual live.query calls retain independent delivery for legacy pages.";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HTML_DASHBOARD_GUIDANCE = void 0;
|
|
3
|
+
exports.HTML_QUERY_ROUNDS = exports.HTML_DASHBOARD_GUIDANCE = void 0;
|
|
4
4
|
exports.HTML_DASHBOARD_GUIDANCE = `For free-layout HTML dashboards, read the installed live-dashboard skill's references/html-runtime.md through read_skill_file, relative to its SKILL.md path in the skill catalog. Create/edit the HTML with SandboxFile; then dashboard_create_html or dashboard_update validates and saves it. Do not use generic present_files to save or preview a live dashboard. Its preview belongs to the Live dashboards Workbench. Call dashboard_libraries for packaged ECharts/Three.js. Network access is temporarily unrestricted for functional acceptance. CDN scripts/styles/fonts, CSS imports, external images and fetch/XHR are available under browser CORS and mixed-content rules. Tailwind CDN is supported; do not remove styling to avoid network validation. Platform business data remains declarative Binding queries through window.xpertLiveArtifact; never embed credentials. The page MUST declare const live = window.xpertLiveArtifact in its script (live is not a host global), register live.subscribe(bindingId, render), await live.ready(), and invoke live.query(bindingId, typedControls) for initial data and filter changes. window.__datasets and window.__refresh are not platform APIs and are never populated by the host. Read the runtime reference and its html-lifecycle.md example before writing HTML; preserve that lifecycle while freely changing the layout. Use one complete Dataset for KPI, trend and details when they share the same metric and filters; do not create a redundant unfiltered total Binding. Never let filtered and unfiltered subscriptions both write the same KPI: a refresh would race and overwrite the selected-region total. Distinct global totals need distinct, clearly labeled elements. Native data selects require data-dashboard-control="<controlId>"; purely visual selects use data-dashboard-presentation. A data filter must query, not only filter cached browser rows. bindSelect controls ONE binding only. For a shared dimension filter across multiple bindings, follow the skill custom-select example and query every affected binding with the same typed controls; matching control IDs do not broadcast automatically. bindSelect derives options from Dataset fields and is only for dimension filters. Fixed query enums (days, page size, granularity) need options from parameter.allowedValues and a typed change listener calling live.query; never use date rows as numeric day-count options.`;
|
|
5
|
+
exports.HTML_QUERY_ROUNDS = 'For a filter shared by multiple Bindings use await live.queryMany(affectedBindingIds, typedControls); render explicit failures from the returned {datasets, failures}. Successful subscriptions are delivered together after that round settles. Individual live.query calls retain independent delivery for legacy pages.';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BadRequestException } from '@nestjs/common';
|
|
2
|
+
import type { DashboardManifest } from './dashboard.schema';
|
|
3
|
+
/** Report only binding identities observed by validation, never query payloads or returned rows. */
|
|
4
|
+
export declare function htmlPreflightFailure(manifest: DashboardManifest, report: {
|
|
5
|
+
errors: string[];
|
|
6
|
+
requestedBindings: string[];
|
|
7
|
+
}): BadRequestException;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.htmlPreflightFailure = htmlPreflightFailure;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
/** Report only binding identities observed by validation, never query payloads or returned rows. */
|
|
6
|
+
function htmlPreflightFailure(manifest, report) {
|
|
7
|
+
const expectedBindingIds = manifest.bindings.map(binding => binding.id);
|
|
8
|
+
const requestedBindingIds = [...new Set(report.requestedBindings)];
|
|
9
|
+
const expected = new Set(expectedBindingIds), requested = new Set(requestedBindingIds);
|
|
10
|
+
const bindingDiagnostics = {
|
|
11
|
+
expectedBindingIds, requestedBindingIds,
|
|
12
|
+
missingQueryBindingIds: expectedBindingIds.filter(id => !requested.has(id)),
|
|
13
|
+
unexpectedQueryBindingIds: requestedBindingIds.filter(id => !expected.has(id))
|
|
14
|
+
};
|
|
15
|
+
const repair = 'Compare the candidate manifest Binding IDs with the HTML query/subscribe IDs. Requested IDs are observed calls, not a static list of every HTML reference. For an existing Binding, preserve dashboard_open.bindings[].id and preview its complete edited Binding with dashboard_preview_binding. Include all intended current-run previewIds, controls and htmlPath together in dashboard_update; omitted components remain saved. Add new Bindings only for new data needs; remove existing ones only for explicitly requested deletions. Repair other reported page errors before retrying. No dashboard was saved.';
|
|
16
|
+
// Some tool hosts retain only Error.message, so keep the bounded identity diagnostics there too.
|
|
17
|
+
return new common_1.BadRequestException({ code: 'DASHBOARD_HTML_PREFLIGHT_FAILED', errors: report.errors,
|
|
18
|
+
bindingDiagnostics, message: `DASHBOARD_HTML_PREFLIGHT_FAILED: ${JSON.stringify(report.errors)}. Binding diagnostics: ${JSON.stringify(bindingDiagnostics)}. ${repair}` });
|
|
19
|
+
}
|