@xpert-ai/plugin-live-dashboard 0.3.1 → 0.4.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 +10 -2
- package/README.md +6 -0
- package/assets/branding/cover-v1.prompt.txt +27 -0
- package/assets/branding/cover-v1.webp +0 -0
- package/assets/previews/customer-brief.png +0 -0
- package/assets/previews/profit-atlas.png +0 -0
- package/assets/previews/trend-workspace.png +0 -0
- package/dist/index.js +6 -3
- package/dist/lib/agent.schema.d.ts +43 -37
- package/dist/lib/agent.schema.js +2 -1
- package/dist/lib/app-config.d.ts +62 -0
- package/dist/lib/app-config.js +38 -0
- package/dist/lib/artifact-type.provider.d.ts +15 -0
- package/dist/lib/artifact-type.provider.js +78 -0
- package/dist/lib/assistant-template.d.ts +1 -2
- package/dist/lib/assistant-template.js +3 -52
- package/dist/lib/content.provider.js +13 -5
- package/dist/lib/dashboard-navigation.d.ts +58 -14
- package/dist/lib/dashboard-navigation.js +11 -10
- package/dist/lib/dashboard-view.schema.d.ts +197 -46
- package/dist/lib/dashboard-view.schema.js +8 -1
- package/dist/lib/dashboard.service.d.ts +39 -2
- package/dist/lib/dashboard.service.js +52 -28
- package/dist/lib/document-libraries.d.ts +1 -1
- package/dist/lib/document-libraries.js +3 -2
- package/dist/lib/document-network.d.ts +1 -1
- package/dist/lib/document-network.js +2 -6
- package/dist/lib/editing-feedback.d.ts +5 -0
- package/dist/lib/editing-feedback.js +19 -0
- package/dist/lib/editing-patch.d.ts +22 -0
- package/dist/lib/editing-patch.js +46 -0
- package/dist/lib/editing-session.d.ts +167 -0
- package/dist/lib/editing-session.js +53 -0
- package/dist/lib/editing.d.ts +92 -60
- package/dist/lib/editing.js +36 -24
- package/dist/lib/html-guidance.d.ts +1 -1
- package/dist/lib/html-guidance.js +1 -1
- package/dist/lib/middleware.js +42 -18
- package/dist/lib/monitor.d.ts +70 -0
- package/dist/lib/monitor.js +101 -0
- package/dist/lib/plugin.js +4 -1
- package/dist/lib/project.d.ts +106 -0
- package/dist/lib/project.js +17 -0
- package/dist/lib/projects.schema.d.ts +49 -0
- package/dist/lib/projects.schema.js +7 -0
- package/dist/lib/projects.service.d.ts +23 -0
- package/dist/lib/projects.service.js +65 -0
- package/dist/lib/resource-card.js +1 -1
- package/dist/lib/runtime-context.d.ts +3 -0
- package/dist/lib/runtime-context.js +13 -0
- package/dist/lib/save-evidence.d.ts +1 -1
- package/dist/lib/templates.d.ts +2 -0
- package/dist/lib/templates.js +55 -0
- package/dist/lib/view.provider.d.ts +97 -7
- package/dist/lib/view.provider.js +39 -10
- package/dist/libraries/TREND-WORKSPACE-ICONS-LICENSE.txt +43 -0
- package/dist/libraries/catalog.json +1 -1
- package/dist/remote/app.css +1 -1
- package/dist/remote/app.js +33 -33
- package/dist/remote/build-manifest.json +115 -32
- package/dist/sandbox-actions/action.json +1 -1
- package/dist/sandbox-actions/bundle/host.js +2 -2
- package/dist/sandbox-actions/bundle/resource-cache.mjs +2 -1
- package/dist/sandbox-actions/bundle/validate.mjs +1 -1
- package/docs/docs.json +7 -0
- package/docs/frontend-libraries.mdx +12 -4
- package/docs/html-mode.md +3 -3
- package/docs/quick-start-acceptance.mdx +50 -0
- package/docs/quick-start.mdx +64 -0
- package/docs/superstore.mdx +38 -0
- package/docs/team-sharing.mdx +6 -2
- package/docs/trend-workspace-acceptance.mdx +43 -0
- package/docs/trend-workspace.mdx +30 -0
- package/docs/verification.mdx +4 -2
- package/docs/visual-styles-acceptance.mdx +40 -0
- package/docs/visual-styles.mdx +46 -0
- package/package.json +23 -17
- package/skills/live-dashboard/SKILL.md +27 -3
- package/skills/live-dashboard/examples/README.md +25 -0
- package/skills/live-dashboard/examples/catalog.json +79 -0
- package/skills/live-dashboard/examples/production-quality/README.md +25 -0
- package/skills/live-dashboard/examples/production-quality/dashboard.html +129 -0
- package/skills/live-dashboard/examples/production-quality/definition.json +67 -0
- package/skills/live-dashboard/examples/production-quality/demo.csv +7 -0
- package/skills/live-dashboard/examples/production-quality/demo.json +44 -0
- package/skills/live-dashboard/examples/production-quality/expected.json +26 -0
- package/skills/live-dashboard/examples/production-quality/preview.png +0 -0
- package/skills/live-dashboard/examples/production-quality/query.json +53 -0
- package/skills/live-dashboard/examples/regional-sales/README.md +25 -0
- package/skills/live-dashboard/examples/regional-sales/dashboard-create.json +35 -0
- package/skills/live-dashboard/examples/regional-sales/definition.json +35 -0
- package/skills/live-dashboard/examples/regional-sales/demo.csv +5 -0
- package/skills/live-dashboard/examples/regional-sales/demo.json +18 -0
- package/skills/live-dashboard/examples/regional-sales/expected.json +19 -0
- package/skills/live-dashboard/examples/regional-sales/preview.png +0 -0
- package/skills/live-dashboard/examples/regional-sales/query.json +45 -0
- package/skills/live-dashboard/examples/sales-overview/README.md +25 -0
- package/skills/live-dashboard/examples/sales-overview/dashboard.html +129 -0
- package/skills/live-dashboard/examples/sales-overview/definition.json +57 -0
- package/skills/live-dashboard/examples/sales-overview/demo.csv +7 -0
- package/skills/live-dashboard/examples/sales-overview/demo.json +38 -0
- package/skills/live-dashboard/examples/sales-overview/expected.json +22 -0
- package/skills/live-dashboard/examples/sales-overview/preview.png +0 -0
- package/skills/live-dashboard/examples/sales-overview/query.json +52 -0
- package/skills/live-dashboard/examples/superstore/README.md +64 -0
- package/skills/live-dashboard/examples/superstore/THIRD_PARTY_LICENSE.txt +207 -0
- package/skills/live-dashboard/examples/superstore/build_data.py +155 -0
- package/skills/live-dashboard/examples/superstore/build_pages.py +129 -0
- package/skills/live-dashboard/examples/superstore/checks.json +104 -0
- package/skills/live-dashboard/examples/superstore/customers-mobile-dark.png +0 -0
- package/skills/live-dashboard/examples/superstore/customers-select.png +0 -0
- package/skills/live-dashboard/examples/superstore/customers.html +316 -0
- package/skills/live-dashboard/examples/superstore/customers.png +0 -0
- package/skills/live-dashboard/examples/superstore/customers.queries.json +512 -0
- package/skills/live-dashboard/examples/superstore/expected.json +4069 -0
- package/skills/live-dashboard/examples/superstore/import.json +200 -0
- package/skills/live-dashboard/examples/superstore/orders.csv +10195 -0
- package/skills/live-dashboard/examples/superstore/overview-mobile-dark.png +0 -0
- package/skills/live-dashboard/examples/superstore/overview-select.png +0 -0
- package/skills/live-dashboard/examples/superstore/overview.html +310 -0
- package/skills/live-dashboard/examples/superstore/overview.png +0 -0
- package/skills/live-dashboard/examples/superstore/overview.queries.json +636 -0
- package/skills/live-dashboard/examples/superstore/page.js +109 -0
- package/skills/live-dashboard/examples/superstore/profitability-mobile-dark.png +0 -0
- package/skills/live-dashboard/examples/superstore/profitability-select.png +0 -0
- package/skills/live-dashboard/examples/superstore/profitability.html +307 -0
- package/skills/live-dashboard/examples/superstore/profitability.png +0 -0
- package/skills/live-dashboard/examples/superstore/profitability.queries.json +334 -0
- package/skills/live-dashboard/examples/superstore/provenance.json +24 -0
- package/skills/live-dashboard/examples/superstore/semantic-model.json +220 -0
- package/skills/live-dashboard/examples/superstore/test_data.py +62 -0
- package/skills/live-dashboard/references/html-runtime.md +1 -1
- package/skills/live-dashboard/themes/README.md +50 -0
- package/skills/live-dashboard/themes/customer-brief/README.md +47 -0
- package/skills/live-dashboard/themes/customer-brief/charts.js +17 -0
- package/skills/live-dashboard/themes/customer-brief/layout.html +22 -0
- package/skills/live-dashboard/themes/customer-brief/theme.css +108 -0
- package/skills/live-dashboard/themes/profit-atlas/README.md +43 -0
- package/skills/live-dashboard/themes/profit-atlas/charts.js +30 -0
- package/skills/live-dashboard/themes/profit-atlas/layout.html +19 -0
- package/skills/live-dashboard/themes/profit-atlas/theme.css +75 -0
- package/skills/live-dashboard/themes/trend-workspace/ICON_LICENSE.txt +43 -0
- package/skills/live-dashboard/themes/trend-workspace/README.md +144 -0
- package/skills/live-dashboard/themes/trend-workspace/charts.js +60 -0
- package/skills/live-dashboard/themes/trend-workspace/icons.js +11 -0
- package/skills/live-dashboard/themes/trend-workspace/layout.html +45 -0
- package/skills/live-dashboard/themes/trend-workspace/select.js +127 -0
- package/skills/live-dashboard/themes/trend-workspace/theme.css +137 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { z } from 'zod/v3';
|
|
2
|
+
import { type AgentMiddleware, type IAgentMiddlewareStrategy, type IAgentMiddlewareContext } from '@xpert-ai/plugin-sdk';
|
|
3
|
+
import type { TAgentMiddlewareMeta, XpertResolvedViewHostContext } from '@xpert-ai/contracts';
|
|
4
|
+
import { DashboardService } from './dashboard.service';
|
|
5
|
+
declare const freshnessRuleSchema: z.ZodObject<{
|
|
6
|
+
bindingId: z.ZodString;
|
|
7
|
+
fieldId: z.ZodString;
|
|
8
|
+
maxAgeSeconds: z.ZodNumber;
|
|
9
|
+
}, "strict", z.ZodTypeAny, {
|
|
10
|
+
bindingId: string;
|
|
11
|
+
fieldId: string;
|
|
12
|
+
maxAgeSeconds: number;
|
|
13
|
+
}, {
|
|
14
|
+
bindingId: string;
|
|
15
|
+
fieldId: string;
|
|
16
|
+
maxAgeSeconds: number;
|
|
17
|
+
}>;
|
|
18
|
+
type FreshnessRule = z.infer<typeof freshnessRuleSchema>;
|
|
19
|
+
export declare class DashboardMonitor {
|
|
20
|
+
private readonly dashboards;
|
|
21
|
+
constructor(dashboards: DashboardService);
|
|
22
|
+
inspect(context: XpertResolvedViewHostContext, artifactId: string, freshnessRule?: FreshnessRule): Promise<{
|
|
23
|
+
artifactId: string;
|
|
24
|
+
versionId: string;
|
|
25
|
+
title: string;
|
|
26
|
+
status: "attention" | "healthy";
|
|
27
|
+
checkedAt: string;
|
|
28
|
+
failures: {
|
|
29
|
+
bindingId: string;
|
|
30
|
+
datasetId: string;
|
|
31
|
+
reason: "unavailable";
|
|
32
|
+
}[];
|
|
33
|
+
datasets: {
|
|
34
|
+
datasetId: string;
|
|
35
|
+
queryFetchedAt: string;
|
|
36
|
+
truncated: boolean;
|
|
37
|
+
returnedRows: number;
|
|
38
|
+
}[];
|
|
39
|
+
businessFreshness: {
|
|
40
|
+
status: "unknown" | "stale" | "fresh";
|
|
41
|
+
latestTimestamp: string | null;
|
|
42
|
+
coverage: "latest_returned_timestamp";
|
|
43
|
+
bindingId: string;
|
|
44
|
+
fieldId: string;
|
|
45
|
+
maxAgeSeconds: number;
|
|
46
|
+
} | "not_asserted";
|
|
47
|
+
availableFreshnessFields: {
|
|
48
|
+
bindingId: string;
|
|
49
|
+
fieldId: string;
|
|
50
|
+
label: string;
|
|
51
|
+
}[];
|
|
52
|
+
}>;
|
|
53
|
+
}
|
|
54
|
+
export declare class DashboardMonitorMiddleware implements IAgentMiddlewareStrategy {
|
|
55
|
+
private readonly monitor;
|
|
56
|
+
private readonly dashboards;
|
|
57
|
+
readonly meta: TAgentMiddlewareMeta;
|
|
58
|
+
constructor(monitor: DashboardMonitor, dashboards: DashboardService);
|
|
59
|
+
createMiddleware(options: unknown, context: IAgentMiddlewareContext): AgentMiddleware;
|
|
60
|
+
}
|
|
61
|
+
/** Business freshness must be an explicit data contract, never the query fetch timestamp. */
|
|
62
|
+
export declare function assessFreshness(manifest: import('./dashboard.schema').DashboardManifest, datasets: import('@xpert-ai/contracts').AnalyticalDataset[], input: FreshnessRule, now: number): {
|
|
63
|
+
status: "unknown" | "stale" | "fresh";
|
|
64
|
+
latestTimestamp: string | null;
|
|
65
|
+
coverage: "latest_returned_timestamp";
|
|
66
|
+
bindingId: string;
|
|
67
|
+
fieldId: string;
|
|
68
|
+
maxAgeSeconds: number;
|
|
69
|
+
};
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.DashboardMonitorMiddleware = exports.DashboardMonitor = void 0;
|
|
13
|
+
exports.assessFreshness = assessFreshness;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const tools_1 = require("@langchain/core/tools");
|
|
16
|
+
const v3_1 = require("zod/v3");
|
|
17
|
+
const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
|
|
18
|
+
const dashboard_service_1 = require("./dashboard.service");
|
|
19
|
+
const runtime_context_1 = require("./runtime-context");
|
|
20
|
+
const dashboard_icon_1 = require("./dashboard-icon");
|
|
21
|
+
const freshnessRuleSchema = v3_1.z.object({ bindingId: v3_1.z.string().min(1), fieldId: v3_1.z.string().min(1), maxAgeSeconds: v3_1.z.number().int().min(1).max(31536000) }).strict();
|
|
22
|
+
let DashboardMonitor = class DashboardMonitor {
|
|
23
|
+
constructor(dashboards) {
|
|
24
|
+
this.dashboards = dashboards;
|
|
25
|
+
}
|
|
26
|
+
async inspect(context, artifactId, freshnessRule) {
|
|
27
|
+
const access = await this.dashboards.access(context);
|
|
28
|
+
if (!access.project || access.archived)
|
|
29
|
+
throw new common_1.ForbiddenException('DASHBOARD_ACTIVE_PROJECT_REQUIRED');
|
|
30
|
+
const saved = await this.dashboards.open(context, artifactId, undefined, undefined, 'published');
|
|
31
|
+
if (!saved.versionId)
|
|
32
|
+
throw new Error('DASHBOARD_NOT_PUBLISHED');
|
|
33
|
+
const result = await this.dashboards.query(context, artifactId, saved.versionId, {});
|
|
34
|
+
// Reauthorize the target after the queries; a receipt is bound to this formal version.
|
|
35
|
+
const current = await this.dashboards.open(context, artifactId, undefined, undefined, 'published');
|
|
36
|
+
if (current.versionId !== saved.versionId || (await this.dashboards.access(context)).archived)
|
|
37
|
+
throw new Error('DASHBOARD_INSPECTION_CHANGED');
|
|
38
|
+
const freshness = freshnessRule ? assessFreshness(saved.manifest, result.datasets, freshnessRule, Date.now()) : undefined;
|
|
39
|
+
return { artifactId, versionId: saved.versionId, title: saved.manifest.title,
|
|
40
|
+
status: result.failures.length || freshness && freshness.status !== 'fresh' ? 'attention' : 'healthy',
|
|
41
|
+
checkedAt: new Date().toISOString(), failures: result.failures,
|
|
42
|
+
datasets: result.datasets.map(dataset => ({ datasetId: dataset.datasetId, queryFetchedAt: dataset.freshness.sourceFetchedAt,
|
|
43
|
+
truncated: dataset.completeness.truncated, returnedRows: dataset.completeness.returnedRows })),
|
|
44
|
+
businessFreshness: freshness ?? 'not_asserted',
|
|
45
|
+
availableFreshnessFields: saved.manifest.bindings.flatMap(binding => binding.output.fields.filter(field => field.logicalType === 'timestamp')
|
|
46
|
+
.map(field => ({ bindingId: binding.id, fieldId: field.id, label: field.label }))) };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.DashboardMonitor = DashboardMonitor;
|
|
50
|
+
exports.DashboardMonitor = DashboardMonitor = __decorate([
|
|
51
|
+
(0, common_1.Injectable)(),
|
|
52
|
+
__metadata("design:paramtypes", [dashboard_service_1.DashboardService])
|
|
53
|
+
], DashboardMonitor);
|
|
54
|
+
let DashboardMonitorMiddleware = class DashboardMonitorMiddleware {
|
|
55
|
+
constructor(monitor, dashboards) {
|
|
56
|
+
this.monitor = monitor;
|
|
57
|
+
this.dashboards = dashboards;
|
|
58
|
+
this.meta = { name: 'LiveDashboardMonitor', icon: dashboard_icon_1.dashboardIcon, features: ['live_dashboard.monitor'],
|
|
59
|
+
label: { en_US: 'Dashboard inspection', zh_Hans: '看板巡检' },
|
|
60
|
+
description: { en_US: 'Inspect published Project dashboards without editing or publishing.', zh_Hans: '检查项目正式看板,不修改或发布。' },
|
|
61
|
+
configSchema: { type: 'object', properties: {}, additionalProperties: false } };
|
|
62
|
+
}
|
|
63
|
+
createMiddleware(options, context) {
|
|
64
|
+
v3_1.z.object({}).strict().parse(options ?? {});
|
|
65
|
+
const scope = (0, runtime_context_1.dashboardRuntimeContext)(context);
|
|
66
|
+
return { name: 'LiveDashboardMonitor', tools: [
|
|
67
|
+
(0, tools_1.tool)(async ({ artifactId, freshness }) => JSON.stringify(await this.monitor.inspect(scope, artifactId, freshness)), {
|
|
68
|
+
name: 'dashboard_inspect', description: 'Check one explicitly selected published Project dashboard as the current run actor. Returns compact binding availability and query timestamps, never data rows. Does not modify or publish. Query time is not proof of business-data freshness. Only an explicitly configured freshness rule checks the latest returned declared timestamp, and incomplete results remain unknown. Scheduled runs retain this receipt in platform execution history.',
|
|
69
|
+
schema: v3_1.z.object({ artifactId: v3_1.z.string().uuid(), freshness: freshnessRuleSchema.optional() }).strict(), verboseParsingErrors: true,
|
|
70
|
+
metadata: { toolName: { en_US: 'Inspect published dashboard', zh_Hans: '巡检正式看板' } }
|
|
71
|
+
}),
|
|
72
|
+
(0, tools_1.tool)(async ({ page }) => {
|
|
73
|
+
const access = await this.dashboards.access(scope);
|
|
74
|
+
if (!access.project || access.archived)
|
|
75
|
+
throw new common_1.ForbiddenException('DASHBOARD_ACTIVE_PROJECT_REQUIRED');
|
|
76
|
+
const result = await this.dashboards.listPage(scope, page, 50);
|
|
77
|
+
return JSON.stringify({ ...result, items: result.items.filter(item => !!item.versionId).map(({ artifactId, versionId, versionNumber, title }) => ({ artifactId, versionId, versionNumber, title })) });
|
|
78
|
+
}, { name: 'dashboard_list_published', description: 'List published dashboards in the current Project. Follow hasMore/page; never infer the target from recency.',
|
|
79
|
+
schema: v3_1.z.object({ page: v3_1.z.number().int().positive().default(1) }).strict(), verboseParsingErrors: true,
|
|
80
|
+
metadata: { toolName: { en_US: 'List published dashboards', zh_Hans: '列出正式看板' } } })
|
|
81
|
+
] };
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
exports.DashboardMonitorMiddleware = DashboardMonitorMiddleware;
|
|
85
|
+
exports.DashboardMonitorMiddleware = DashboardMonitorMiddleware = __decorate([
|
|
86
|
+
(0, plugin_sdk_1.AgentMiddlewareStrategy)('LiveDashboardMonitor'),
|
|
87
|
+
__metadata("design:paramtypes", [DashboardMonitor, dashboard_service_1.DashboardService])
|
|
88
|
+
], DashboardMonitorMiddleware);
|
|
89
|
+
/** Business freshness must be an explicit data contract, never the query fetch timestamp. */
|
|
90
|
+
function assessFreshness(manifest, datasets, input, now) {
|
|
91
|
+
const rule = freshnessRuleSchema.parse(input);
|
|
92
|
+
const binding = manifest.bindings.find(binding => binding.id === rule.bindingId);
|
|
93
|
+
const field = binding?.output.fields.find(field => field.id === rule.fieldId && field.logicalType === 'timestamp');
|
|
94
|
+
const dataset = datasets.find(dataset => dataset.datasetId === binding?.output.datasetId);
|
|
95
|
+
const values = dataset?.rows.map(row => row[rule.fieldId]) ?? [];
|
|
96
|
+
const times = values.map(value => typeof value === 'string' && /(?:Z|[+-]\d{2}:\d{2})$/.test(value) ? Date.parse(value) : NaN);
|
|
97
|
+
const unknown = !field || !dataset || dataset.completeness.truncated || !times.length || times.some(time => !Number.isFinite(time) || time > now + 60000);
|
|
98
|
+
const latest = unknown ? null : times.reduce((latest, time) => Math.max(latest, time), -Infinity);
|
|
99
|
+
return { ...rule, status: unknown ? 'unknown' : now - latest > rule.maxAgeSeconds * 1000 ? 'stale' : 'fresh',
|
|
100
|
+
latestTimestamp: latest === null ? null : new Date(latest).toISOString(), coverage: 'latest_returned_timestamp' };
|
|
101
|
+
}
|
package/dist/lib/plugin.js
CHANGED
|
@@ -7,7 +7,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
};
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.LiveDashboardPlugin = void 0;
|
|
10
|
+
const projects_service_1 = require("./projects.service");
|
|
10
11
|
const content_capability_1 = require("./content-capability");
|
|
12
|
+
const monitor_1 = require("./monitor");
|
|
11
13
|
const content_provider_1 = require("./content.provider");
|
|
12
14
|
const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
|
|
13
15
|
const dashboard_service_1 = require("./dashboard.service");
|
|
@@ -16,10 +18,11 @@ const middleware_1 = require("./middleware");
|
|
|
16
18
|
const html_validation_1 = require("./html-validation");
|
|
17
19
|
const presentation_provider_1 = require("./presentation.provider");
|
|
18
20
|
const sharing_service_1 = require("./sharing.service");
|
|
21
|
+
const artifact_type_provider_1 = require("./artifact-type.provider");
|
|
19
22
|
const provider_options_controller_1 = require("./provider-options.controller");
|
|
20
23
|
let LiveDashboardPlugin = class LiveDashboardPlugin {
|
|
21
24
|
};
|
|
22
25
|
exports.LiveDashboardPlugin = LiveDashboardPlugin;
|
|
23
26
|
exports.LiveDashboardPlugin = LiveDashboardPlugin = __decorate([
|
|
24
|
-
(0, plugin_sdk_1.XpertServerPlugin)({ controllers: [provider_options_controller_1.DashboardProviderOptionsController], providers: [content_capability_1.DashboardCapability, content_provider_1.DashboardContentProvider, content_provider_1.DashboardContentEditor, dashboard_service_1.DashboardService, view_provider_1.DashboardViewProvider, middleware_1.DashboardMiddleware, html_validation_1.HtmlDashboardValidation, presentation_provider_1.DashboardPresentationProvider, sharing_service_1.DashboardSharingService] })
|
|
27
|
+
(0, plugin_sdk_1.XpertServerPlugin)({ controllers: [provider_options_controller_1.DashboardProviderOptionsController], providers: [projects_service_1.DashboardProjectsService, monitor_1.DashboardMonitor, monitor_1.DashboardMonitorMiddleware, artifact_type_provider_1.DashboardArtifactType, content_capability_1.DashboardCapability, content_provider_1.DashboardContentProvider, content_provider_1.DashboardContentEditor, dashboard_service_1.DashboardService, view_provider_1.DashboardViewProvider, middleware_1.DashboardMiddleware, html_validation_1.HtmlDashboardValidation, presentation_provider_1.DashboardPresentationProvider, sharing_service_1.DashboardSharingService] })
|
|
25
28
|
], LiveDashboardPlugin);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export declare const DASHBOARD_PROJECT_TYPE: {
|
|
2
|
+
readonly applicationKey: "@xpert-ai/plugin-live-dashboard:live-dashboard";
|
|
3
|
+
readonly projectTypeKey: "dashboard";
|
|
4
|
+
};
|
|
5
|
+
export declare const dashboardApp: {
|
|
6
|
+
type: "app";
|
|
7
|
+
name: string;
|
|
8
|
+
icon: {
|
|
9
|
+
type: "svg";
|
|
10
|
+
alt: string;
|
|
11
|
+
value: string;
|
|
12
|
+
};
|
|
13
|
+
appConfig: {
|
|
14
|
+
scope: "organization";
|
|
15
|
+
assistantTemplateKey: string;
|
|
16
|
+
workspace: {
|
|
17
|
+
mode: "dedicated";
|
|
18
|
+
sharing: "private";
|
|
19
|
+
name: {
|
|
20
|
+
en_US: string;
|
|
21
|
+
zh_Hans: string;
|
|
22
|
+
};
|
|
23
|
+
description: {
|
|
24
|
+
en_US: string;
|
|
25
|
+
zh_Hans: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
knowledgebases: never[];
|
|
29
|
+
modelRequirements: {
|
|
30
|
+
primary: true;
|
|
31
|
+
};
|
|
32
|
+
presentation: {
|
|
33
|
+
developer: string;
|
|
34
|
+
tagline: {
|
|
35
|
+
en_US: string;
|
|
36
|
+
zh_Hans: string;
|
|
37
|
+
};
|
|
38
|
+
longDescription: {
|
|
39
|
+
en_US: string;
|
|
40
|
+
zh_Hans: string;
|
|
41
|
+
};
|
|
42
|
+
screenshots: string[];
|
|
43
|
+
features: {
|
|
44
|
+
key: string;
|
|
45
|
+
title: {
|
|
46
|
+
en_US: string;
|
|
47
|
+
zh_Hans: string;
|
|
48
|
+
};
|
|
49
|
+
description: {
|
|
50
|
+
en_US: string;
|
|
51
|
+
zh_Hans: string;
|
|
52
|
+
};
|
|
53
|
+
}[];
|
|
54
|
+
useCases: {
|
|
55
|
+
en_US: string;
|
|
56
|
+
zh_Hans: string;
|
|
57
|
+
}[];
|
|
58
|
+
dataScope: {
|
|
59
|
+
en_US: string;
|
|
60
|
+
zh_Hans: string;
|
|
61
|
+
};
|
|
62
|
+
initializationSummary: {
|
|
63
|
+
en_US: string;
|
|
64
|
+
zh_Hans: string;
|
|
65
|
+
};
|
|
66
|
+
initializationSteps: {
|
|
67
|
+
en_US: string;
|
|
68
|
+
zh_Hans: string;
|
|
69
|
+
}[];
|
|
70
|
+
};
|
|
71
|
+
entry: {
|
|
72
|
+
type: "assistant-chat";
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
displayName: {
|
|
76
|
+
en_US: string;
|
|
77
|
+
zh_Hans: string;
|
|
78
|
+
};
|
|
79
|
+
description: {
|
|
80
|
+
en_US: string;
|
|
81
|
+
zh_Hans: string;
|
|
82
|
+
};
|
|
83
|
+
projectTypes: {
|
|
84
|
+
key: "dashboard";
|
|
85
|
+
title: {
|
|
86
|
+
en_US: string;
|
|
87
|
+
zh_Hans: string;
|
|
88
|
+
};
|
|
89
|
+
icon: {
|
|
90
|
+
type: "svg";
|
|
91
|
+
alt: string;
|
|
92
|
+
value: string;
|
|
93
|
+
};
|
|
94
|
+
binding: {
|
|
95
|
+
kind: "project";
|
|
96
|
+
};
|
|
97
|
+
}[];
|
|
98
|
+
};
|
|
99
|
+
export type DashboardAccess = {
|
|
100
|
+
project: boolean;
|
|
101
|
+
archived: boolean;
|
|
102
|
+
canReadDraft: boolean;
|
|
103
|
+
canEdit: boolean;
|
|
104
|
+
canManage: boolean;
|
|
105
|
+
};
|
|
106
|
+
export type DashboardMode = 'published' | 'draft';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dashboardApp = exports.DASHBOARD_PROJECT_TYPE = void 0;
|
|
4
|
+
const dashboard_icon_1 = require("./dashboard-icon");
|
|
5
|
+
const app_config_1 = require("./app-config");
|
|
6
|
+
exports.DASHBOARD_PROJECT_TYPE = {
|
|
7
|
+
applicationKey: '@xpert-ai/plugin-live-dashboard:live-dashboard', projectTypeKey: 'dashboard'
|
|
8
|
+
};
|
|
9
|
+
exports.dashboardApp = {
|
|
10
|
+
type: 'app', name: 'live-dashboard', icon: dashboard_icon_1.dashboardIcon,
|
|
11
|
+
appConfig: app_config_1.dashboardAppConfig,
|
|
12
|
+
displayName: { en_US: 'Live Dashboard', zh_Hans: '实时看板' },
|
|
13
|
+
description: { en_US: 'Create and use live dashboards in Assistant ChatKit with a synchronized Project selection.', zh_Hans: '在助理 ChatKit 中按项目制作和使用实时看板,项目选择双向同步。' },
|
|
14
|
+
projectTypes: [{ key: exports.DASHBOARD_PROJECT_TYPE.projectTypeKey,
|
|
15
|
+
title: { en_US: 'Live Dashboard project', zh_Hans: '实时看板项目' }, icon: dashboard_icon_1.dashboardIcon,
|
|
16
|
+
binding: { kind: 'project' } }]
|
|
17
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from 'zod/v3';
|
|
2
|
+
export declare const projectSearchSchema: z.ZodObject<{
|
|
3
|
+
search: z.ZodDefault<z.ZodString>;
|
|
4
|
+
page: z.ZodDefault<z.ZodNumber>;
|
|
5
|
+
}, "strict", z.ZodTypeAny, {
|
|
6
|
+
search: string;
|
|
7
|
+
page: number;
|
|
8
|
+
}, {
|
|
9
|
+
search?: string | undefined;
|
|
10
|
+
page?: number | undefined;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const dashboardProjectSchema: z.ZodObject<{
|
|
13
|
+
id: z.ZodString;
|
|
14
|
+
name: z.ZodString;
|
|
15
|
+
}, "strip", z.ZodTypeAny, {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
}, {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
}>;
|
|
22
|
+
export declare const dashboardProjectsSchema: z.ZodObject<{
|
|
23
|
+
items: z.ZodArray<z.ZodObject<{
|
|
24
|
+
id: z.ZodString;
|
|
25
|
+
name: z.ZodString;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
}, {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
}>, "many">;
|
|
33
|
+
page: z.ZodNumber;
|
|
34
|
+
hasMore: z.ZodBoolean;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
page: number;
|
|
37
|
+
items: {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
}[];
|
|
41
|
+
hasMore: boolean;
|
|
42
|
+
}, {
|
|
43
|
+
page: number;
|
|
44
|
+
items: {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
}[];
|
|
48
|
+
hasMore: boolean;
|
|
49
|
+
}>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dashboardProjectsSchema = exports.dashboardProjectSchema = exports.projectSearchSchema = void 0;
|
|
4
|
+
const v3_1 = require("zod/v3");
|
|
5
|
+
exports.projectSearchSchema = v3_1.z.object({ search: v3_1.z.string().trim().max(200).default(''), page: v3_1.z.number().int().positive().default(1) }).strict();
|
|
6
|
+
exports.dashboardProjectSchema = v3_1.z.object({ id: v3_1.z.string().uuid(), name: v3_1.z.string() });
|
|
7
|
+
exports.dashboardProjectsSchema = v3_1.z.object({ items: v3_1.z.array(exports.dashboardProjectSchema), page: v3_1.z.number().int().positive(), hasMore: v3_1.z.boolean() });
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod/v3';
|
|
2
|
+
import type { XpertResolvedViewHostContext } from '@xpert-ai/contracts';
|
|
3
|
+
import { type RuntimeCapabilityRegistry } from '@xpert-ai/plugin-sdk';
|
|
4
|
+
import { projectSearchSchema } from './projects.schema';
|
|
5
|
+
export { projectSearchSchema } from './projects.schema';
|
|
6
|
+
/** Selection uses the host's membership and Assistant binding policy, never a client-supplied data scope. */
|
|
7
|
+
export declare class DashboardProjectsService {
|
|
8
|
+
private readonly runtime;
|
|
9
|
+
constructor(runtime: RuntimeCapabilityRegistry);
|
|
10
|
+
private actor;
|
|
11
|
+
current(context: XpertResolvedViewHostContext): Promise<{
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
} | null>;
|
|
15
|
+
list(context: XpertResolvedViewHostContext, input: z.infer<typeof projectSearchSchema>): Promise<{
|
|
16
|
+
items: {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
}[];
|
|
20
|
+
page: number;
|
|
21
|
+
hasMore: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.DashboardProjectsService = exports.projectSearchSchema = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
|
|
18
|
+
const dashboard_service_1 = require("./dashboard.service");
|
|
19
|
+
var projects_schema_1 = require("./projects.schema");
|
|
20
|
+
Object.defineProperty(exports, "projectSearchSchema", { enumerable: true, get: function () { return projects_schema_1.projectSearchSchema; } });
|
|
21
|
+
/** Selection uses the host's membership and Assistant binding policy, never a client-supplied data scope. */
|
|
22
|
+
let DashboardProjectsService = class DashboardProjectsService {
|
|
23
|
+
constructor(runtime) {
|
|
24
|
+
this.runtime = runtime;
|
|
25
|
+
}
|
|
26
|
+
actor(context) {
|
|
27
|
+
if (context.hostType !== 'agent' || !context.tenantId || !context.organizationId || !context.userId)
|
|
28
|
+
throw new common_1.ForbiddenException('DASHBOARD_ACCESS_DENIED');
|
|
29
|
+
return { tenantId: context.tenantId, organizationId: context.organizationId, userId: context.userId };
|
|
30
|
+
}
|
|
31
|
+
async current(context) {
|
|
32
|
+
const id = (0, dashboard_service_1.projectId)(context);
|
|
33
|
+
if (!id)
|
|
34
|
+
return null;
|
|
35
|
+
const access = await this.runtime.require(plugin_sdk_1.ProjectAccessRuntimeCapability).assertAssistant({ actor: this.actor(context), projectId: id, assistantId: context.hostId });
|
|
36
|
+
return { id, name: access.name ?? id };
|
|
37
|
+
}
|
|
38
|
+
async list(context, input) {
|
|
39
|
+
const actor = this.actor(context), access = this.runtime.require(plugin_sdk_1.ProjectAccessRuntimeCapability);
|
|
40
|
+
const projects = await access.listReadable({ actor });
|
|
41
|
+
const items = [];
|
|
42
|
+
for (const project of projects) {
|
|
43
|
+
if (project.archived || !(project.name ?? project.projectId).toLocaleLowerCase().includes(input.search.toLocaleLowerCase()))
|
|
44
|
+
continue;
|
|
45
|
+
try {
|
|
46
|
+
await access.assertAssistant({ actor, projectId: project.projectId, assistantId: context.hostId });
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error instanceof common_1.ForbiddenException)
|
|
50
|
+
continue;
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
items.push({ id: project.projectId, name: project.name ?? project.projectId });
|
|
54
|
+
}
|
|
55
|
+
items.sort((a, b) => a.name.localeCompare(b.name) || a.id.localeCompare(b.id));
|
|
56
|
+
const start = (input.page - 1) * 20;
|
|
57
|
+
return { items: items.slice(start, start + 20), page: input.page, hasMore: start + 20 < items.length };
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
exports.DashboardProjectsService = DashboardProjectsService;
|
|
61
|
+
exports.DashboardProjectsService = DashboardProjectsService = __decorate([
|
|
62
|
+
(0, common_1.Injectable)(),
|
|
63
|
+
__param(0, (0, common_1.Inject)(plugin_sdk_1.XPERT_RUNTIME_CAPABILITIES_TOKEN)),
|
|
64
|
+
__metadata("design:paramtypes", [Object])
|
|
65
|
+
], DashboardProjectsService);
|
|
@@ -16,7 +16,7 @@ function dashboardResourceCard(scope, saved) {
|
|
|
16
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
|
+
parameters: saved.state === 'published' && saved.versionId ? { versionId: saved.versionId } : { mode: 'draft' }
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dashboardRuntimeContext = dashboardRuntimeContext;
|
|
4
|
+
const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
|
|
5
|
+
function dashboardRuntimeContext(context) {
|
|
6
|
+
if (!context.xpertId)
|
|
7
|
+
throw new Error('DASHBOARD_ASSISTANT_REQUIRED');
|
|
8
|
+
return { tenantId: context.tenantId ?? plugin_sdk_1.RequestContext.currentTenantId(),
|
|
9
|
+
organizationId: context.organizationId ?? plugin_sdk_1.RequestContext.getOrganizationId(), userId: context.userId ?? plugin_sdk_1.RequestContext.currentUserId(),
|
|
10
|
+
hostType: 'agent', hostId: context.xpertId, slots: [],
|
|
11
|
+
...(context.projectId ? { runtimeScope: { projectId: context.projectId, conversationId: context.conversationId ?? null,
|
|
12
|
+
dataScopeKey: `project:${context.projectId}`, workspaceFiles: { catalog: 'projects', scopeId: context.projectId, projectId: context.projectId } } } : {}) };
|
|
13
|
+
}
|
|
@@ -15,7 +15,7 @@ export declare function dashboardSaveEvidence(files: () => WorkspaceFilesApi): {
|
|
|
15
15
|
token: number;
|
|
16
16
|
generations: Map<string, number>;
|
|
17
17
|
supersedesPaths: string[];
|
|
18
|
-
confirmation: "
|
|
18
|
+
confirmation: "source" | "draft";
|
|
19
19
|
};
|
|
20
20
|
accept(save: SaveAttempt, output: unknown): Promise<void>;
|
|
21
21
|
readonly pending: boolean;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dashboardTemplates = void 0;
|
|
4
|
+
const contracts_1 = require("@xpert-ai/contracts");
|
|
5
|
+
const project_1 = require("./project");
|
|
6
|
+
const dashboard_icon_1 = require("./dashboard-icon");
|
|
7
|
+
const prompt_workflows_1 = require("./prompt-workflows");
|
|
8
|
+
const startPrompts = [
|
|
9
|
+
"请读取 live-dashboard 技能中 regional-sales 的完整配方,使用该配方随附的演示文件和标准图表定义,在当前项目新建区域销售看板。核对区域筛选、销售额和明细;不要使用其他样例或项目中已有的不同数据替代。完成实际查询与两个筛选验证后保存草稿,保留演示标识,不发布。",
|
|
10
|
+
"请读取 live-dashboard 技能中 sales-overview 的完整配方,使用该配方随附的演示文件和完整页面,在当前项目新建销售总览看板。包含销售额、订单数、日趋势、区域筛选和明细;不要使用其他样例或项目中已有的不同数据替代。完成实际查询与两个筛选验证后保存草稿,保留演示标识,不发布。",
|
|
11
|
+
"请读取 live-dashboard 技能中 production-quality 的完整配方,使用该配方随附的演示文件和完整页面,在当前项目新建生产质量看板。必须包含产量、良品数、加权良品率、不良品数和产线筛选;不要将销售数据或其他看板改名替代。完成实际查询与两个产线筛选验证后保存草稿,保留演示标识,不发布。",
|
|
12
|
+
"请读取 live-dashboard 技能中的 themes/README.md 和 superstore 完整配方(总览使用 Trend Workspace、盈利使用 Profit Atlas、客户退货使用 Customer Brief),在当前项目使用已授权的 Data Xpert SuperstoreOrders 发布模型,分别制作经营总览、商品盈利、客户与退货三个看板。必须保留演示标识;先核对全量及区域、年份、品类筛选,再按完整 HTML 和全部 Binding 保存三个草稿,不发布。若模型不可用,请说明数据准备步骤,不得用其他样例或自造数据替代。",
|
|
13
|
+
"使用我的业务数据制作看板,先检查当前项目可用的数据及指标口径。"
|
|
14
|
+
];
|
|
15
|
+
const startLabels = ['区域销售 · 入门', '销售总览 · 入门', '生产质量 · 入门', 'Superstore 企业分析 · 进阶', '使用我的数据'];
|
|
16
|
+
const dsl = (monitor) => JSON.stringify({
|
|
17
|
+
team: { name: monitor ? 'live-dashboard-monitor' : 'live-dashboard-assistant', type: 'agent',
|
|
18
|
+
title: monitor ? '看板巡检' : '实时看板助理', version: '1', agent: { key: 'Agent_Dashboard' },
|
|
19
|
+
options: { workspaceScope: { mode: 'project-required', projectType: project_1.DASHBOARD_PROJECT_TYPE } },
|
|
20
|
+
features: monitor ? {} : { sandbox: { enabled: true }, opener: { enabled: true,
|
|
21
|
+
message: '选择或创建项目,从样例开始,或连接你的业务数据制作实时看板。', questions: startPrompts.map((prompt, index) => ({ label: startLabels[index], prompt })) } },
|
|
22
|
+
// Reading a recipe, registering its file and validating filters spans multiple graph steps per tool call.
|
|
23
|
+
agentConfig: { recursionLimit: monitor ? 100 : 300 }, workspaceDataScope: 'shared', knowledgebases: [], toolsets: [], tags: [] },
|
|
24
|
+
nodes: [
|
|
25
|
+
{ type: 'agent', key: 'Agent_Dashboard', position: { x: 200, y: 100 }, entity: { key: 'Agent_Dashboard',
|
|
26
|
+
name: monitor ? 'dashboard-monitor' : 'dashboard-author', title: monitor ? '看板巡检' : '看板制作',
|
|
27
|
+
prompt: monitor
|
|
28
|
+
? 'Inspect explicitly selected published dashboards in the current Project. Use dashboard_inspect to check live bindings as the scheduled run actor. Report failed bindings, incomplete results and the observed freshness; never claim business-data freshness from query time alone. Do not change definitions, publish, or expand access. Only schedule work when the human requests it. Use the user language.'
|
|
29
|
+
: 'Create and maintain dashboards in the current Project. Read the live-dashboard skill before authoring. For example requests use read_skill_file to read examples/catalog.json and the selected recipe directly relative to the catalog SKILL.md path; do not list sandbox directories to locate bundled files. After a successful draft receipt, report the receipt and let the user open its emitted card; do not reopen/update an unchanged dashboard merely to verify the save. Ask whether to use labeled synthetic demo data or authorized real data when unspecified. Small onboarding demo files belong to the current Project and use file.table after registration. The Superstore enterprise recipe instead requires the authorized published Data Xpert ontology; follow its own setup and query plans, never replace it with file.table or other sample rows. Never substitute demo values for missing real data. For enterprise BI pages, read themes/README.md, choose one visual style appropriate to the requested analysis and read its guide and complete recipe. The Superstore suite uses Trend Workspace for overview, Profit Atlas for profitability and Customer Brief for customers and returns. Use echarts plus exactly one matching theme library, adapt chart fields to discovered data, and preserve the selected theme on edits unless a redesign is requested. Discover registered data sources and validate exact bindings. Preserve the selected Artifact, component IDs and current draft revision on edits. Saving is not publication. Publication requires a manager in the Workbench. Never infer another dashboard from titles or recency. Use the user language.',
|
|
30
|
+
collaboratorNames: [], toolsetIds: [], knowledgebaseIds: [] } },
|
|
31
|
+
...(monitor ? ['LiveDashboardMonitor', 'scheduler'] : ['LiveDashboard', 'SandboxFile', 'skillsMiddleware']).map((provider, index) => ({
|
|
32
|
+
type: 'workflow', key: `Middleware_${provider}`, position: { x: 550, y: 100 + index * 120 },
|
|
33
|
+
entity: { type: 'middleware', key: `Middleware_${provider}`, title: provider, provider, required: true,
|
|
34
|
+
...(provider === 'LiveDashboard' ? { options: { maxModelCalls: 64 } } : {}) }
|
|
35
|
+
}))
|
|
36
|
+
],
|
|
37
|
+
connections: (monitor ? ['LiveDashboardMonitor', 'scheduler'] : ['LiveDashboard', 'SandboxFile', 'skillsMiddleware']).map(provider => ({
|
|
38
|
+
type: 'workflow', key: `Agent_Dashboard/Middleware_${provider}`, from: 'Agent_Dashboard', to: `Middleware_${provider}`, required: true
|
|
39
|
+
}))
|
|
40
|
+
});
|
|
41
|
+
exports.dashboardTemplates = [false, true].map(monitor => ({
|
|
42
|
+
key: monitor ? 'live-dashboard-monitor' : 'live-dashboard-assistant',
|
|
43
|
+
name: monitor ? 'Live Dashboard Monitor' : 'Live Dashboard Assistant',
|
|
44
|
+
title: monitor ? '看板巡检' : '实时看板助理', type: contracts_1.XpertTypeEnum.Agent, icon: dashboard_icon_1.dashboardIcon,
|
|
45
|
+
description: monitor ? '在项目内以授权身份检查正式看板,不修改或发布。' : '在项目内制作和维护看板,草稿与正式发布分离。',
|
|
46
|
+
targetApps: ['xpert', 'data-xpert'], targetAppMeta: { xpert: { types: ['business-assistant'],
|
|
47
|
+
capabilities: [monitor ? 'live_dashboard.monitor' : 'live_dashboard'], requiredPlugins: monitor ? ['@xpert-ai/plugin-live-dashboard'] : ['@xpert-ai/plugin-live-dashboard', '@xpert-ai/plugin-analytics-files'] } },
|
|
48
|
+
dependencies: { plugins: monitor ? ['@xpert-ai/plugin-live-dashboard'] : ['@xpert-ai/plugin-live-dashboard', '@xpert-ai/plugin-analytics-files'],
|
|
49
|
+
skills: monitor ? [] : [{ componentKey: 'live-dashboard', targetAgentKey: 'Agent_Dashboard' }] },
|
|
50
|
+
category: 'Analytics',
|
|
51
|
+
promptWorkflows: monitor ? undefined : prompt_workflows_1.dashboardWorkspacePrompts,
|
|
52
|
+
startPrompts: monitor ? [] : startPrompts,
|
|
53
|
+
releaseNotes: monitor ? undefined : 'Adds project-scoped onboarding, three small examples and the Data Xpert Superstore enterprise suite with three optional reusable visual styles (Trend Workspace, Profit Atlas and Customer Brief) and accessible select controls; existing dashboards are never overwritten by template updates.',
|
|
54
|
+
dslContent: dsl(monitor), default: false, order: monitor ? 36 : 35
|
|
55
|
+
}));
|