rhombus-node-mcp 0.1.13 → 0.1.16
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/README.md +11 -3
- package/dist/api/camera-tool-api.js +108 -0
- package/dist/api/clips-tool-api.js +36 -0
- package/dist/api/create-camera-policy-tool-api.js +9 -0
- package/dist/api/create-tool-api.js +53 -0
- package/dist/api/entity-lookup-tool-api.js +37 -0
- package/dist/api/events-tool-api.js +320 -0
- package/dist/api/faces-tool-api.js +110 -0
- package/dist/api/get-entity-tool-api.js +176 -0
- package/dist/api/get-org-information-tool-api.js +9 -0
- package/dist/api/location-tool-api.js +9 -0
- package/dist/api/lpr-tool-api.js +68 -0
- package/dist/api/policy-alerts-tool-api.js +42 -0
- package/dist/api/reboot-cameras-tool-api.js +34 -0
- package/dist/api/report-tool-api.js +426 -0
- package/dist/api/time-tool-api.js +90 -0
- package/dist/api/update-tool-api.js +148 -0
- package/dist/createServer.js +50 -0
- package/dist/disabled-tools/endpoint-to-keys-tool.js +84 -0
- package/dist/disabled-tools/semantic-search-tool.js +90 -0
- package/dist/index.js +25 -32
- package/dist/logger.js +5 -4
- package/dist/network.js +45 -14
- package/dist/resources/routes.json.js +1 -1
- package/dist/services/embedding-service.js +153 -0
- package/dist/services/faiss-search-service.js +261 -0
- package/dist/tools/camera-tool.js +100 -0
- package/dist/tools/clips-tool.js +23 -38
- package/dist/tools/count-tool.js +25 -0
- package/dist/tools/create-camera-policy-tool.js +214 -0
- package/dist/tools/create-tool.js +25 -75
- package/dist/tools/entity-lookup-tool.js +35 -0
- package/dist/tools/events-tool.js +188 -93
- package/dist/tools/faces-tool.js +59 -133
- package/dist/tools/get-entity-tool.js +78 -0
- package/dist/tools/get-org-information-tool.js +18 -0
- package/dist/tools/location-tool.js +24 -32
- package/dist/tools/lpr-tool.js +71 -0
- package/dist/tools/policy-alerts-tool.js +32 -43
- package/dist/tools/reboot-cameras-tool.js +34 -0
- package/dist/tools/report-tool.js +190 -0
- package/dist/tools/time-conversion-tool.js +43 -0
- package/dist/tools/time-tool.js +17 -55
- package/dist/tools/update-tool.js +262 -0
- package/dist/transports/stdio.js +10 -0
- package/dist/transports/streamable-http.js +201 -0
- package/dist/{tools/devices/camera-tool/types.js → types/camera-tool-types.js} +13 -0
- package/dist/types/clips-tool-types.js +41 -0
- package/dist/types/create-camera-policy-tool-types.js +44 -0
- package/dist/types/create-tool-types.js +8 -0
- package/dist/types/deviceType.js +1 -0
- package/dist/types/endpoint-to-keys-tool-types.js +7 -0
- package/dist/types/entity-lookup-tool-types.js +70 -0
- package/dist/types/events-tools-types.js +257 -0
- package/dist/types/faces-tools-types.js +143 -0
- package/dist/types/get-entity-tool-types.js +25 -0
- package/dist/types/get-org-information-tool-types.js +3 -0
- package/dist/types/location-tool-types.js +11 -0
- package/dist/types/lpr-tool-types.js +97 -0
- package/dist/types/policy-alerts-tool-types.js +74 -0
- package/dist/types/reboot-cameras-tool-types.js +8 -0
- package/dist/types/report-tool-types.js +268 -0
- package/dist/types/schema-components.js +7093 -0
- package/dist/types/schema.js +1 -0
- package/dist/types/semantic-search-tool-types.js +5 -0
- package/dist/types/time-conversion-tool-types.js +8 -0
- package/dist/types/time-tool-types.js +11 -0
- package/dist/types/update-tool-types.js +186 -0
- package/dist/types/zod-schemas.js +21315 -0
- package/dist/types.js +17 -7
- package/dist/util.js +96 -14
- package/dist/utils/confirmation.js +1 -7
- package/dist/utils/reduce-output.js +35 -0
- package/dist/utils/remove-nulls.js +28 -0
- package/dist/utils/temp.js +8 -0
- package/dist/utils/timestampInput.js +12 -0
- package/package.json +28 -3
- package/dist/tools/devices/camera-tool/camera-tool.js +0 -218
- package/dist/tools/devices/get-entity-tool.js +0 -117
- package/dist/tools/get-org-information.js +0 -18
- package/dist/tools/reboot-cameras.js +0 -63
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { schemas } from "./zod-schemas.js";
|
|
3
|
+
import { createEpochSchema, ISOTimestampFormatDescription } from "../utils/timestampInput.js";
|
|
4
|
+
export const TOOL_ARGS = {
|
|
5
|
+
queryType: z
|
|
6
|
+
.enum(["existing", "expiringSoon"])
|
|
7
|
+
.describe('The type of policy alerts to retrieve. Use "existing" to get current policy alerts, and "expiringSoon" to get policy alerts that are nearing their expiration date.'),
|
|
8
|
+
afterTimestampISO: z
|
|
9
|
+
.string()
|
|
10
|
+
.datetime({ message: "Invalid ISO 8601 date format.", offset: true })
|
|
11
|
+
.nullable()
|
|
12
|
+
.describe("The start of the time range for which to retrieve alerts. Only alerts that occurred AFTER this timestamp will be returned." +
|
|
13
|
+
ISOTimestampFormatDescription),
|
|
14
|
+
beforeTimestampISO: z
|
|
15
|
+
.string()
|
|
16
|
+
.datetime({ message: "Invalid ISO 8601 date format.", offset: true })
|
|
17
|
+
.nullable()
|
|
18
|
+
.describe("The end of the time range for which to retrieve alerts. Only alerts that occurred BEFORE this timestamp will be returned." +
|
|
19
|
+
ISOTimestampFormatDescription),
|
|
20
|
+
deviceFilter: z
|
|
21
|
+
.array(z.string())
|
|
22
|
+
.nullable()
|
|
23
|
+
.describe("A list of UUIDs representing the specific devices to filter alerts by. Only alerts emitted by these devices will be returned. Please truncate any facets, such as .v0"),
|
|
24
|
+
locationFilter: z
|
|
25
|
+
.array(z.string())
|
|
26
|
+
.nullable()
|
|
27
|
+
.describe("A list of UUIDs representing the specific locations to filter alerts by. Only alerts associated with these locations will be returned. Please truncate any facets, such as .v0"),
|
|
28
|
+
maxResults: z
|
|
29
|
+
.number()
|
|
30
|
+
.nullable()
|
|
31
|
+
.describe("The maximum number of policy alerts to return. The system may default to a reasonable number (e.g., 20) if not specified, but there is a hard cap (e.g., 100) on the maximum results the API will return."),
|
|
32
|
+
timeZone: z
|
|
33
|
+
.string()
|
|
34
|
+
.describe("The timezone from the location of the camera of the policy alert, for formatting timestamps. This is necessary for the tool to produce accurate formatted timestamps."),
|
|
35
|
+
};
|
|
36
|
+
const TOOL_ARGS_SCHEMA = z.object(TOOL_ARGS);
|
|
37
|
+
export const ApiPayloadSchema = TOOL_ARGS_SCHEMA.transform(args => {
|
|
38
|
+
const { queryType, afterTimestampISO, beforeTimestampISO, timeZone, ...rest } = args;
|
|
39
|
+
const afterTimestampMs = createEpochSchema().parse(afterTimestampISO);
|
|
40
|
+
const beforeTimestampMs = createEpochSchema().parse(beforeTimestampISO);
|
|
41
|
+
return {
|
|
42
|
+
...rest,
|
|
43
|
+
afterTimestampMs,
|
|
44
|
+
beforeTimestampMs,
|
|
45
|
+
timeZone,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
// Extend both possible alert types with the createdOnString field
|
|
49
|
+
// Use passthrough to allow any additional fields that might be in the response
|
|
50
|
+
const ExtendedPolicyAlertV2Type = schemas.PolicyAlertV2Type.extend({
|
|
51
|
+
createdOnString: z
|
|
52
|
+
.string()
|
|
53
|
+
.optional()
|
|
54
|
+
.describe("Human-readable formatted timestamp (e.g., 'January 24, 2025 at 5:32 PM')"),
|
|
55
|
+
}).passthrough();
|
|
56
|
+
const ExtendedAccessControlledDoorPolicyAlertType = schemas.AccessControlledDoorPolicyAlertType.extend({
|
|
57
|
+
createdOnString: z
|
|
58
|
+
.string()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe("Human-readable formatted timestamp (e.g., 'January 24, 2025 at 5:32 PM')"),
|
|
61
|
+
}).passthrough();
|
|
62
|
+
// Create a union type that accepts either type of policy alert
|
|
63
|
+
const ExtendedPolicyAlertType = z.union([
|
|
64
|
+
ExtendedPolicyAlertV2Type,
|
|
65
|
+
ExtendedAccessControlledDoorPolicyAlertType,
|
|
66
|
+
]);
|
|
67
|
+
// Create a new schema that matches what we actually return
|
|
68
|
+
export const OUTPUT_SCHEMA = z
|
|
69
|
+
.object({
|
|
70
|
+
error: z.boolean().optional(),
|
|
71
|
+
errorMsg: z.string().optional(),
|
|
72
|
+
policyAlerts: z.array(ExtendedPolicyAlertType).optional().default([]),
|
|
73
|
+
})
|
|
74
|
+
.passthrough();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { addConfirmationParams } from "../utils/confirmation.js";
|
|
3
|
+
export const TOOL_ARGS = addConfirmationParams({
|
|
4
|
+
cameraUuids: z
|
|
5
|
+
.array(z.string())
|
|
6
|
+
.describe("An array of camera UUID strings which are unique identifiers for cameras"),
|
|
7
|
+
});
|
|
8
|
+
const TOOL_ARGS_SCHEMA = z.object(TOOL_ARGS);
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ISOTimestampFormatDescription } from "../utils/timestampInput.js";
|
|
3
|
+
export var RequestType;
|
|
4
|
+
(function (RequestType) {
|
|
5
|
+
RequestType["GET_SUMMARY_COUNT_REPORT"] = "get-summary-count-report";
|
|
6
|
+
RequestType["GET_OCCUPANCY_COUNT_REPORT"] = "get-occupancy-count-report";
|
|
7
|
+
RequestType["GET_OCCUPANCY_ENABLED_CAMERAS"] = "get-occupancy-enabled-cameras";
|
|
8
|
+
RequestType["GET_LINE_CROSSING_ENABLED_CAMERAS"] = "get-line-crossing-enabled-cameras";
|
|
9
|
+
RequestType["GET_THRESHOLD_CROSSING_COUNT_REPORT"] = "get-threshold-crossing-count-report";
|
|
10
|
+
RequestType["FIND_PROMPT_CONFIGURATIONS"] = "find-prompt-configurations";
|
|
11
|
+
RequestType["GET_CUSTOM_LLM_REPORT"] = "get-custom-llm-report";
|
|
12
|
+
})(RequestType || (RequestType = {}));
|
|
13
|
+
export const TOOL_ARGS = z.object({
|
|
14
|
+
requestType: z.enum([
|
|
15
|
+
RequestType.GET_SUMMARY_COUNT_REPORT,
|
|
16
|
+
RequestType.GET_OCCUPANCY_COUNT_REPORT,
|
|
17
|
+
RequestType.GET_OCCUPANCY_ENABLED_CAMERAS,
|
|
18
|
+
RequestType.GET_LINE_CROSSING_ENABLED_CAMERAS,
|
|
19
|
+
RequestType.GET_THRESHOLD_CROSSING_COUNT_REPORT,
|
|
20
|
+
RequestType.FIND_PROMPT_CONFIGURATIONS,
|
|
21
|
+
RequestType.GET_CUSTOM_LLM_REPORT,
|
|
22
|
+
]),
|
|
23
|
+
occupancyCountRequest: z.object({
|
|
24
|
+
deviceUuid: z.string().describe("The uuid of the device to get occupancy count for"),
|
|
25
|
+
rangeStart: z
|
|
26
|
+
.string()
|
|
27
|
+
.datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true })
|
|
28
|
+
.describe("The start of the time range (inclusive) for the report period." +
|
|
29
|
+
ISOTimestampFormatDescription),
|
|
30
|
+
rangeEnd: z
|
|
31
|
+
.string()
|
|
32
|
+
.datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true })
|
|
33
|
+
.describe("The end of the time range (inclusive) for the report period." +
|
|
34
|
+
ISOTimestampFormatDescription),
|
|
35
|
+
interval: z
|
|
36
|
+
.enum(["MINUTELY", "HOURLY", "DAILY", "WEEKLY", "MONTHLY", "YEARLY"])
|
|
37
|
+
.describe("The time interval for the report aggregation"),
|
|
38
|
+
}),
|
|
39
|
+
summaryCountRequest: z.object({
|
|
40
|
+
interval: z
|
|
41
|
+
.enum(["MINUTELY", "HOURLY", "DAILY", "WEEKLY", "MONTHLY", "YEARLY"])
|
|
42
|
+
.describe("The time interval for the report aggregation"),
|
|
43
|
+
uuid: z
|
|
44
|
+
.nullable(z.string())
|
|
45
|
+
.describe("The uuid of the device, or location, or organization depending on what scope is. If scope is DEVICE, this is the device uuid. If scope is LOCATION, this is the location uuid. If scope is ORG, this is the organization uuid. This UUID is *always* 22 characters long"),
|
|
46
|
+
scope: z
|
|
47
|
+
.enum(["REGION", "LOCATION", "DEVICE", "ORG"])
|
|
48
|
+
.describe("The scope level for the report data"),
|
|
49
|
+
types: z
|
|
50
|
+
.array(z.enum([
|
|
51
|
+
"CROWD",
|
|
52
|
+
"PEOPLE",
|
|
53
|
+
"FACES",
|
|
54
|
+
"MOTION",
|
|
55
|
+
"BANDWIDTH",
|
|
56
|
+
"VEHICLES",
|
|
57
|
+
"LICENSEPLATES",
|
|
58
|
+
"ALERTS",
|
|
59
|
+
"AM_VERIFICATION",
|
|
60
|
+
"DWELL",
|
|
61
|
+
]))
|
|
62
|
+
.describe("The types of data to include in the summary count report"),
|
|
63
|
+
rangeStart: z
|
|
64
|
+
.string()
|
|
65
|
+
.datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true })
|
|
66
|
+
.describe("The start of the time range (inclusive) for the report period." +
|
|
67
|
+
ISOTimestampFormatDescription),
|
|
68
|
+
rangeEnd: z
|
|
69
|
+
.string()
|
|
70
|
+
.datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true })
|
|
71
|
+
.describe("The end of the time range (inclusive) for the report period." +
|
|
72
|
+
ISOTimestampFormatDescription),
|
|
73
|
+
timeZone: z.string()
|
|
74
|
+
.describe(`The timezone of the requested locations or devices. This is necessary for the tool to produce
|
|
75
|
+
accurate UTC dates for the returned data.`),
|
|
76
|
+
}),
|
|
77
|
+
occupancyEnabledCamerasRequest: z
|
|
78
|
+
.object({})
|
|
79
|
+
.describe("Request to get list of occupancy enabled cameras"),
|
|
80
|
+
lineCrossingEnabledCamerasRequest: z.object({
|
|
81
|
+
locationUuid: z
|
|
82
|
+
.string()
|
|
83
|
+
.describe("The uuid of the location to get line crossing enabled cameras for"),
|
|
84
|
+
}),
|
|
85
|
+
thresholdCrossingCountRequest: z.object({
|
|
86
|
+
deviceUuid: z.string().describe("The uuid of the device to get threshold crossing count for"),
|
|
87
|
+
rangeStart: z
|
|
88
|
+
.string()
|
|
89
|
+
.datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true })
|
|
90
|
+
.describe("The start of the time range (inclusive) for the report period." +
|
|
91
|
+
ISOTimestampFormatDescription),
|
|
92
|
+
rangeEnd: z
|
|
93
|
+
.string()
|
|
94
|
+
.datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true })
|
|
95
|
+
.describe("The end of the time range (inclusive) for the report period." +
|
|
96
|
+
ISOTimestampFormatDescription),
|
|
97
|
+
bucketSize: z
|
|
98
|
+
.enum(["QUARTER_HOUR", "HOUR", "DAY", "WEEK"])
|
|
99
|
+
.describe("The time bucket size for aggregating crossing counts"),
|
|
100
|
+
crossingObject: z
|
|
101
|
+
.enum(["HUMAN", "VEHICLE", "UNKNOWN"])
|
|
102
|
+
.describe("The type of object crossing to report on"),
|
|
103
|
+
dedupe: z.boolean().describe("Whether to deduplicate crossing events"),
|
|
104
|
+
}),
|
|
105
|
+
findPromptConfigurationsRequest: z
|
|
106
|
+
.object({})
|
|
107
|
+
.describe("Request to find all custom event prompt configurations"),
|
|
108
|
+
customLLMReportRequest: z.object({
|
|
109
|
+
promptUuid: z.string().describe("The uuid of the prompt configuration to get counts for"),
|
|
110
|
+
promptType: z
|
|
111
|
+
.enum(["COUNT", "PERCENT", "BOOLEAN"])
|
|
112
|
+
.describe("The type of prompt configuration - determines which API endpoint to use"),
|
|
113
|
+
rangeStart: z
|
|
114
|
+
.string()
|
|
115
|
+
.datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true })
|
|
116
|
+
.describe("The start of the time range (inclusive) for the report period." +
|
|
117
|
+
ISOTimestampFormatDescription),
|
|
118
|
+
rangeEnd: z
|
|
119
|
+
.string()
|
|
120
|
+
.datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true })
|
|
121
|
+
.describe("The end of the time range (inclusive) for the report period." +
|
|
122
|
+
ISOTimestampFormatDescription),
|
|
123
|
+
interval: z
|
|
124
|
+
.enum(["MINUTELY", "QUARTERHOURLY", "HOURLY", "DAILY", "WEEKLY", "MONTHLY"])
|
|
125
|
+
.describe("The time interval for the report aggregation"),
|
|
126
|
+
}),
|
|
127
|
+
});
|
|
128
|
+
const TOOL_ARGS_SCHEMA = TOOL_ARGS;
|
|
129
|
+
export const SanitizedTimeSeriesDataPoint = z.object({
|
|
130
|
+
dateUtcString: z
|
|
131
|
+
.optional(z.string())
|
|
132
|
+
.describe("The UTC date of the data point in ISO 8601 format"),
|
|
133
|
+
eventCountMap: z.optional(z.record(z.any())),
|
|
134
|
+
});
|
|
135
|
+
export const OUTPUT_SCHEMA = z.object({
|
|
136
|
+
error: z.optional(z.boolean()),
|
|
137
|
+
errorMsg: z.optional(z.string()),
|
|
138
|
+
summaryCountReport: z.optional(z
|
|
139
|
+
.object({
|
|
140
|
+
error: z.optional(z.boolean()),
|
|
141
|
+
errorMsg: z.optional(z.string()),
|
|
142
|
+
timeSeriesDataPoints: z.optional(z.array(SanitizedTimeSeriesDataPoint)),
|
|
143
|
+
})
|
|
144
|
+
.nullable()
|
|
145
|
+
.describe("Report data for various high level organization metrics like people counts, bandwidth counts, face counts, etc.")),
|
|
146
|
+
occupancyCountReport: z
|
|
147
|
+
.optional(z.object({
|
|
148
|
+
error: z.optional(z.boolean()),
|
|
149
|
+
errorMsg: z.optional(z.string()),
|
|
150
|
+
timeSeriesDataPoints: z.optional(z.array(z.object({
|
|
151
|
+
approximateTimestampMsMap: z.optional(z.record(z.unknown())),
|
|
152
|
+
dateLocal: z.optional(z.string()),
|
|
153
|
+
dateUtc: z.optional(z.string()),
|
|
154
|
+
dateLocalString: z.optional(z.string()),
|
|
155
|
+
dateUtcString: z.optional(z.string()),
|
|
156
|
+
eventCountMap: z.optional(z.record(z.unknown())),
|
|
157
|
+
timestampMs: z.optional(z.number()),
|
|
158
|
+
}))),
|
|
159
|
+
}))
|
|
160
|
+
.nullable(),
|
|
161
|
+
occupancyEnabledCamerasReport: z
|
|
162
|
+
.optional(z.object({
|
|
163
|
+
error: z.optional(z.boolean()),
|
|
164
|
+
errorMsg: z.optional(z.string()),
|
|
165
|
+
cameras: z.optional(z.array(z.object({
|
|
166
|
+
uuid: z.optional(z.string()),
|
|
167
|
+
deviceUuid: z.optional(z.string()),
|
|
168
|
+
name: z.optional(z.string()),
|
|
169
|
+
serialNumber: z.optional(z.string()),
|
|
170
|
+
locationUuid: z.optional(z.string()),
|
|
171
|
+
facetNameMap: z.optional(z.record(z.string().nullable())),
|
|
172
|
+
deleted: z.optional(z.boolean()),
|
|
173
|
+
pending: z.optional(z.boolean()),
|
|
174
|
+
mummified: z.optional(z.boolean()),
|
|
175
|
+
}))),
|
|
176
|
+
}))
|
|
177
|
+
.nullable()
|
|
178
|
+
.describe("List of cameras that have occupancy reporting enabled"),
|
|
179
|
+
lineCrossingEnabledCamerasReport: z
|
|
180
|
+
.optional(z.object({
|
|
181
|
+
error: z.optional(z.boolean()),
|
|
182
|
+
errorMsg: z.optional(z.string()),
|
|
183
|
+
camerasToConfigs: z.optional(z.record(z.unknown())),
|
|
184
|
+
}))
|
|
185
|
+
.nullable()
|
|
186
|
+
.describe("Cameras at a location that have line crossing enabled with their configurations"),
|
|
187
|
+
thresholdCrossingCountReport: z
|
|
188
|
+
.optional(z.object({
|
|
189
|
+
error: z.optional(z.boolean()),
|
|
190
|
+
errorMsg: z.optional(z.string()),
|
|
191
|
+
crossingCounts: z.optional(z.array(z.object({
|
|
192
|
+
timestampMs: z.optional(z.number()),
|
|
193
|
+
ingressCount: z.optional(z.number()),
|
|
194
|
+
egressCount: z.optional(z.number()),
|
|
195
|
+
}))),
|
|
196
|
+
metrics: z
|
|
197
|
+
.optional(z.object({
|
|
198
|
+
averageEntriesPerHour: z
|
|
199
|
+
.number()
|
|
200
|
+
.describe("Average number of entries (ingress) per hour"),
|
|
201
|
+
averageExitsPerHour: z.number().describe("Average number of exits (egress) per hour"),
|
|
202
|
+
mostEntriesInHour: z
|
|
203
|
+
.object({
|
|
204
|
+
count: z.number().describe("Maximum number of entries in a single hour"),
|
|
205
|
+
timestamp: z.string().describe("ISO timestamp of the hour with most entries"),
|
|
206
|
+
hourLabel: z
|
|
207
|
+
.string()
|
|
208
|
+
.describe("Human-readable hour label (e.g., '2:00 PM - 3:00 PM')"),
|
|
209
|
+
})
|
|
210
|
+
.describe("Hour with the most entries"),
|
|
211
|
+
mostExitsInHour: z
|
|
212
|
+
.object({
|
|
213
|
+
count: z.number().describe("Maximum number of exits in a single hour"),
|
|
214
|
+
timestamp: z.string().describe("ISO timestamp of the hour with most exits"),
|
|
215
|
+
hourLabel: z
|
|
216
|
+
.string()
|
|
217
|
+
.describe("Human-readable hour label (e.g., '2:00 PM - 3:00 PM')"),
|
|
218
|
+
})
|
|
219
|
+
.describe("Hour with the most exits"),
|
|
220
|
+
busiestHour: z
|
|
221
|
+
.object({
|
|
222
|
+
totalCount: z.number().describe("Total entries + exits in the busiest hour"),
|
|
223
|
+
timestamp: z.string().describe("ISO timestamp of the busiest hour"),
|
|
224
|
+
hourLabel: z
|
|
225
|
+
.string()
|
|
226
|
+
.describe("Human-readable hour label (e.g., '2:00 PM - 3:00 PM')"),
|
|
227
|
+
entries: z.number().describe("Number of entries in the busiest hour"),
|
|
228
|
+
exits: z.number().describe("Number of exits in the busiest hour"),
|
|
229
|
+
})
|
|
230
|
+
.describe("Hour with the most total activity (entries + exits)"),
|
|
231
|
+
}))
|
|
232
|
+
.describe("Calculated metrics from the crossing count data"),
|
|
233
|
+
}))
|
|
234
|
+
.nullable()
|
|
235
|
+
.describe("Threshold crossing count report showing ingress and egress counts over time with calculated metrics"),
|
|
236
|
+
promptConfigurationsReport: z
|
|
237
|
+
.optional(z.object({
|
|
238
|
+
error: z.optional(z.boolean()),
|
|
239
|
+
errorMsg: z.optional(z.string()),
|
|
240
|
+
promptConfigurations: z.optional(z.array(z.object({
|
|
241
|
+
active: z.optional(z.boolean()),
|
|
242
|
+
cameraConfigurations: z.optional(z.array(z.unknown())),
|
|
243
|
+
checkCondition: z.optional(z.unknown()),
|
|
244
|
+
description: z.optional(z.string()),
|
|
245
|
+
name: z.optional(z.string()),
|
|
246
|
+
orgUuid: z.optional(z.string()),
|
|
247
|
+
prompt: z.optional(z.string()),
|
|
248
|
+
promptType: z.optional(z.enum(["COUNT", "PERCENT", "BOOLEAN"])),
|
|
249
|
+
scheduleUuid: z.optional(z.string()),
|
|
250
|
+
shortName: z.optional(z.string()),
|
|
251
|
+
uuid: z.optional(z.string()),
|
|
252
|
+
}))),
|
|
253
|
+
}))
|
|
254
|
+
.nullable()
|
|
255
|
+
.describe("List of custom event prompt configurations"),
|
|
256
|
+
customLLMReport: z
|
|
257
|
+
.optional(z.object({
|
|
258
|
+
error: z.optional(z.boolean()),
|
|
259
|
+
errorMsg: z.optional(z.string()),
|
|
260
|
+
timeSeriesDataPoints: z.optional(z.array(z.object({
|
|
261
|
+
dateLocal: z.optional(z.string()),
|
|
262
|
+
dateUtc: z.optional(z.string()),
|
|
263
|
+
eventCountMap: z.optional(z.record(z.union([z.number(), z.boolean(), z.string()]))),
|
|
264
|
+
}))),
|
|
265
|
+
}))
|
|
266
|
+
.nullable()
|
|
267
|
+
.describe("Custom LLM report showing event data over time - supports COUNT, PERCENT, and BOOLEAN prompt types"),
|
|
268
|
+
});
|