@butlr/butlr-mcp-server 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cache/topology-cache.d.ts +18 -3
- package/dist/cache/topology-cache.d.ts.map +1 -1
- package/dist/cache/topology-cache.js +19 -3
- package/dist/cache/topology-cache.js.map +1 -1
- package/dist/clients/queries/tags.d.ts +63 -6
- package/dist/clients/queries/tags.d.ts.map +1 -1
- package/dist/clients/queries/tags.js +26 -4
- package/dist/clients/queries/tags.js.map +1 -1
- package/dist/clients/queries/topology.d.ts +8 -2
- package/dist/clients/queries/topology.d.ts.map +1 -1
- package/dist/clients/queries/topology.js +19 -2
- package/dist/clients/queries/topology.js.map +1 -1
- package/dist/clients/types.d.ts +4 -0
- package/dist/clients/types.d.ts.map +1 -1
- package/dist/errors/mcp-errors.d.ts +34 -0
- package/dist/errors/mcp-errors.d.ts.map +1 -1
- package/dist/errors/mcp-errors.js +71 -5
- package/dist/errors/mcp-errors.js.map +1 -1
- package/dist/tools/butlr-available-rooms.d.ts +5 -23
- package/dist/tools/butlr-available-rooms.d.ts.map +1 -1
- package/dist/tools/butlr-available-rooms.js +104 -51
- package/dist/tools/butlr-available-rooms.js.map +1 -1
- package/dist/tools/butlr-fetch-entity-details.d.ts +4 -0
- package/dist/tools/butlr-fetch-entity-details.d.ts.map +1 -1
- package/dist/tools/butlr-fetch-entity-details.js +31 -1
- package/dist/tools/butlr-fetch-entity-details.js.map +1 -1
- package/dist/tools/butlr-get-asset-details.d.ts.map +1 -1
- package/dist/tools/butlr-get-asset-details.js +29 -4
- package/dist/tools/butlr-get-asset-details.js.map +1 -1
- package/dist/tools/butlr-get-current-occupancy.d.ts.map +1 -1
- package/dist/tools/butlr-get-current-occupancy.js +15 -4
- package/dist/tools/butlr-get-current-occupancy.js.map +1 -1
- package/dist/tools/butlr-get-occupancy-timeseries.d.ts.map +1 -1
- package/dist/tools/butlr-get-occupancy-timeseries.js +16 -5
- package/dist/tools/butlr-get-occupancy-timeseries.js.map +1 -1
- package/dist/tools/butlr-list-tags.d.ts +28 -10
- package/dist/tools/butlr-list-tags.d.ts.map +1 -1
- package/dist/tools/butlr-list-tags.js +81 -24
- package/dist/tools/butlr-list-tags.js.map +1 -1
- package/dist/tools/butlr-list-topology.d.ts +7 -1
- package/dist/tools/butlr-list-topology.d.ts.map +1 -1
- package/dist/tools/butlr-list-topology.js +845 -35
- package/dist/tools/butlr-list-topology.js.map +1 -1
- package/dist/tools/butlr-search-assets.d.ts.map +1 -1
- package/dist/tools/butlr-search-assets.js +7 -1
- package/dist/tools/butlr-search-assets.js.map +1 -1
- package/dist/tools/butlr-space-busyness.d.ts.map +1 -1
- package/dist/tools/butlr-space-busyness.js +22 -4
- package/dist/tools/butlr-space-busyness.js.map +1 -1
- package/dist/tools/butlr-traffic-flow.d.ts.map +1 -1
- package/dist/tools/butlr-traffic-flow.js +9 -3
- package/dist/tools/butlr-traffic-flow.js.map +1 -1
- package/dist/types/responses.d.ts +123 -5
- package/dist/types/responses.d.ts.map +1 -1
- package/dist/utils/field-validator.d.ts +6 -0
- package/dist/utils/field-validator.d.ts.map +1 -1
- package/dist/utils/field-validator.js +5 -1
- package/dist/utils/field-validator.js.map +1 -1
- package/dist/utils/occupancy-helpers.d.ts +15 -2
- package/dist/utils/occupancy-helpers.d.ts.map +1 -1
- package/dist/utils/occupancy-helpers.js +116 -19
- package/dist/utils/occupancy-helpers.js.map +1 -1
- package/dist/utils/tag-resolver.d.ts +99 -0
- package/dist/utils/tag-resolver.d.ts.map +1 -0
- package/dist/utils/tag-resolver.js +108 -0
- package/dist/utils/tag-resolver.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReportingRequestBuilder } from "../clients/reporting-client.js";
|
|
1
|
+
import { ReportingRequestBuilder, ApiError } from "../clients/reporting-client.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { fetchTopologyAndSensors, resolveAssetContext, getPresenceMeasurement, getTrafficMeasurement, getPresenceCoverageNote, getTrafficCoverageNote, buildRecommendation, } from "../utils/occupancy-helpers.js";
|
|
4
4
|
import { debug } from "../utils/debug.js";
|
|
@@ -31,13 +31,18 @@ export async function executeGetCurrentOccupancy(args) {
|
|
|
31
31
|
for (const assetId of args.asset_ids) {
|
|
32
32
|
const asset = resolveAssetContext(assetId, ctx);
|
|
33
33
|
// ---- Presence ----
|
|
34
|
+
// Zones have no client-visible sensor attribution (see occupancy-helpers
|
|
35
|
+
// `resolveAssetContext`), but the server computes `zone_occupancy`
|
|
36
|
+
// independently. Always query for zones; gate on sensor count for
|
|
37
|
+
// rooms/floors where 0 sensors really does mean "no data possible".
|
|
38
|
+
const shouldQueryPresence = asset.assetType === "zone" || asset.presenceSensors.length > 0;
|
|
34
39
|
const presenceData = {
|
|
35
|
-
available:
|
|
40
|
+
available: shouldQueryPresence,
|
|
36
41
|
sensor_count: asset.presenceSensors.length,
|
|
37
42
|
coverage_note: getPresenceCoverageNote(asset.assetType, asset.presenceSensors.length),
|
|
38
43
|
};
|
|
39
44
|
let presenceHasData = false;
|
|
40
|
-
if (
|
|
45
|
+
if (shouldQueryPresence) {
|
|
41
46
|
const measurement = getPresenceMeasurement(asset.assetType);
|
|
42
47
|
try {
|
|
43
48
|
const response = await new ReportingRequestBuilder()
|
|
@@ -55,6 +60,9 @@ export async function executeGetCurrentOccupancy(args) {
|
|
|
55
60
|
}
|
|
56
61
|
catch (error) {
|
|
57
62
|
debug("current-occupancy", "Presence query failed:", error);
|
|
63
|
+
if (error instanceof ApiError && error.statusCode >= 400) {
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
58
66
|
presenceData.warning =
|
|
59
67
|
"Failed to retrieve current presence data. Occupancy value may be missing.";
|
|
60
68
|
}
|
|
@@ -85,12 +93,15 @@ export async function executeGetCurrentOccupancy(args) {
|
|
|
85
93
|
}
|
|
86
94
|
catch (error) {
|
|
87
95
|
debug("current-occupancy", "Traffic query failed:", error);
|
|
96
|
+
if (error instanceof ApiError && error.statusCode >= 400) {
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
88
99
|
trafficData.warning =
|
|
89
100
|
"Failed to retrieve current traffic data. Occupancy value may be missing.";
|
|
90
101
|
}
|
|
91
102
|
}
|
|
92
103
|
// ---- Recommendation (checks data success, not just sensor availability) ----
|
|
93
|
-
const recommendation = buildRecommendation(presenceData, trafficData, presenceHasData, trafficHasData);
|
|
104
|
+
const recommendation = buildRecommendation(presenceData, trafficData, presenceHasData, trafficHasData, { assetType: asset.assetType, windowLabel: "the last 5 minutes" });
|
|
94
105
|
const assetEntry = {
|
|
95
106
|
asset_id: assetId,
|
|
96
107
|
asset_type: asset.assetType,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"butlr-get-current-occupancy.js","sourceRoot":"","sources":["../../src/tools/butlr-get-current-occupancy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"butlr-get-current-occupancy.js","sourceRoot":"","sources":["../../src/tools/butlr-get-current-occupancy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"butlr-get-occupancy-timeseries.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-get-occupancy-timeseries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,OAAO,KAAK,EACV,2BAA2B,EAI5B,MAAM,uBAAuB,CAAC;AAyB/B,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;EAAsD,CAAC;AAEpG,sDAAsD;AACtD,KAAK,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAiCpF;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,2BAA2B,CAAC,
|
|
1
|
+
{"version":3,"file":"butlr-get-occupancy-timeseries.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-get-occupancy-timeseries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,OAAO,KAAK,EACV,2BAA2B,EAI5B,MAAM,uBAAuB,CAAC;AAyB/B,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;EAAsD,CAAC;AAEpG,sDAAsD;AACtD,KAAK,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAiCpF;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,2BAA2B,CAAC,CA6HtC;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsBtE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReportingRequestBuilder } from "../clients/reporting-client.js";
|
|
1
|
+
import { ReportingRequestBuilder, ApiError } from "../clients/reporting-client.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { validateTimeRange } from "../utils/time-range-validator.js";
|
|
4
4
|
import { fetchTopologyAndSensors, resolveAssetContext, getPresenceMeasurement, getTrafficMeasurement, getPresenceCoverageNote, getTrafficCoverageNote, buildRecommendation, } from "../utils/occupancy-helpers.js";
|
|
@@ -55,14 +55,19 @@ export async function executeGetOccupancyTimeseries(args) {
|
|
|
55
55
|
let hasAnyFallback = false;
|
|
56
56
|
for (const assetId of args.asset_ids) {
|
|
57
57
|
const asset = resolveAssetContext(assetId, ctx);
|
|
58
|
-
// Build presence measurement data
|
|
58
|
+
// Build presence measurement data. Zones have no client-visible sensor
|
|
59
|
+
// attribution (see occupancy-helpers `resolveAssetContext`), but the
|
|
60
|
+
// server computes `zone_occupancy` independently. Always query for
|
|
61
|
+
// zones; gate on sensor count for rooms/floors where 0 sensors really
|
|
62
|
+
// does mean "no data possible".
|
|
63
|
+
const shouldQueryPresence = asset.assetType === "zone" || asset.presenceSensors.length > 0;
|
|
59
64
|
const presenceData = {
|
|
60
|
-
available:
|
|
65
|
+
available: shouldQueryPresence,
|
|
61
66
|
sensor_count: asset.presenceSensors.length,
|
|
62
67
|
coverage_note: getPresenceCoverageNote(asset.assetType, asset.presenceSensors.length),
|
|
63
68
|
timeseries: [],
|
|
64
69
|
};
|
|
65
|
-
if (
|
|
70
|
+
if (shouldQueryPresence) {
|
|
66
71
|
const measurement = getPresenceMeasurement(asset.assetType);
|
|
67
72
|
try {
|
|
68
73
|
const points = await queryTimeseries(asset.assetType, assetId, measurement, args.start, args.stop, args.interval, asset.timezone);
|
|
@@ -72,6 +77,9 @@ export async function executeGetOccupancyTimeseries(args) {
|
|
|
72
77
|
}
|
|
73
78
|
catch (error) {
|
|
74
79
|
debug("occupancy-timeseries", "Presence query failed:", error);
|
|
80
|
+
if (error instanceof ApiError && error.statusCode >= 400) {
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
75
83
|
presenceData.warning =
|
|
76
84
|
"Failed to retrieve presence timeseries data. Results may be incomplete.";
|
|
77
85
|
}
|
|
@@ -94,12 +102,15 @@ export async function executeGetOccupancyTimeseries(args) {
|
|
|
94
102
|
}
|
|
95
103
|
catch (error) {
|
|
96
104
|
debug("occupancy-timeseries", "Traffic query failed:", error);
|
|
105
|
+
if (error instanceof ApiError && error.statusCode >= 400) {
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
97
108
|
trafficData.warning =
|
|
98
109
|
"Failed to retrieve traffic timeseries data. Results may be incomplete.";
|
|
99
110
|
}
|
|
100
111
|
}
|
|
101
112
|
// Recommendation checks data success, not just sensor count
|
|
102
|
-
const recommendation = buildRecommendation(presenceData, trafficData, presenceData.timeseries.length > 0, trafficData.timeseries.length > 0);
|
|
113
|
+
const recommendation = buildRecommendation(presenceData, trafficData, presenceData.timeseries.length > 0, trafficData.timeseries.length > 0, { assetType: asset.assetType, windowLabel: "the requested time range" });
|
|
103
114
|
const assetEntry = {
|
|
104
115
|
asset_id: assetId,
|
|
105
116
|
asset_type: asset.assetType,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"butlr-get-occupancy-timeseries.js","sourceRoot":"","sources":["../../src/tools/butlr-get-occupancy-timeseries.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"butlr-get-occupancy-timeseries.js","sourceRoot":"","sources":["../../src/tools/butlr-get-occupancy-timeseries.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +1,49 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { type TaggedEntityRef } from "../clients/queries/tags.js";
|
|
3
4
|
export declare const ListTagsArgsSchema: z.ZodObject<{
|
|
4
5
|
name_contains: z.ZodOptional<z.ZodString>;
|
|
5
6
|
min_usage: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
include_entities: z.ZodDefault<z.ZodBoolean>;
|
|
6
8
|
}, "strict", z.ZodTypeAny, {
|
|
9
|
+
include_entities: boolean;
|
|
7
10
|
name_contains?: string | undefined;
|
|
8
11
|
min_usage?: number | undefined;
|
|
9
12
|
}, {
|
|
10
13
|
name_contains?: string | undefined;
|
|
11
14
|
min_usage?: number | undefined;
|
|
15
|
+
include_entities?: boolean | undefined;
|
|
12
16
|
}>;
|
|
13
17
|
export type ListTagsArgs = z.output<typeof ListTagsArgsSchema>;
|
|
14
18
|
export interface TagFootprint {
|
|
15
|
-
rooms: number;
|
|
16
|
-
zones: number;
|
|
17
|
-
floors: number;
|
|
19
|
+
readonly rooms: number;
|
|
20
|
+
readonly zones: number;
|
|
21
|
+
readonly floors: number;
|
|
22
|
+
}
|
|
23
|
+
export interface TaggedEntities {
|
|
24
|
+
readonly rooms: ReadonlyArray<TaggedEntityRef>;
|
|
25
|
+
readonly zones: ReadonlyArray<TaggedEntityRef>;
|
|
26
|
+
readonly floors: ReadonlyArray<TaggedEntityRef>;
|
|
18
27
|
}
|
|
19
28
|
export interface TagSummary {
|
|
20
|
-
id: string;
|
|
21
|
-
name: string;
|
|
22
|
-
applied_to: TagFootprint;
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly applied_to: TagFootprint;
|
|
32
|
+
readonly applied_to_entities?: TaggedEntities;
|
|
23
33
|
}
|
|
24
34
|
export interface ListTagsResponse {
|
|
25
|
-
tags: TagSummary
|
|
26
|
-
total: number;
|
|
27
|
-
timestamp: string;
|
|
28
|
-
filtered_by?: Record<string, unknown>;
|
|
35
|
+
readonly tags: ReadonlyArray<TagSummary>;
|
|
36
|
+
readonly total: number;
|
|
37
|
+
readonly timestamp: string;
|
|
38
|
+
readonly filtered_by?: Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Set when upstream returned tag rows missing a usable id/name
|
|
41
|
+
* (`malformed_tag_rows` analogue). Counts and entities reflect the
|
|
42
|
+
* surviving valid rows; this field tells the caller how many were
|
|
43
|
+
* dropped so they can surface or escalate the upstream contract
|
|
44
|
+
* violation rather than misread it as "tag deleted".
|
|
45
|
+
*/
|
|
46
|
+
readonly warning?: string;
|
|
29
47
|
}
|
|
30
48
|
export declare function executeListTags(args: ListTagsArgs): Promise<ListTagsResponse>;
|
|
31
49
|
export declare function registerListTags(server: McpServer): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"butlr-list-tags.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-list-tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"butlr-list-tags.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-list-tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AAgCpC,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EAAwC,CAAC;AAExE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AA0B/D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC;IAClC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,cAAc,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAMD,wBAAsB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAyGnF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsBxD"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { apolloClient } from "../clients/graphql-client.js";
|
|
3
|
-
import { GET_TAGS_WITH_USAGE } from "../clients/queries/tags.js";
|
|
3
|
+
import { GET_TAGS_WITH_USAGE, } from "../clients/queries/tags.js";
|
|
4
4
|
import { rethrowIfGraphQLError, throwIfGraphQLErrors } from "../utils/graphql-helpers.js";
|
|
5
|
-
import {
|
|
5
|
+
import { projectValidRefs } from "../utils/tag-resolver.js";
|
|
6
|
+
import { withToolErrorHandling, throwInternalError } from "../errors/mcp-errors.js";
|
|
6
7
|
import { debug } from "../utils/debug.js";
|
|
7
8
|
const listTagsInputShape = {
|
|
8
9
|
name_contains: z
|
|
@@ -18,6 +19,10 @@ const listTagsInputShape = {
|
|
|
18
19
|
.max(100000)
|
|
19
20
|
.optional()
|
|
20
21
|
.describe("Exclude tags whose total application count (rooms + zones + floors) is below this threshold"),
|
|
22
|
+
include_entities: z
|
|
23
|
+
.boolean()
|
|
24
|
+
.default(false)
|
|
25
|
+
.describe("When true, each tag's response includes `applied_to_entities` with the id and name of every valid tagged room, zone, and floor (not just counts). Refs without a usable id (deleted entities whose tag link survived; partial GraphQL responses) are dropped silently — `applied_to.{rooms,zones,floors}` counts are derived from the SAME filtered list so they cannot disagree. Default false to keep the response token-light; set true when you need to know exactly which entities are tagged without follow-up calls."),
|
|
21
26
|
};
|
|
22
27
|
export const ListTagsArgsSchema = z.object(listTagsInputShape).strict();
|
|
23
28
|
const LIST_TAGS_DESCRIPTION = "List every tag in the organization, with the footprint (count of rooms, zones, and floors each tag is applied to). Tags are org-scoped labels — the same tag can be attached to any mix of rooms, zones, and floors. Use this tool first to discover what tags exist and which entity types they apply to before calling tag-filtered queries.\n\n" +
|
|
@@ -29,17 +34,19 @@ const LIST_TAGS_DESCRIPTION = "List every tag in the organization, with the foot
|
|
|
29
34
|
'1. "What tags are used in this org?" → list everything\n' +
|
|
30
35
|
'2. "Show me video-conferencing tags" → name_contains: "videoconf"\n' +
|
|
31
36
|
'3. "Which tags are actually in use?" → min_usage: 1\n' +
|
|
32
|
-
'4. "Find tags applied to many zones" → list, then look at applied_to.zones\n
|
|
37
|
+
'4. "Find tags applied to many zones" → list, then look at applied_to.zones\n' +
|
|
38
|
+
'5. "What rooms and zones are tagged \'huddle\'?" → name_contains: "huddle", include_entities: true\n\n' +
|
|
33
39
|
"When to Use:\n" +
|
|
34
40
|
"- Before any tag-based filter, to map a human term (e.g. 'videoconf') to the right tag id and entity level\n" +
|
|
35
41
|
"- To understand whether a tag lives on rooms, zones, floors, or several levels at once\n" +
|
|
36
|
-
"- To audit tagging hygiene (unused tags, single-level tags, etc.)\n
|
|
42
|
+
"- To audit tagging hygiene (unused tags, single-level tags, etc.)\n" +
|
|
43
|
+
"- With include_entities=true, to enumerate every tagged entity in one call (avoids per-tag follow-up to butlr_get_asset_details)\n\n" +
|
|
37
44
|
"When NOT to Use:\n" +
|
|
38
|
-
"- You
|
|
39
|
-
"- You
|
|
40
|
-
"Response Shape: { tags: [{ id, name, applied_to: { rooms, zones, floors } }], total, timestamp }. Tags are sorted by total usage descending
|
|
41
|
-
"Note on coverage: spot-level tags exist in the data model but are not yet exposed by this tool — applied_to
|
|
42
|
-
"See Also: butlr_available_rooms (uses tag
|
|
45
|
+
"- You want full topology browsing — use butlr_list_topology (supports tag_names filter for tagged-only views)\n" +
|
|
46
|
+
"- You only need available rooms by tag — use butlr_available_rooms\n\n" +
|
|
47
|
+
"Response Shape: { tags: [{ id, name, applied_to: { rooms: number, zones: number, floors: number }, applied_to_entities?: { rooms: [{id, name?}], zones: [{id, name?}], floors: [{id, name?}] } }], total, timestamp }. Tags are sorted by total usage descending. `applied_to_entities` is present only when include_entities=true; the inner `name` is best-effort (omitted when upstream returns no name for the tagged entity).\n\n" +
|
|
48
|
+
"Note on coverage: spot-level tags exist in the data model but are not yet exposed by this tool — applied_to and applied_to_entities cover rooms, zones, and floors only.\n\n" +
|
|
49
|
+
"See Also: butlr_list_topology (tag_names filter for tagged subtrees), butlr_available_rooms (uses tag names from this tool), butlr_search_assets";
|
|
43
50
|
function totalUsage(t) {
|
|
44
51
|
return t.applied_to.rooms + t.applied_to.zones + t.applied_to.floors;
|
|
45
52
|
}
|
|
@@ -52,21 +59,60 @@ export async function executeListTags(args) {
|
|
|
52
59
|
fetchPolicy: "network-only",
|
|
53
60
|
});
|
|
54
61
|
throwIfGraphQLErrors(result);
|
|
55
|
-
|
|
62
|
+
// Distinguish "empty array" (legitimate — org has no tags) from
|
|
63
|
+
// "null" (upstream contract violation — the schema should send `[]`
|
|
64
|
+
// when empty, never `null`). Treating `null` as legitimate-empty
|
|
65
|
+
// would silently launder a serialisation regression. `undefined`
|
|
66
|
+
// (field omitted entirely) is similarly treated as a contract
|
|
67
|
+
// violation; only an explicit array survives.
|
|
68
|
+
const tags = result.data?.tags;
|
|
69
|
+
if (!Array.isArray(tags)) {
|
|
70
|
+
throwInternalError("Unexpected response shape from tags query (expected array, got " +
|
|
71
|
+
`${tags === null ? "null" : typeof tags}). Please retry; if persistent, the upstream API contract may have changed.`);
|
|
72
|
+
}
|
|
73
|
+
rawTags = tags;
|
|
56
74
|
}
|
|
57
75
|
catch (error) {
|
|
58
76
|
rethrowIfGraphQLError(error);
|
|
59
77
|
throw error;
|
|
60
78
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
// Validate each row at the boundary. Mirrors the contract that
|
|
80
|
+
// `resolveTagNames` enforces on the topology path: any row missing a
|
|
81
|
+
// usable id/name is dropped, and the dropped count is surfaced as a
|
|
82
|
+
// `malformed_tag_rows` diagnostic. Without this, the name_contains
|
|
83
|
+
// filter below would call `.toLowerCase()` on a non-string and crash
|
|
84
|
+
// with a raw TypeError outside the MCP error translator.
|
|
85
|
+
const isValidRow = (t) => typeof t?.id === "string" &&
|
|
86
|
+
t.id.trim().length > 0 &&
|
|
87
|
+
typeof t?.name === "string" &&
|
|
88
|
+
t.name.trim().length > 0;
|
|
89
|
+
const validTagRows = rawTags.filter(isValidRow);
|
|
90
|
+
const malformedTagRowCount = rawTags.length - validTagRows.length;
|
|
91
|
+
// `projectValidRefs` filters out refs without a usable id (dangling
|
|
92
|
+
// associations after a hard delete, or partial GraphQL responses).
|
|
93
|
+
// Counts and the optional entity array are computed off the same
|
|
94
|
+
// filtered list so they cannot disagree within a single response. The
|
|
95
|
+
// helper is shared with `butlr_list_topology` so the validity predicate
|
|
96
|
+
// lives in one place — if the rule ever tightens, both tools update
|
|
97
|
+
// together.
|
|
98
|
+
let tags = validTagRows.map((t) => {
|
|
99
|
+
const rooms = projectValidRefs(t.rooms);
|
|
100
|
+
const zones = projectValidRefs(t.zones);
|
|
101
|
+
const floors = projectValidRefs(t.floors);
|
|
102
|
+
const applied_to = {
|
|
103
|
+
rooms: rooms.length,
|
|
104
|
+
zones: zones.length,
|
|
105
|
+
floors: floors.length,
|
|
106
|
+
};
|
|
107
|
+
return args.include_entities
|
|
108
|
+
? {
|
|
109
|
+
id: t.id,
|
|
110
|
+
name: t.name,
|
|
111
|
+
applied_to,
|
|
112
|
+
applied_to_entities: { rooms, zones, floors },
|
|
113
|
+
}
|
|
114
|
+
: { id: t.id, name: t.name, applied_to };
|
|
115
|
+
});
|
|
70
116
|
if (args.name_contains) {
|
|
71
117
|
const needle = args.name_contains.toLowerCase();
|
|
72
118
|
tags = tags.filter((t) => t.name.toLowerCase().includes(needle));
|
|
@@ -76,15 +122,26 @@ export async function executeListTags(args) {
|
|
|
76
122
|
tags = tags.filter((t) => totalUsage(t) >= threshold);
|
|
77
123
|
}
|
|
78
124
|
tags.sort((a, b) => totalUsage(b) - totalUsage(a));
|
|
79
|
-
|
|
125
|
+
// Surface the args used to filter, but only when at least one filter was
|
|
126
|
+
// actually supplied. `include_entities` defaults to false at the schema
|
|
127
|
+
// layer so it's always set on `args`; treat the all-defaults case as
|
|
128
|
+
// "no filter applied".
|
|
129
|
+
const { include_entities, ...rest } = args;
|
|
130
|
+
const explicitFilters = { ...rest };
|
|
131
|
+
if (include_entities === true)
|
|
132
|
+
explicitFilters.include_entities = true;
|
|
133
|
+
const hasFilters = Object.keys(explicitFilters).length > 0;
|
|
134
|
+
const warning = malformedTagRowCount > 0
|
|
135
|
+
? `${malformedTagRowCount} tag row(s) skipped — upstream returned entries ` +
|
|
136
|
+
"with missing or empty id/name fields. If unexpected, contact support."
|
|
137
|
+
: undefined;
|
|
138
|
+
return {
|
|
80
139
|
tags,
|
|
81
140
|
total: tags.length,
|
|
82
141
|
timestamp: new Date().toISOString(),
|
|
142
|
+
...(hasFilters ? { filtered_by: explicitFilters } : {}),
|
|
143
|
+
...(warning !== undefined ? { warning } : {}),
|
|
83
144
|
};
|
|
84
|
-
if (Object.keys(args).length > 0) {
|
|
85
|
-
response.filtered_by = args;
|
|
86
|
-
}
|
|
87
|
-
return response;
|
|
88
145
|
}
|
|
89
146
|
export function registerListTags(server) {
|
|
90
147
|
server.registerTool("butlr_list_tags", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"butlr-list-tags.js","sourceRoot":"","sources":["../../src/tools/butlr-list-tags.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,
|
|
1
|
+
{"version":3,"file":"butlr-list-tags.js","sourceRoot":"","sources":["../../src/tools/butlr-list-tags.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACL,mBAAmB,GAGpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,MAAM,kBAAkB,GAAG;IACzB,aAAa,EAAE,CAAC;SACb,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,+BAA+B,CAAC;SACvC,GAAG,CAAC,GAAG,EAAE,yCAAyC,CAAC;SACnD,QAAQ,EAAE;SACV,QAAQ,CAAC,+CAA+C,CAAC;IAE5D,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,8BAA8B,CAAC;SACnC,GAAG,CAAC,CAAC,EAAE,wBAAwB,CAAC;SAChC,GAAG,CAAC,MAAM,CAAC;SACX,QAAQ,EAAE;SACV,QAAQ,CACP,6FAA6F,CAC9F;IAEH,gBAAgB,EAAE,CAAC;SAChB,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CACP,6fAA6f,CAC9f;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,MAAM,EAAE,CAAC;AAIxE,MAAM,qBAAqB,GACzB,oVAAoV;IACpV,kBAAkB;IAClB,0FAA0F;IAC1F,oGAAoG;IACpG,yEAAyE;IACzE,oBAAoB;IACpB,0DAA0D;IAC1D,qEAAqE;IACrE,uDAAuD;IACvD,8EAA8E;IAC9E,wGAAwG;IACxG,gBAAgB;IAChB,8GAA8G;IAC9G,0FAA0F;IAC1F,qEAAqE;IACrE,sIAAsI;IACtI,oBAAoB;IACpB,iHAAiH;IACjH,wEAAwE;IACxE,waAAwa;IACxa,8KAA8K;IAC9K,kJAAkJ,CAAC;AAoCrJ,SAAS,UAAU,CAAC,CAAa;IAC/B,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAkB;IACtD,KAAK,CAAC,WAAW,EAAE,yBAAyB,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpE,IAAI,OAAO,GAAsB,EAAE,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAqC;YAC1E,KAAK,EAAE,mBAAmB;YAC1B,WAAW,EAAE,cAAc;SAC5B,CAAC,CAAC;QAEH,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC7B,gEAAgE;QAChE,oEAAoE;QACpE,iEAAiE;QACjE,iEAAiE;QACjE,8DAA8D;QAC9D,8CAA8C;QAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,kBAAkB,CAChB,iEAAiE;gBAC/D,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,6EAA6E,CACvH,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,KAAK,CAAC;IACd,CAAC;IAED,+DAA+D;IAC/D,qEAAqE;IACrE,oEAAoE;IACpE,mEAAmE;IACnE,qEAAqE;IACrE,yDAAyD;IACzD,MAAM,UAAU,GAAG,CAAC,CAAkB,EAAW,EAAE,CACjD,OAAO,CAAC,EAAE,EAAE,KAAK,QAAQ;QACzB,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QACtB,OAAO,CAAC,EAAE,IAAI,KAAK,QAAQ;QAC3B,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,oBAAoB,GAAG,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;IAElE,oEAAoE;IACpE,mEAAmE;IACnE,iEAAiE;IACjE,sEAAsE;IACtE,wEAAwE;IACxE,oEAAoE;IACpE,YAAY;IACZ,IAAI,IAAI,GAAiB,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC9C,MAAM,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAiB;YAC/B,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC;QACF,OAAO,IAAI,CAAC,gBAAgB;YAC1B,CAAC,CAAC;gBACE,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,UAAU;gBACV,mBAAmB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE;aAC9C;YACH,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAEnD,yEAAyE;IACzE,wEAAwE;IACxE,qEAAqE;IACrE,uBAAuB;IACvB,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAC3C,MAAM,eAAe,GAA4B,EAAE,GAAG,IAAI,EAAE,CAAC;IAC7D,IAAI,gBAAgB,KAAK,IAAI;QAAE,eAAe,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACvE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAE3D,MAAM,OAAO,GACX,oBAAoB,GAAG,CAAC;QACtB,CAAC,CAAC,GAAG,oBAAoB,kDAAkD;YACzE,uEAAuE;QACzE,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,IAAI;QACJ,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,qBAAqB;QAClC,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACnC,MAAM,SAAS,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;QAChD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -5,20 +5,26 @@ export declare const ListTopologyArgsSchema: z.ZodObject<{
|
|
|
5
5
|
asset_ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
6
6
|
starting_depth: z.ZodDefault<z.ZodNumber>;
|
|
7
7
|
traversal_depth: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
tag_names: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
9
|
+
tag_match: z.ZodDefault<z.ZodEnum<["all", "any"]>>;
|
|
8
10
|
}, "strict", z.ZodTypeAny, {
|
|
11
|
+
tag_match: "all" | "any";
|
|
9
12
|
starting_depth: number;
|
|
10
13
|
traversal_depth: number;
|
|
11
14
|
asset_ids?: string[] | undefined;
|
|
15
|
+
tag_names?: string[] | undefined;
|
|
12
16
|
}, {
|
|
17
|
+
tag_match?: "all" | "any" | undefined;
|
|
13
18
|
asset_ids?: string[] | undefined;
|
|
14
19
|
starting_depth?: number | undefined;
|
|
15
20
|
traversal_depth?: number | undefined;
|
|
21
|
+
tag_names?: string[] | undefined;
|
|
16
22
|
}>;
|
|
17
23
|
type ListTopologyArgs = z.output<typeof ListTopologyArgsSchema>;
|
|
18
24
|
/**
|
|
19
25
|
* Execute butlr_list_topology tool
|
|
20
26
|
*/
|
|
21
|
-
export declare function executeListTopology(args
|
|
27
|
+
export declare function executeListTopology(args: ListTopologyArgs): Promise<ListTopologyResponse>;
|
|
22
28
|
/**
|
|
23
29
|
* Register butlr_list_topology with an McpServer instance
|
|
24
30
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"butlr-list-topology.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-list-topology.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"butlr-list-topology.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-list-topology.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAoBzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,OAAO,KAAK,EAAE,oBAAoB,EAAsB,MAAM,uBAAuB,CAAC;AAoEtF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;EAA4C,CAAC;AAEhF,KAAK,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAyMhE;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAuf/F;AAmVD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB5D"}
|