@xpert-ai/plugin-live-dashboard 0.1.3 → 0.1.4
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 +2 -2
- package/dist/lib/agent.schema.d.ts +11 -11
- package/dist/lib/agent.schema.js +3 -3
- package/dist/lib/analytics-source.d.ts +3 -0
- package/dist/lib/analytics-source.js +11 -0
- package/dist/lib/dashboard-icon.d.ts +2 -1
- package/dist/lib/dashboard-icon.js +10 -2
- package/dist/lib/dashboard-sharing.js +2 -1
- package/dist/lib/dashboard-view.schema.d.ts +1249 -0
- package/dist/lib/dashboard-view.schema.js +19 -0
- package/dist/lib/dashboard.schema.d.ts +12 -12
- package/dist/lib/dashboard.schema.js +1 -1
- package/dist/lib/dashboard.service.d.ts +3 -3
- package/dist/lib/dashboard.service.js +3 -6
- package/dist/lib/definition-tools.d.ts +56 -0
- package/dist/lib/definition-tools.js +42 -0
- package/dist/lib/document-package.d.ts +1 -1
- package/dist/lib/document-package.js +2 -2
- package/dist/lib/middleware.js +12 -8
- package/dist/lib/presentation.provider.d.ts +1 -1
- package/dist/lib/resource-card.js +1 -1
- package/dist/lib/view.provider.d.ts +2 -2
- package/dist/lib/view.provider.js +3 -2
- package/dist/remote/app.js +11 -11
- package/dist/remote/build-manifest.json +17 -14
- package/docs/frontend-libraries.mdx +1 -1
- package/docs/html-mode.md +2 -2
- package/docs/index.mdx +14 -0
- package/docs/verification.mdx +1 -1
- package/examples/data-xpert-sales.json +6 -3
- package/examples/postgres-sales.json +5 -3
- package/package.json +5 -5
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dashboardViewDataSchema = exports.dashboardSavedSchema = exports.dashboardSummarySchema = void 0;
|
|
4
|
+
const v3_1 = require("zod/v3");
|
|
5
|
+
const analytics_1 = require("@xpert-ai/plugin-sdk/analytics");
|
|
6
|
+
const artifact_document_1 = require("@xpert-ai/plugin-sdk/artifact-document");
|
|
7
|
+
const dashboard_schema_1 = require("./dashboard.schema");
|
|
8
|
+
const dashboard_navigation_1 = require("./dashboard-navigation");
|
|
9
|
+
exports.dashboardSummarySchema = v3_1.z.object({ artifactId: v3_1.z.string(), versionId: v3_1.z.string().nullish(), versionNumber: v3_1.z.number().optional(), title: v3_1.z.string().nullish(), updatedAt: v3_1.z.string().optional(), draftRevision: v3_1.z.number().optional(), isDraft: v3_1.z.boolean().optional(), baseVersionId: v3_1.z.string().nullish() });
|
|
10
|
+
exports.dashboardSavedSchema = exports.dashboardSummarySchema.extend({ manifest: dashboard_schema_1.dashboardSchema, dependencies: artifact_document_1.artifactDocumentDependencyAssets.optional() });
|
|
11
|
+
// Source identities belong to Analytics, including immutable Definitions and Artifacts.
|
|
12
|
+
// The viewer consumes only the reference and label; DataSource fields are not universal.
|
|
13
|
+
exports.dashboardViewDataSchema = v3_1.z.object({ meta: v3_1.z.object({
|
|
14
|
+
navigationTarget: dashboard_navigation_1.dashboardNavigationTargetSchema.optional(),
|
|
15
|
+
dashboards: v3_1.z.array(exports.dashboardSummarySchema),
|
|
16
|
+
sources: v3_1.z.array(v3_1.z.object({ source: analytics_1.analyticsSourceRefSchema, name: v3_1.z.string() })),
|
|
17
|
+
saved: exports.dashboardSavedSchema.optional(),
|
|
18
|
+
versions: v3_1.z.array(exports.dashboardSummarySchema).optional()
|
|
19
|
+
}) });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod/v3';
|
|
2
2
|
export declare const dashboardSchema: z.ZodEffects<z.ZodObject<{
|
|
3
|
-
schema: z.ZodLiteral<"xpert.live-dashboard
|
|
3
|
+
schema: z.ZodLiteral<"xpert.live-dashboard">;
|
|
4
4
|
id: z.ZodString;
|
|
5
5
|
title: z.ZodString;
|
|
6
6
|
bindings: z.ZodArray<z.ZodType<import("@xpert-ai/contracts").AnalyticsBinding, z.ZodTypeDef, import("@xpert-ai/contracts").AnalyticsBinding>, "many">;
|
|
@@ -114,7 +114,7 @@ export declare const dashboardSchema: z.ZodEffects<z.ZodObject<{
|
|
|
114
114
|
fields: string[];
|
|
115
115
|
}>, "many">;
|
|
116
116
|
}, "strict", z.ZodTypeAny, {
|
|
117
|
-
schema: "xpert.live-dashboard
|
|
117
|
+
schema: "xpert.live-dashboard";
|
|
118
118
|
id: string;
|
|
119
119
|
title: string;
|
|
120
120
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -146,7 +146,7 @@ export declare const dashboardSchema: z.ZodEffects<z.ZodObject<{
|
|
|
146
146
|
dependencies?: import("@xpert-ai/plugin-sdk/artifact-document").ArtifactDocumentDependencyLock[] | undefined;
|
|
147
147
|
} | undefined;
|
|
148
148
|
}, {
|
|
149
|
-
schema: "xpert.live-dashboard
|
|
149
|
+
schema: "xpert.live-dashboard";
|
|
150
150
|
id: string;
|
|
151
151
|
title: string;
|
|
152
152
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -184,7 +184,7 @@ export declare const dashboardSchema: z.ZodEffects<z.ZodObject<{
|
|
|
184
184
|
}[] | undefined;
|
|
185
185
|
} | undefined;
|
|
186
186
|
}>, {
|
|
187
|
-
schema: "xpert.live-dashboard
|
|
187
|
+
schema: "xpert.live-dashboard";
|
|
188
188
|
id: string;
|
|
189
189
|
title: string;
|
|
190
190
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -216,7 +216,7 @@ export declare const dashboardSchema: z.ZodEffects<z.ZodObject<{
|
|
|
216
216
|
dependencies?: import("@xpert-ai/plugin-sdk/artifact-document").ArtifactDocumentDependencyLock[] | undefined;
|
|
217
217
|
} | undefined;
|
|
218
218
|
}, {
|
|
219
|
-
schema: "xpert.live-dashboard
|
|
219
|
+
schema: "xpert.live-dashboard";
|
|
220
220
|
id: string;
|
|
221
221
|
title: string;
|
|
222
222
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -442,7 +442,7 @@ export type DashboardChanges = z.output<typeof dashboardChangesSchema>;
|
|
|
442
442
|
export declare const controlsSchema: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
|
|
443
443
|
export declare const saveSchema: z.ZodObject<{
|
|
444
444
|
manifest: z.ZodEffects<z.ZodObject<{
|
|
445
|
-
schema: z.ZodLiteral<"xpert.live-dashboard
|
|
445
|
+
schema: z.ZodLiteral<"xpert.live-dashboard">;
|
|
446
446
|
id: z.ZodString;
|
|
447
447
|
title: z.ZodString;
|
|
448
448
|
bindings: z.ZodArray<z.ZodType<import("@xpert-ai/contracts").AnalyticsBinding, z.ZodTypeDef, import("@xpert-ai/contracts").AnalyticsBinding>, "many">;
|
|
@@ -556,7 +556,7 @@ export declare const saveSchema: z.ZodObject<{
|
|
|
556
556
|
fields: string[];
|
|
557
557
|
}>, "many">;
|
|
558
558
|
}, "strict", z.ZodTypeAny, {
|
|
559
|
-
schema: "xpert.live-dashboard
|
|
559
|
+
schema: "xpert.live-dashboard";
|
|
560
560
|
id: string;
|
|
561
561
|
title: string;
|
|
562
562
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -588,7 +588,7 @@ export declare const saveSchema: z.ZodObject<{
|
|
|
588
588
|
dependencies?: import("@xpert-ai/plugin-sdk/artifact-document").ArtifactDocumentDependencyLock[] | undefined;
|
|
589
589
|
} | undefined;
|
|
590
590
|
}, {
|
|
591
|
-
schema: "xpert.live-dashboard
|
|
591
|
+
schema: "xpert.live-dashboard";
|
|
592
592
|
id: string;
|
|
593
593
|
title: string;
|
|
594
594
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -626,7 +626,7 @@ export declare const saveSchema: z.ZodObject<{
|
|
|
626
626
|
}[] | undefined;
|
|
627
627
|
} | undefined;
|
|
628
628
|
}>, {
|
|
629
|
-
schema: "xpert.live-dashboard
|
|
629
|
+
schema: "xpert.live-dashboard";
|
|
630
630
|
id: string;
|
|
631
631
|
title: string;
|
|
632
632
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -658,7 +658,7 @@ export declare const saveSchema: z.ZodObject<{
|
|
|
658
658
|
dependencies?: import("@xpert-ai/plugin-sdk/artifact-document").ArtifactDocumentDependencyLock[] | undefined;
|
|
659
659
|
} | undefined;
|
|
660
660
|
}, {
|
|
661
|
-
schema: "xpert.live-dashboard
|
|
661
|
+
schema: "xpert.live-dashboard";
|
|
662
662
|
id: string;
|
|
663
663
|
title: string;
|
|
664
664
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -700,7 +700,7 @@ export declare const saveSchema: z.ZodObject<{
|
|
|
700
700
|
expectedRevision: z.ZodDefault<z.ZodNumber>;
|
|
701
701
|
}, "strict", z.ZodTypeAny, {
|
|
702
702
|
manifest: {
|
|
703
|
-
schema: "xpert.live-dashboard
|
|
703
|
+
schema: "xpert.live-dashboard";
|
|
704
704
|
id: string;
|
|
705
705
|
title: string;
|
|
706
706
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -736,7 +736,7 @@ export declare const saveSchema: z.ZodObject<{
|
|
|
736
736
|
expectedRevision: number;
|
|
737
737
|
}, {
|
|
738
738
|
manifest: {
|
|
739
|
-
schema: "xpert.live-dashboard
|
|
739
|
+
schema: "xpert.live-dashboard";
|
|
740
740
|
id: string;
|
|
741
741
|
title: string;
|
|
742
742
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -6,7 +6,7 @@ const analytics_1 = require("@xpert-ai/plugin-sdk/analytics");
|
|
|
6
6
|
const artifact_document_1 = require("@xpert-ai/plugin-sdk/artifact-document");
|
|
7
7
|
const id = v3_1.z.string().regex(/^[A-Za-z][A-Za-z0-9_.-]{0,79}$/);
|
|
8
8
|
exports.dashboardSchema = v3_1.z.object({
|
|
9
|
-
schema: v3_1.z.literal('xpert.live-dashboard
|
|
9
|
+
schema: v3_1.z.literal('xpert.live-dashboard'), id: v3_1.z.string().uuid(), title: v3_1.z.string().min(1).max(160),
|
|
10
10
|
bindings: v3_1.z.array(analytics_1.analyticsBindingSchema).min(1).max(8),
|
|
11
11
|
presentation: v3_1.z.object({ type: v3_1.z.literal('html'), html: artifact_document_1.artifactDocumentHtml, dependencies: artifact_document_1.artifactDocumentDependencyLocks.optional() }).strict().optional(),
|
|
12
12
|
controls: v3_1.z.array(v3_1.z.object({ controlId: id, type: v3_1.z.enum(['string', 'number', 'boolean', 'date']),
|
|
@@ -27,7 +27,7 @@ export declare class DashboardService {
|
|
|
27
27
|
}>;
|
|
28
28
|
open(context: XpertResolvedViewHostContext, artifactId: string, versionId?: string, draftRevision?: number): Promise<{
|
|
29
29
|
manifest: {
|
|
30
|
-
schema: "xpert.live-dashboard
|
|
30
|
+
schema: "xpert.live-dashboard";
|
|
31
31
|
id: string;
|
|
32
32
|
title: string;
|
|
33
33
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -72,7 +72,7 @@ export declare class DashboardService {
|
|
|
72
72
|
/** Trusted View transport only. Agent read tools receive locks, never megabytes of library code. */
|
|
73
73
|
openDocument(context: XpertResolvedViewHostContext, artifactId: string, versionId?: string, draftRevision?: number): Promise<{
|
|
74
74
|
manifest: {
|
|
75
|
-
schema: "xpert.live-dashboard
|
|
75
|
+
schema: "xpert.live-dashboard";
|
|
76
76
|
id: string;
|
|
77
77
|
title: string;
|
|
78
78
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -195,7 +195,7 @@ export declare class DashboardService {
|
|
|
195
195
|
} | undefined;
|
|
196
196
|
datasets: import("@xpert-ai/contracts").AnalyticalDataset[];
|
|
197
197
|
manifest: {
|
|
198
|
-
schema: "xpert.live-dashboard
|
|
198
|
+
schema: "xpert.live-dashboard";
|
|
199
199
|
id: string;
|
|
200
200
|
title: string;
|
|
201
201
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -159,12 +159,9 @@ let DashboardService = class DashboardService {
|
|
|
159
159
|
const samples = [...(alternative !== undefined ? [alternative] : []),
|
|
160
160
|
...(current !== null && parameter.allowedValues?.includes(null) ? [null] : [])];
|
|
161
161
|
for (const value of samples) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
throw new common_1.BadRequestException(`DASHBOARD_FILTER_PREVIEW_FAILED: ${parameter.controlId}; a declared non-default filter failed. Inspect the native parameter type and operator before retrying.`);
|
|
167
|
-
}
|
|
162
|
+
// Analytics already redacts provider failures. Preserve its actionable validation
|
|
163
|
+
// errors: a duplicate grain is not a malformed filter and needs a different repair.
|
|
164
|
+
await this.runtime.require(plugin_sdk_1.AnalyticsRuntimeCapability).query(actor(context), { binding, controls: { ...controls, [parameter.controlId]: value } });
|
|
168
165
|
}
|
|
169
166
|
}
|
|
170
167
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from 'zod/v3';
|
|
2
|
+
import { type IAgentMiddlewareContext } from '@xpert-ai/plugin-sdk';
|
|
3
|
+
export declare const DEFINITION_GUIDANCE = "If dashboard_list_sources lacks the requested source, call analytics_definition_connections, then analytics_definition_inspect with an exact returned selection and inputJson=\"{}\". Follow its instructions, inspect real source data and generate the business definition yourself. Never ask users to fill internal IDs/configuration. Register using analytics_definition_register and a stable requestId, refresh dashboard_list_sources, discover the returned source and preview before saving. Settings \u2192 Analytics is for viewing, correction and version management. Do not create redundant definitions for already governed sources.";
|
|
4
|
+
export declare function createDefinitionTools(context: IAgentMiddlewareContext, registered: () => void): (import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>, {}, {}, string> | import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
5
|
+
providerId: z.ZodString;
|
|
6
|
+
connectionKey: z.ZodString;
|
|
7
|
+
} & {
|
|
8
|
+
inputJson: z.ZodString;
|
|
9
|
+
}, "strict", z.ZodTypeAny, {
|
|
10
|
+
providerId: string;
|
|
11
|
+
connectionKey: string;
|
|
12
|
+
inputJson: string;
|
|
13
|
+
}, {
|
|
14
|
+
providerId: string;
|
|
15
|
+
connectionKey: string;
|
|
16
|
+
inputJson: string;
|
|
17
|
+
}>, {
|
|
18
|
+
providerId: string;
|
|
19
|
+
connectionKey: string;
|
|
20
|
+
inputJson: string;
|
|
21
|
+
}, {
|
|
22
|
+
providerId: string;
|
|
23
|
+
connectionKey: string;
|
|
24
|
+
inputJson: string;
|
|
25
|
+
}, string> | import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
26
|
+
providerId: z.ZodString;
|
|
27
|
+
connectionKey: z.ZodString;
|
|
28
|
+
} & {
|
|
29
|
+
requestId: z.ZodString;
|
|
30
|
+
name: z.ZodString;
|
|
31
|
+
definitionJson: z.ZodString;
|
|
32
|
+
}, "strict", z.ZodTypeAny, {
|
|
33
|
+
name: string;
|
|
34
|
+
providerId: string;
|
|
35
|
+
connectionKey: string;
|
|
36
|
+
requestId: string;
|
|
37
|
+
definitionJson: string;
|
|
38
|
+
}, {
|
|
39
|
+
name: string;
|
|
40
|
+
providerId: string;
|
|
41
|
+
connectionKey: string;
|
|
42
|
+
requestId: string;
|
|
43
|
+
definitionJson: string;
|
|
44
|
+
}>, {
|
|
45
|
+
name: string;
|
|
46
|
+
providerId: string;
|
|
47
|
+
connectionKey: string;
|
|
48
|
+
requestId: string;
|
|
49
|
+
definitionJson: string;
|
|
50
|
+
}, {
|
|
51
|
+
name: string;
|
|
52
|
+
providerId: string;
|
|
53
|
+
connectionKey: string;
|
|
54
|
+
requestId: string;
|
|
55
|
+
definitionJson: string;
|
|
56
|
+
}, string>)[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFINITION_GUIDANCE = void 0;
|
|
4
|
+
exports.createDefinitionTools = createDefinitionTools;
|
|
5
|
+
const tools_1 = require("@langchain/core/tools");
|
|
6
|
+
const v3_1 = require("zod/v3");
|
|
7
|
+
const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
|
|
8
|
+
const selection = v3_1.z.object({ providerId: v3_1.z.string().min(1).max(160), connectionKey: v3_1.z.string().min(1).max(400) }).strict();
|
|
9
|
+
exports.DEFINITION_GUIDANCE = 'If dashboard_list_sources lacks the requested source, call analytics_definition_connections, then analytics_definition_inspect with an exact returned selection and inputJson="{}". Follow its instructions, inspect real source data and generate the business definition yourself. Never ask users to fill internal IDs/configuration. Register using analytics_definition_register and a stable requestId, refresh dashboard_list_sources, discover the returned source and preview before saving. Settings → Analytics is for viewing, correction and version management. Do not create redundant definitions for already governed sources.';
|
|
10
|
+
function createDefinitionTools(context, registered) {
|
|
11
|
+
const api = () => {
|
|
12
|
+
if (!context.workspaceId || !context.xpertId || !context.organizationId || !context.runtime?.capabilities)
|
|
13
|
+
throw new Error('ANALYTICS_ASSISTANT_SCOPE_REQUIRED');
|
|
14
|
+
return { runtime: context.runtime.capabilities.require(plugin_sdk_1.AnalyticsDefinitionAuthoringCapability), scope: {
|
|
15
|
+
actor: { tenantId: context.tenantId, organizationId: context.organizationId, userId: context.userId },
|
|
16
|
+
workspaceId: context.workspaceId, xpertId: context.xpertId,
|
|
17
|
+
files: context.runtime.capabilities.require(plugin_sdk_1.WorkspaceFilesRuntimeCapability)
|
|
18
|
+
} };
|
|
19
|
+
};
|
|
20
|
+
return [
|
|
21
|
+
(0, tools_1.tool)(async () => { const { runtime, scope } = api(); return JSON.stringify(await runtime.catalog(scope)); }, {
|
|
22
|
+
name: 'analytics_definition_connections', description: 'List authorized connections for generating a missing analytics source. Returns exact providerId/connectionKey selections; no credentials.',
|
|
23
|
+
schema: v3_1.z.object({}).strict(), metadata: { toolName: { en_US: 'Find analytics inputs', zh_Hans: '发现分析输入' } }
|
|
24
|
+
}),
|
|
25
|
+
(0, tools_1.tool)(async ({ inputJson, ...selection }) => {
|
|
26
|
+
const { runtime, scope } = api();
|
|
27
|
+
return JSON.stringify(await runtime.inspect(scope, selection, plugin_sdk_1.analyticsOptionsSchema.parse(JSON.parse(inputJson))));
|
|
28
|
+
}, { name: 'analytics_definition_inspect', description: 'Inspect approved input metadata and provider authoring schemas. Start inputJson="{}". Follow inspectSchema for operation samples/file inspection. Input cannot override host scope.',
|
|
29
|
+
schema: selection.extend({ inputJson: v3_1.z.string().min(2).max(100000) }).strict(), verboseParsingErrors: true,
|
|
30
|
+
metadata: { toolName: { en_US: 'Inspect analytics input', zh_Hans: '检查分析输入' } }
|
|
31
|
+
}),
|
|
32
|
+
(0, tools_1.tool)(async ({ definitionJson, ...input }) => {
|
|
33
|
+
const { runtime, scope } = api();
|
|
34
|
+
const receipt = await runtime.register(scope, { ...input, definition: plugin_sdk_1.analyticsOptionsSchema.parse(JSON.parse(definitionJson)) });
|
|
35
|
+
registered();
|
|
36
|
+
return JSON.stringify(receipt);
|
|
37
|
+
}, { name: 'analytics_definition_register', description: 'Register an Agent-generated definition matching definitionSchema. System supplies identities and validates real input. Keep requestId stable on retries; changed intent needs another key. Returns an immutable source and discoveryRequest. Refresh sources, discover and preview it before saving a dashboard.',
|
|
38
|
+
schema: selection.extend({ requestId: v3_1.z.string().min(1).max(128), name: v3_1.z.string().min(1).max(200), definitionJson: v3_1.z.string().min(2).max(100000) }).strict(), verboseParsingErrors: true,
|
|
39
|
+
metadata: { toolName: { en_US: 'Register analytics definition', zh_Hans: '生成分析定义' } }
|
|
40
|
+
})
|
|
41
|
+
];
|
|
42
|
+
}
|
|
@@ -5,7 +5,7 @@ export declare const MAX_DASHBOARD_PACKAGE_BYTES = 9000000;
|
|
|
5
5
|
export declare function encodeDashboardPackage(manifest: DashboardManifest, dependencies: ArtifactDocumentDependencyAsset[]): Buffer<ArrayBuffer>;
|
|
6
6
|
export declare function decodeDashboardPackage(bytes: Buffer): {
|
|
7
7
|
manifest: {
|
|
8
|
-
schema: "xpert.live-dashboard
|
|
8
|
+
schema: "xpert.live-dashboard";
|
|
9
9
|
id: string;
|
|
10
10
|
title: string;
|
|
11
11
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -8,13 +8,13 @@ const artifact_document_1 = require("@xpert-ai/plugin-sdk/artifact-document");
|
|
|
8
8
|
const dashboard_schema_1 = require("./dashboard.schema");
|
|
9
9
|
exports.MAX_DASHBOARD_PACKAGE_BYTES = 9_000_000;
|
|
10
10
|
const storedSchema = v3_1.z.union([
|
|
11
|
-
v3_1.z.object({ schema: v3_1.z.literal('xpert.live-dashboard.package
|
|
11
|
+
v3_1.z.object({ schema: v3_1.z.literal('xpert.live-dashboard.package'), manifest: dashboard_schema_1.dashboardSchema, dependencies: artifact_document_1.artifactDocumentDependencyAssets }).strict(),
|
|
12
12
|
dashboard_schema_1.dashboardSchema.transform(manifest => ({ manifest, dependencies: [] }))
|
|
13
13
|
]);
|
|
14
14
|
/** Definition and exact library bytes share one immutable Artifact Version and content checksum. */
|
|
15
15
|
function encodeDashboardPackage(manifest, dependencies) {
|
|
16
16
|
(0, artifact_document_1.verifyArtifactDocumentDependencies)(dependencies, manifest.presentation?.dependencies ?? []);
|
|
17
|
-
return Buffer.from(JSON.stringify(dependencies.length ? { schema: 'xpert.live-dashboard.package
|
|
17
|
+
return Buffer.from(JSON.stringify(dependencies.length ? { schema: 'xpert.live-dashboard.package', manifest, dependencies } : manifest));
|
|
18
18
|
}
|
|
19
19
|
function decodeDashboardPackage(bytes) {
|
|
20
20
|
if (bytes.byteLength > exports.MAX_DASHBOARD_PACKAGE_BYTES)
|
package/dist/lib/middleware.js
CHANGED
|
@@ -10,6 +10,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.DashboardMiddleware = exports.DASHBOARD_GUIDANCE = void 0;
|
|
13
|
+
const definition_tools_1 = require("./definition-tools");
|
|
14
|
+
const analytics_source_1 = require("./analytics-source");
|
|
15
|
+
const analytics_1 = require("@xpert-ai/plugin-sdk/analytics");
|
|
13
16
|
const messages_1 = require("@langchain/core/messages");
|
|
14
17
|
const tools_1 = require("@langchain/core/tools");
|
|
15
18
|
const node_crypto_1 = require("node:crypto");
|
|
@@ -57,7 +60,7 @@ let DashboardMiddleware = class DashboardMiddleware {
|
|
|
57
60
|
const filterEvidence = (0, filter_evidence_1.createFilterEvidence)(this.service, scope, previews);
|
|
58
61
|
const created = new Map();
|
|
59
62
|
const preview = async (binding) => {
|
|
60
|
-
const contract = discovered.get(`${binding.
|
|
63
|
+
const contract = discovered.get(`${(0, analytics_1.analyticsSourceKey)(binding.source)}/${binding.providerId}`);
|
|
61
64
|
if (!contract)
|
|
62
65
|
throw new Error('DASHBOARD_DISCOVER_REQUIRED');
|
|
63
66
|
(0, plugin_sdk_1.validateAnalyticsPayload)(binding.payload, contract.payloadSchema);
|
|
@@ -96,7 +99,7 @@ let DashboardMiddleware = class DashboardMiddleware {
|
|
|
96
99
|
const save = async (input, config, html, dependencies = []) => {
|
|
97
100
|
const { previewIds, supersedesPaths, ...definition } = input;
|
|
98
101
|
const bindings = resolvePreviews(previewIds);
|
|
99
|
-
const manifest = dashboard_schema_1.dashboardSchema.parse({ ...definition, bindings, schema: 'xpert.live-dashboard
|
|
102
|
+
const manifest = dashboard_schema_1.dashboardSchema.parse({ ...definition, bindings, schema: 'xpert.live-dashboard', id: (0, node_crypto_1.randomUUID)(),
|
|
100
103
|
...(html ? { presentation: { type: 'html', html, ...(dependencies.length ? { dependencies } : {}) } } : {}) });
|
|
101
104
|
validateFinal(manifest, true);
|
|
102
105
|
const key = hash({ input: { ...definition, previewIds }, html, dependencies });
|
|
@@ -141,13 +144,14 @@ let DashboardMiddleware = class DashboardMiddleware {
|
|
|
141
144
|
throw new Error('DASHBOARD_SAVE_NOT_CONFIRMED: no successful draft save receipt; Workspace changes have not been saved to the dashboard.');
|
|
142
145
|
const result = await handler({ ...request, ...(evidence.pending ? { toolChoice: 'required' } : {}), ...(exhausted ? { tools: [] } : {}), systemMessage: new messages_1.SystemMessage({ content: [
|
|
143
146
|
...(typeof request.systemMessage?.content === 'string' ? [{ type: 'text', text: request.systemMessage.content }] : request.systemMessage?.content ?? []),
|
|
144
|
-
{ type: 'text', text: exports.DASHBOARD_GUIDANCE + '\n' + html_guidance_1.HTML_DASHBOARD_GUIDANCE + '\n' + editing_1.EDITING_GUIDANCE + (evidence.pending ? `\nDashboard changes are pending without a matching draft save receipt. Unsaved files: ${JSON.stringify(evidence.pendingPaths)}. Continue reading/repairing and call dashboard_create_html or dashboard_update with the exact file path; do not finish or claim it was saved. When abandoning earlier unsaved HTML creation candidates, explicitly pass their exact paths as supersedesPaths to dashboard_create or dashboard_create_html, matching the requested presentation mode. If a standard dashboard is already saved, repeat dashboard_create with the same definition/previewIds and supersedesPaths; do not create an unwanted HTML dashboard. This only abandons those candidates after a successful save; it never discards another Artifact editing copy.` : '') + (options.allowedFinalProviders ? `\nThis Assistant requires every saved dashboard binding to use one of these providers: ${options.allowedFinalProviders.join(', ')}. Other providers may be previewed only as upstream inputs. Do not save a direct-source substitute.` : '') + (exhausted ? '\nThe dashboard tool budget is exhausted. Stop calls; report only saved receipts or explain the concrete blocker truthfully.' : '') }
|
|
147
|
+
{ type: 'text', text: exports.DASHBOARD_GUIDANCE + '\n' + definition_tools_1.DEFINITION_GUIDANCE + '\n' + html_guidance_1.HTML_DASHBOARD_GUIDANCE + '\n' + editing_1.EDITING_GUIDANCE + (evidence.pending ? `\nDashboard changes are pending without a matching draft save receipt. Unsaved files: ${JSON.stringify(evidence.pendingPaths)}. Continue reading/repairing and call dashboard_create_html or dashboard_update with the exact file path; do not finish or claim it was saved. When abandoning earlier unsaved HTML creation candidates, explicitly pass their exact paths as supersedesPaths to dashboard_create or dashboard_create_html, matching the requested presentation mode. If a standard dashboard is already saved, repeat dashboard_create with the same definition/previewIds and supersedesPaths; do not create an unwanted HTML dashboard. This only abandons those candidates after a successful save; it never discards another Artifact editing copy.` : '') + (options.allowedFinalProviders ? `\nThis Assistant requires every saved dashboard binding to use one of these providers: ${options.allowedFinalProviders.join(', ')}. Other providers may be previewed only as upstream inputs. Do not save a direct-source substitute.` : '') + (exhausted ? '\nThe dashboard tool budget is exhausted. Stop calls; report only saved receipts or explain the concrete blocker truthfully.' : '') }
|
|
145
148
|
] }) });
|
|
146
149
|
if (evidence.pending && result && !result.tool_calls?.length)
|
|
147
150
|
throw new Error('DASHBOARD_SAVE_NOT_CONFIRMED: the model stopped without a successful draft save receipt.');
|
|
148
151
|
return result;
|
|
149
152
|
}, tools: [
|
|
150
153
|
filterEvidence.tool,
|
|
154
|
+
...(0, definition_tools_1.createDefinitionTools)(context, () => { listedSources = undefined; }),
|
|
151
155
|
(0, tools_1.tool)(async () => JSON.stringify({ libraries: await (0, document_libraries_1.libraryLocks)(['echarts', 'three']),
|
|
152
156
|
pageRuntime: {
|
|
153
157
|
global: 'window.xpertLiveArtifact',
|
|
@@ -169,16 +173,16 @@ let DashboardMiddleware = class DashboardMiddleware {
|
|
|
169
173
|
schema: v3_1.z.object({}).strict(), verboseParsingErrors: true, metadata: { toolName: { en_US: 'List analytics sources', zh_Hans: '发现分析数据源' } }
|
|
170
174
|
}),
|
|
171
175
|
(0, tools_1.tool)(async (input) => {
|
|
172
|
-
if (listedSources && !listedSources.some(source => source.
|
|
173
|
-
throw new Error(`DASHBOARD_SOURCE_SELECTION_INVALID: copy an exact
|
|
174
|
-
const parsed = {
|
|
176
|
+
if (listedSources && !listedSources.some(source => (0, analytics_source_1.sameAnalyticsResource)(source.source, input.source) && source.providers.some(provider => provider.id === input.providerId)))
|
|
177
|
+
throw new Error(`DASHBOARD_SOURCE_SELECTION_INVALID: copy an exact source/providerId pair from dashboard_list_sources; do not invent or combine IDs. Known pairs: ${JSON.stringify(listedSources.map(source => ({ source: source.source, name: source.name, providerIds: source.providers.map(provider => provider.id) })))}. Refresh the list if the source changed. Initial requestJson is "{}"; then follow inspectRequest/nextRequest.`);
|
|
178
|
+
const parsed = { source: input.source, providerId: input.providerId, request: (0, agent_schema_1.parseObjectJson)(input.requestJson) };
|
|
175
179
|
const result = await this.service.discover(scope, parsed);
|
|
176
|
-
discovered.set(`${parsed.
|
|
180
|
+
discovered.set(`${(0, analytics_1.analyticsSourceKey)(parsed.source)}/${parsed.providerId}`, result.queryContract);
|
|
177
181
|
return JSON.stringify(result);
|
|
178
182
|
}, { name: 'dashboard_discover', description: 'Discover provider-owned business metadata. Start requestJson="{}" then serialize inspectRequest/nextRequest. Inspect dataset fields, comments, measures and native query format before preview.',
|
|
179
183
|
schema: agent_schema_1.discoverToolSchema, verboseParsingErrors: true, metadata: { toolName: { en_US: 'Inspect business data', zh_Hans: '理解业务数据与指标' } } }),
|
|
180
184
|
(0, tools_1.tool)(async (input) => {
|
|
181
|
-
const contract = discovered.get(`${input.binding.
|
|
185
|
+
const contract = discovered.get(`${(0, analytics_1.analyticsSourceKey)(input.binding.source)}/${input.binding.providerId}`);
|
|
182
186
|
if (!contract)
|
|
183
187
|
throw new Error('DASHBOARD_DISCOVER_REQUIRED: discover the source before preview');
|
|
184
188
|
const binding = (0, agent_schema_1.fromAgentBinding)(input.binding, contract);
|
|
@@ -17,7 +17,7 @@ export declare class DashboardPresentationProvider implements IArtifactPresentat
|
|
|
17
17
|
title: string;
|
|
18
18
|
isDraft: boolean;
|
|
19
19
|
manifest: {
|
|
20
|
-
schema: "xpert.live-dashboard
|
|
20
|
+
schema: "xpert.live-dashboard";
|
|
21
21
|
id: string;
|
|
22
22
|
title: string;
|
|
23
23
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -13,7 +13,7 @@ function dashboardResourceCard(scope, saved) {
|
|
|
13
13
|
resource: { namespace: 'live_dashboard', type: 'live-dashboard', id: saved.artifactId, artifactId: saved.artifactId },
|
|
14
14
|
title: saved.title,
|
|
15
15
|
description: saved.state === 'draft' ? `Dashboard · Draft r${saved.revision}` : `Dashboard · v${saved.versionNumber}`,
|
|
16
|
-
icon: dashboard_icon_1.dashboardIcon,
|
|
16
|
+
icon: { type: dashboard_icon_1.dashboardIcon.type, value: dashboard_icon_1.dashboardIcon.value },
|
|
17
17
|
open: {
|
|
18
18
|
...(0, dashboard_navigation_1.dashboardNavigationTarget)(scope), selectionId: saved.artifactId,
|
|
19
19
|
...(saved.state === 'published' && saved.versionId ? { parameters: { versionId: saved.versionId } } : {})
|
|
@@ -19,7 +19,7 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
|
|
|
19
19
|
meta: {
|
|
20
20
|
saved?: {
|
|
21
21
|
manifest: {
|
|
22
|
-
schema: "xpert.live-dashboard
|
|
22
|
+
schema: "xpert.live-dashboard";
|
|
23
23
|
id: string;
|
|
24
24
|
title: string;
|
|
25
25
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -192,7 +192,7 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
|
|
|
192
192
|
} | undefined;
|
|
193
193
|
datasets: import("@xpert-ai/contracts").AnalyticalDataset[];
|
|
194
194
|
manifest: {
|
|
195
|
-
schema: "xpert.live-dashboard
|
|
195
|
+
schema: "xpert.live-dashboard";
|
|
196
196
|
id: string;
|
|
197
197
|
title: string;
|
|
198
198
|
bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
|
|
@@ -20,6 +20,7 @@ const sharing_service_1 = require("./sharing.service");
|
|
|
20
20
|
const dashboard_schema_1 = require("./dashboard.schema");
|
|
21
21
|
const dashboard_receipt_1 = require("./dashboard-receipt");
|
|
22
22
|
const dashboard_navigation_1 = require("./dashboard-navigation");
|
|
23
|
+
const dashboard_icon_1 = require("./dashboard-icon");
|
|
23
24
|
exports.VIEW_KEY = 'live-dashboard';
|
|
24
25
|
exports.VIEW_PROVIDER = 'live-dashboard';
|
|
25
26
|
exports.FEATURE = 'live_dashboard';
|
|
@@ -34,9 +35,9 @@ let DashboardViewProvider = class DashboardViewProvider {
|
|
|
34
35
|
if (!(context.hostType === 'agent' && slot === 'agent.workbench' || context.hostType === 'project' && slot === 'detail.sections'))
|
|
35
36
|
return [];
|
|
36
37
|
return [{ key: exports.VIEW_KEY, title: text('Live dashboards', '实时看板'), hostType: context.hostType, slot, order: 35,
|
|
37
|
-
icon:
|
|
38
|
+
icon: dashboard_icon_1.dashboardIcon, refreshable: true, activation: { requiredFeatures: [exports.FEATURE] },
|
|
38
39
|
source: { provider: exports.VIEW_PROVIDER, plugin: dashboard_service_1.PLUGIN_NAME },
|
|
39
|
-
workbench: { fixed: true, menu: { enabled: true, label: text('Live dashboards', '实时看板'), order: 35 } },
|
|
40
|
+
workbench: { fixed: true, menu: { enabled: true, label: text('Live dashboards', '实时看板'), icon: dashboard_icon_1.dashboardIcon, order: 35 } },
|
|
40
41
|
view: { type: 'remote_component', runtime: 'react', protocolVersion: 1, component: { isolation: 'iframe', entry: exports.VIEW_KEY }, dataSource: { mode: 'platform' } },
|
|
41
42
|
dataSource: { mode: 'platform', querySchema: { supportsSelection: true, supportsParameters: true }, cache: { enabled: false } },
|
|
42
43
|
clientCommands: [{ key: contracts_1.ASSISTANT_CONTEXT_SET_COMMAND, label: text('Select dashboard for Assistant', '设置助理当前看板') },
|