@cef-ai/cli 0.2.7 → 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/README.md +75 -1247
- package/dist/build/duration.d.ts +22 -0
- package/dist/build/duration.d.ts.map +1 -0
- package/dist/build/duration.js +44 -0
- package/dist/build/duration.js.map +1 -0
- package/dist/build/esbuild-plugin.d.ts +32 -0
- package/dist/build/esbuild-plugin.d.ts.map +1 -0
- package/dist/build/esbuild-plugin.js +53 -0
- package/dist/build/esbuild-plugin.js.map +1 -0
- package/dist/build/lints.d.ts +55 -0
- package/dist/build/lints.d.ts.map +1 -0
- package/dist/build/lints.js +214 -0
- package/dist/build/lints.js.map +1 -0
- package/dist/build/load-config.d.ts +114 -0
- package/dist/build/load-config.d.ts.map +1 -0
- package/dist/build/load-config.js +150 -0
- package/dist/build/load-config.js.map +1 -0
- package/dist/build/manifest.d.ts +156 -0
- package/dist/build/manifest.d.ts.map +1 -0
- package/dist/build/manifest.js +111 -0
- package/dist/build/manifest.js.map +1 -0
- package/dist/build/targeting.d.ts +15 -0
- package/dist/build/targeting.d.ts.map +1 -0
- package/dist/build/targeting.js +69 -0
- package/dist/build/targeting.js.map +1 -0
- package/dist/cli-program.d.ts +14 -0
- package/dist/cli-program.d.ts.map +1 -0
- package/dist/cli-program.js +171 -0
- package/dist/cli-program.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +25 -65
- package/dist/cli.js.map +1 -0
- package/dist/commands/build.d.ts +41 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +252 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/inspect.d.ts +49 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +135 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/keypair.d.ts +21 -0
- package/dist/commands/keypair.d.ts.map +1 -0
- package/dist/commands/keypair.js +91 -0
- package/dist/commands/keypair.js.map +1 -0
- package/dist/commands/publish.d.ts +40 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +187 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/typegen.d.ts +36 -0
- package/dist/commands/typegen.d.ts.map +1 -0
- package/dist/commands/typegen.js +210 -0
- package/dist/commands/typegen.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cid.d.ts +3 -0
- package/dist/lib/cid.d.ts.map +1 -0
- package/dist/lib/cid.js +43 -0
- package/dist/lib/cid.js.map +1 -0
- package/dist/lib/credentials.d.ts +40 -16
- package/dist/lib/credentials.d.ts.map +1 -0
- package/dist/lib/credentials.js +222 -49
- package/dist/lib/credentials.js.map +1 -0
- package/dist/lib/jcs.d.ts +3 -0
- package/dist/lib/jcs.d.ts.map +1 -0
- package/dist/lib/jcs.js +48 -0
- package/dist/lib/jcs.js.map +1 -0
- package/dist/lib/signing.d.ts +13 -0
- package/dist/lib/signing.d.ts.map +1 -0
- package/dist/lib/signing.js +34 -0
- package/dist/lib/signing.js.map +1 -0
- package/dist/lib.d.ts +18 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +12 -0
- package/dist/lib.js.map +1 -0
- package/dist/typegen/augment.d.ts +57 -0
- package/dist/typegen/augment.d.ts.map +1 -0
- package/dist/typegen/augment.js +87 -0
- package/dist/typegen/augment.js.map +1 -0
- package/dist/typegen/fetch.d.ts +30 -0
- package/dist/typegen/fetch.d.ts.map +1 -0
- package/dist/typegen/fetch.js +38 -0
- package/dist/typegen/fetch.js.map +1 -0
- package/dist/typegen/lockfile.d.ts +42 -0
- package/dist/typegen/lockfile.d.ts.map +1 -0
- package/dist/typegen/lockfile.js +58 -0
- package/dist/typegen/lockfile.js.map +1 -0
- package/dist/typegen/schema-to-ts.d.ts +21 -0
- package/dist/typegen/schema-to-ts.d.ts.map +1 -0
- package/dist/typegen/schema-to-ts.js +29 -0
- package/dist/typegen/schema-to-ts.js.map +1 -0
- package/package.json +23 -58
- package/dist/commands/auth/index.d.ts +0 -2
- package/dist/commands/auth/index.js +0 -162
- package/dist/commands/deploy/clone.d.ts +0 -13
- package/dist/commands/deploy/clone.js +0 -143
- package/dist/commands/deploy/delete.d.ts +0 -14
- package/dist/commands/deploy/delete.js +0 -134
- package/dist/commands/deploy/deploy.d.ts +0 -24
- package/dist/commands/deploy/deploy.js +0 -654
- package/dist/commands/deploy/index.d.ts +0 -2
- package/dist/commands/deploy/index.js +0 -216
- package/dist/commands/deploy/status.d.ts +0 -14
- package/dist/commands/deploy/status.js +0 -61
- package/dist/commands/dev/index.d.ts +0 -2
- package/dist/commands/dev/index.js +0 -134
- package/dist/commands/dev/server.d.ts +0 -14
- package/dist/commands/dev/server.js +0 -195
- package/dist/commands/dev/static/app.js +0 -633
- package/dist/commands/dev/static/index.html +0 -205
- package/dist/commands/dev/static/static/app.js +0 -633
- package/dist/commands/dev/static/static/index.html +0 -205
- package/dist/commands/dev/static/static/style.css +0 -184
- package/dist/commands/dev/static/style.css +0 -184
- package/dist/commands/playground/index.d.ts +0 -2
- package/dist/commands/playground/index.js +0 -75
- package/dist/commands/playground/test.d.ts +0 -15
- package/dist/commands/playground/test.js +0 -166
- package/dist/commands/service/index.d.ts +0 -2
- package/dist/commands/service/index.js +0 -89
- package/dist/lib/api.d.ts +0 -146
- package/dist/lib/api.js +0 -330
- package/dist/lib/config.d.ts +0 -12
- package/dist/lib/config.js +0 -145
- package/dist/lib/runtime/agent-router.d.ts +0 -12
- package/dist/lib/runtime/agent-router.js +0 -67
- package/dist/lib/runtime/context-builder.d.ts +0 -27
- package/dist/lib/runtime/context-builder.js +0 -166
- package/dist/lib/runtime/cubby-manager.d.ts +0 -20
- package/dist/lib/runtime/cubby-manager.js +0 -162
- package/dist/lib/runtime/index.d.ts +0 -51
- package/dist/lib/runtime/index.js +0 -181
- package/dist/lib/runtime/log-collector.d.ts +0 -17
- package/dist/lib/runtime/log-collector.js +0 -61
- package/dist/lib/runtime/stream-manager.d.ts +0 -10
- package/dist/lib/runtime/stream-manager.js +0 -77
- package/dist/lib/runtime/types.d.ts +0 -76
- package/dist/lib/runtime/types.js +0 -2
- package/dist/lib/transpile.d.ts +0 -1
- package/dist/lib/transpile.js +0 -9
- package/dist/lib/typecheck.d.ts +0 -31
- package/dist/lib/typecheck.js +0 -175
- package/dist/lib/types.d.ts +0 -246
- package/dist/lib/types.js +0 -2
- package/dist/lib/utils.d.ts +0 -4
- package/dist/lib/utils.js +0 -33
- package/example/.env.example +0 -6
- package/example/agents/object-detection/tasks/yolo.ts +0 -28
- package/example/agents/parking-violation-detector/tasks/detect.ts +0 -326
- package/example/cef.config.yaml +0 -91
- package/example/engagements/engagement.ts +0 -902
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parking Violation Detector — Consolidated Agent
|
|
3
|
-
*
|
|
4
|
-
* This file contains the complete logic for projecting drone detections to GPS,
|
|
5
|
-
* querying a local parking map, and tracking violations over time.
|
|
6
|
-
*
|
|
7
|
-
* Optimized for Agent Runtime with embedded map data and MCP task schemas.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
// ─── Embedded Data (ng.geojson) ─────────────────────────────────────────────
|
|
11
|
-
|
|
12
|
-
const REGION_MAP_JSON = `{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-122.045544,37.516652],[-122.045518,37.516605],[-122.044711,37.516874],[-122.044732,37.516918],[-122.045544,37.516652]]]},"bbox":[-122.045544,37.516605,-122.044711,37.516918]},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-122.044621,37.51693],[-122.044445,37.516597],[-122.044389,37.516615],[-122.044573,37.516948],[-122.044621,37.51693]]]},"bbox":[-122.044621,37.516597,-122.044389,37.516948]},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-122.045407,37.516562],[-122.045383,37.516517],[-122.045212,37.516578],[-122.045227,37.516621],[-122.045407,37.516562]]]},"bbox":[-122.045407,37.516517,-122.045212,37.516621]},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-122.044949,37.516719],[-122.044924,37.516676],[-122.044651,37.51677],[-122.044672,37.516814],[-122.044949,37.516719]]]},"bbox":[-122.044949,37.516676,-122.044651,37.516814]},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-122.045443,37.516468],[-122.045364,37.516321],[-122.045306,37.516345],[-122.045387,37.516485],[-122.045443,37.516468]]]},"bbox":[-122.045443,37.516321,-122.045306,37.516485]},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-122.044389,37.516491],[-122.044316,37.516353],[-122.044262,37.516369],[-122.044344,37.516505],[-122.044389,37.516491]]]},"bbox":[-122.044389,37.516353,-122.044262,37.516505]},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-122.045734,37.516598],[-122.045574,37.516289],[-122.045508,37.516311],[-122.045668,37.516616],[-122.045734,37.516598]]]},"bbox":[-122.045734,37.516289,-122.045508,37.516616]}]}`;
|
|
13
|
-
|
|
14
|
-
// ─── Enums & Types ──────────────────────────────────────────────────────────
|
|
15
|
-
|
|
16
|
-
enum ZoneType {
|
|
17
|
-
REGULAR = "regular",
|
|
18
|
-
HANDICAP = "handicap",
|
|
19
|
-
FIRE_LANE = "fire_lane",
|
|
20
|
-
LOADING = "loading",
|
|
21
|
-
NO_PARKING = "no_parking",
|
|
22
|
-
ACCESS_AISLE = "access_aisle",
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
enum ViolationType {
|
|
26
|
-
NONE = "none",
|
|
27
|
-
OUTSIDE_SLOT = "outside_slot",
|
|
28
|
-
DOUBLE_PARKED = "double_parked",
|
|
29
|
-
FIRE_LANE = "fire_lane",
|
|
30
|
-
HANDICAP_ZONE = "handicap_zone",
|
|
31
|
-
BLOCKING_ACCESS = "blocking_access",
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
enum ViolationSeverity {
|
|
35
|
-
INFO = "info",
|
|
36
|
-
WARNING = "warning",
|
|
37
|
-
CRITICAL = "critical",
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface GeoPoint { lat: number; lng: number; }
|
|
41
|
-
type GeoPolygon = GeoPoint[];
|
|
42
|
-
|
|
43
|
-
interface BoundingBox { x: number; y: number; w: number; h: number; }
|
|
44
|
-
|
|
45
|
-
interface Detection {
|
|
46
|
-
classLabel: string;
|
|
47
|
-
bbox: BoundingBox;
|
|
48
|
-
confidence: number;
|
|
49
|
-
trackingId?: string;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
interface DroneTelemetry {
|
|
53
|
-
timestamp: number;
|
|
54
|
-
position: GeoPoint;
|
|
55
|
-
altitudeAGL: number;
|
|
56
|
-
heading: number;
|
|
57
|
-
gimbalPitch: number;
|
|
58
|
-
hfov: number;
|
|
59
|
-
vfov: number;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
interface FrameDetections {
|
|
63
|
-
timestamp: number;
|
|
64
|
-
detections: Detection[];
|
|
65
|
-
telemetry: DroneTelemetry;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
interface CameraIntrinsics {
|
|
69
|
-
focalLengthMm: number;
|
|
70
|
-
sensorWidthMm: number;
|
|
71
|
-
sensorHeightMm: number;
|
|
72
|
-
imageWidthPx: number;
|
|
73
|
-
imageHeightPx: number;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
interface ParkingSlot {
|
|
77
|
-
id: string;
|
|
78
|
-
polygon: GeoPolygon;
|
|
79
|
-
zoneType: ZoneType;
|
|
80
|
-
label?: string;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
interface ViolationResult {
|
|
84
|
-
detection: Detection;
|
|
85
|
-
violationType: ViolationType;
|
|
86
|
-
severity: ViolationSeverity;
|
|
87
|
-
location: GeoPoint;
|
|
88
|
-
vehicleFootprint: GeoPolygon;
|
|
89
|
-
confidence: number;
|
|
90
|
-
timestamp: number;
|
|
91
|
-
nearestSlot?: ParkingSlot;
|
|
92
|
-
distanceToNearestSlot?: number;
|
|
93
|
-
shouldEscalate: boolean;
|
|
94
|
-
triggerPlateRecognition: boolean;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
interface TrackedVehicle {
|
|
98
|
-
geoHash: string;
|
|
99
|
-
firstSeen: number;
|
|
100
|
-
lastSeen: number;
|
|
101
|
-
observationCount: number;
|
|
102
|
-
location: GeoPoint;
|
|
103
|
-
violationType: ViolationType;
|
|
104
|
-
trackingId?: string;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// ─── Internal Logic (Consolidated) ──────────────────────────────────────────
|
|
108
|
-
|
|
109
|
-
const EARTH_RADIUS_M = 6371000;
|
|
110
|
-
|
|
111
|
-
function degreesToRadians(deg: number): number { return (deg * Math.PI) / 180; }
|
|
112
|
-
function radiansToDegrees(rad: number): number { return (rad * 180) / Math.PI; }
|
|
113
|
-
|
|
114
|
-
function haversineDistance(a: GeoPoint, b: GeoPoint): number {
|
|
115
|
-
const dLat = degreesToRadians(b.lat - a.lat);
|
|
116
|
-
const dLng = degreesToRadians(b.lng - a.lng);
|
|
117
|
-
const h = Math.sin(dLat / 2) ** 2 + Math.cos(degreesToRadians(a.lat)) * Math.cos(degreesToRadians(b.lat)) * Math.sin(dLng / 2) ** 2;
|
|
118
|
-
return EARTH_RADIUS_M * 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h));
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function offsetToGeoPoint(origin: GeoPoint, dx: number, dy: number): GeoPoint {
|
|
122
|
-
const latMeters = (Math.PI / 180) * EARTH_RADIUS_M;
|
|
123
|
-
const lngMeters = latMeters * Math.cos(degreesToRadians(origin.lat));
|
|
124
|
-
return { lat: origin.lat + dy / latMeters, lng: origin.lng + dx / lngMeters };
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function pointInPolygon(p: GeoPoint, poly: GeoPolygon): boolean {
|
|
128
|
-
let inside = false;
|
|
129
|
-
for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
|
|
130
|
-
const intersect = ((poly[i].lat > p.lat) !== (poly[j].lat > p.lat)) &&
|
|
131
|
-
(p.lng < (poly[j].lng - poly[i].lng) * (p.lat - poly[i].lat) / (poly[j].lat - poly[i].lat) + poly[i].lng);
|
|
132
|
-
if (intersect) inside = !inside;
|
|
133
|
-
}
|
|
134
|
-
return inside;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function polygonsOverlap(polyA: GeoPolygon, polyB: GeoPolygon): boolean {
|
|
138
|
-
for (const v of polyA) if (pointInPolygon(v, polyB)) return true;
|
|
139
|
-
for (const v of polyB) if (pointInPolygon(v, polyA)) return true;
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function polygonCentroid(poly: GeoPolygon): GeoPoint {
|
|
144
|
-
let lat = 0, lng = 0;
|
|
145
|
-
for (const p of poly) { lat += p.lat; lng += p.lng; }
|
|
146
|
-
return { lat: lat / poly.length, lng: lng / poly.length };
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function simpleGeoHash(p: GeoPoint): string {
|
|
150
|
-
return `${Math.round(p.lat * 10000) / 10000}_${Math.round(p.lng * 10000) / 10000}`;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// ─── Geo Projector ──────────────────────────────────────────────────────────
|
|
154
|
-
|
|
155
|
-
class InternalGeoProjector {
|
|
156
|
-
calculateGSD(altitude: number, intrinsics: CameraIntrinsics): number {
|
|
157
|
-
return (altitude * intrinsics.sensorWidthMm) / (intrinsics.focalLengthMm * intrinsics.imageWidthPx);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
projectBboxToGeo(bbox: BoundingBox, tel: DroneTelemetry, intrinsics: CameraIntrinsics) {
|
|
161
|
-
const gsd = this.calculateGSD(tel.altitudeAGL, intrinsics);
|
|
162
|
-
const cx = intrinsics.imageWidthPx / 2;
|
|
163
|
-
const cy = intrinsics.imageHeightPx / 2;
|
|
164
|
-
const headingRad = degreesToRadians(tel.heading);
|
|
165
|
-
const pitchRad = degreesToRadians(Math.abs(tel.gimbalPitch));
|
|
166
|
-
const pitchScale = (pitchRad > 0 && pitchRad < Math.PI / 2) ? 1 / Math.cos(Math.PI / 2 - pitchRad) : 1;
|
|
167
|
-
|
|
168
|
-
const project = (px: number, py: number) => {
|
|
169
|
-
let dx = (px - cx) * gsd;
|
|
170
|
-
let dy = -(py - cy) * gsd * pitchScale;
|
|
171
|
-
const rdx = dx * Math.cos(headingRad) + dy * Math.sin(headingRad);
|
|
172
|
-
const rdy = -dx * Math.sin(headingRad) + dy * Math.cos(headingRad);
|
|
173
|
-
return offsetToGeoPoint(tel.position, rdx, rdy);
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
const center = project(bbox.x + bbox.w / 2, bbox.y + bbox.h / 2);
|
|
177
|
-
const corners = [
|
|
178
|
-
project(bbox.x, bbox.y), project(bbox.x + bbox.w, bbox.y),
|
|
179
|
-
project(bbox.x + bbox.w, bbox.y + bbox.h), project(bbox.x, bbox.y + bbox.h)
|
|
180
|
-
];
|
|
181
|
-
corners.push({ ...corners[0] });
|
|
182
|
-
return { center, corners };
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// ─── Parking Map Service ────────────────────────────────────────────────────
|
|
187
|
-
|
|
188
|
-
class InternalMapService {
|
|
189
|
-
private slots: ParkingSlot[] = [];
|
|
190
|
-
|
|
191
|
-
load(geojson: any) {
|
|
192
|
-
this.slots = geojson.features.map((f: any, i: number) => ({
|
|
193
|
-
id: f.id || `slot-${i}`,
|
|
194
|
-
polygon: f.geometry.coordinates[0].map(([lng, lat]: number[]) => ({ lat, lng })),
|
|
195
|
-
zoneType: this.inferZone(f.properties),
|
|
196
|
-
label: f.properties.name || ""
|
|
197
|
-
}));
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
private inferZone(props: any): ZoneType {
|
|
201
|
-
if (props.fire_lane === "yes" || props.parking === "fire_lane") return ZoneType.FIRE_LANE;
|
|
202
|
-
if (props.access === "disabled" || props.parking === "disabled") return ZoneType.HANDICAP;
|
|
203
|
-
if (props.parking === "no" || props.parking === "no_parking") return ZoneType.NO_PARKING;
|
|
204
|
-
return ZoneType.REGULAR;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
getZoneAt(p: GeoPoint) { return this.slots.find(s => pointInPolygon(p, s.polygon)); }
|
|
208
|
-
findNearest(p: GeoPoint) {
|
|
209
|
-
let nearest = null, minDist = Infinity;
|
|
210
|
-
for (const s of this.slots) {
|
|
211
|
-
const d = haversineDistance(p, polygonCentroid(s.polygon));
|
|
212
|
-
if (d < minDist) { minDist = d; nearest = s; }
|
|
213
|
-
}
|
|
214
|
-
return nearest ? { slot: nearest, distance: minDist } : null;
|
|
215
|
-
}
|
|
216
|
-
getOverlapping(poly: GeoPolygon) { return this.slots.filter(s => polygonsOverlap(poly, s.polygon)); }
|
|
217
|
-
getSlots() { return this.slots; }
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// ─── Temporal Tracker ───────────────────────────────────────────────────────
|
|
221
|
-
|
|
222
|
-
class InternalTracker {
|
|
223
|
-
private tracked = new Map<string, TrackedVehicle>();
|
|
224
|
-
private escalationMs = 5 * 60 * 1000;
|
|
225
|
-
private plateMs = 3 * 60 * 1000;
|
|
226
|
-
|
|
227
|
-
record(loc: GeoPoint, type: ViolationType, ts: number, tid?: string) {
|
|
228
|
-
const hash = simpleGeoHash(loc);
|
|
229
|
-
let vehicle = tid ? Array.from(this.tracked.values()).find(v => v.trackingId === tid) : null;
|
|
230
|
-
if (!vehicle) {
|
|
231
|
-
for (const v of this.tracked.values()) {
|
|
232
|
-
if (haversineDistance(loc, v.location) < 5) { vehicle = v; break; }
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (vehicle) {
|
|
237
|
-
vehicle.lastSeen = ts;
|
|
238
|
-
vehicle.observationCount++;
|
|
239
|
-
vehicle.location = loc;
|
|
240
|
-
vehicle.violationType = type;
|
|
241
|
-
} else {
|
|
242
|
-
vehicle = { geoHash: hash, firstSeen: ts, lastSeen: ts, observationCount: 1, location: loc, violationType: type, trackingId: tid };
|
|
243
|
-
this.tracked.set(`${hash}_${ts}`, vehicle);
|
|
244
|
-
}
|
|
245
|
-
return vehicle;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
shouldEscalate(v: TrackedVehicle) { return (v.lastSeen - v.firstSeen >= this.escalationMs) && v.violationType !== ViolationType.NONE; }
|
|
249
|
-
shouldPlate(v: TrackedVehicle) { return (v.lastSeen - v.firstSeen >= this.plateMs) && v.violationType !== ViolationType.NONE; }
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// ─── Violation Engine ───────────────────────────────────────────────────────
|
|
253
|
-
|
|
254
|
-
class ViolationEngine {
|
|
255
|
-
private projector = new InternalGeoProjector();
|
|
256
|
-
private map = new InternalMapService();
|
|
257
|
-
private tracker = new InternalTracker();
|
|
258
|
-
private intrinsics: CameraIntrinsics = { focalLengthMm: 12.29, sensorWidthMm: 17.3, sensorHeightMm: 13.0, imageWidthPx: 5280, imageHeightPx: 3956 };
|
|
259
|
-
|
|
260
|
-
constructor() {
|
|
261
|
-
this.map.load(JSON.parse(REGION_MAP_JSON));
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
updateIntrinsics(i: Partial<CameraIntrinsics>) { this.intrinsics = { ...this.intrinsics, ...i }; }
|
|
265
|
-
|
|
266
|
-
process(frame: FrameDetections): ViolationResult[] {
|
|
267
|
-
return frame.detections
|
|
268
|
-
.filter(d => ["car", "truck", "van", "bus"].includes(d.classLabel.toLowerCase()) && d.confidence >= 0.5)
|
|
269
|
-
.map(d => {
|
|
270
|
-
const { center, corners } = this.projector.projectBboxToGeo(d.bbox, frame.telemetry, this.intrinsics);
|
|
271
|
-
let vType = ViolationType.NONE;
|
|
272
|
-
const zone = this.map.getZoneAt(center);
|
|
273
|
-
const overlapping = this.map.getOverlapping(corners);
|
|
274
|
-
const nearest = this.map.findNearest(center);
|
|
275
|
-
|
|
276
|
-
if (zone?.zoneType === ZoneType.FIRE_LANE) vType = ViolationType.FIRE_LANE;
|
|
277
|
-
else if (zone?.zoneType === ZoneType.HANDICAP) vType = ViolationType.HANDICAP_ZONE;
|
|
278
|
-
else if (overlapping.length >= 2) vType = ViolationType.DOUBLE_PARKED;
|
|
279
|
-
else if (!zone) vType = ViolationType.OUTSIDE_SLOT;
|
|
280
|
-
|
|
281
|
-
const tracked = this.tracker.record(center, vType, frame.timestamp, d.trackingId);
|
|
282
|
-
|
|
283
|
-
return {
|
|
284
|
-
detection: d, violationType: vType, location: center, vehicleFootprint: corners,
|
|
285
|
-
confidence: d.confidence, timestamp: frame.timestamp,
|
|
286
|
-
severity: vType === ViolationType.NONE ? ViolationSeverity.INFO : (vType === ViolationType.FIRE_LANE ? ViolationSeverity.CRITICAL : ViolationSeverity.WARNING),
|
|
287
|
-
nearestSlot: nearest?.slot, distanceToNearestSlot: nearest?.distance,
|
|
288
|
-
shouldEscalate: this.tracker.shouldEscalate(tracked),
|
|
289
|
-
triggerPlateRecognition: this.tracker.shouldPlate(tracked)
|
|
290
|
-
};
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
getStats() { return { region: "Newark Waterfront", slotCount: this.map.getSlots().length }; }
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// ─── MCP Tasks ──────────────────────────────────────────────────────────────
|
|
298
|
-
|
|
299
|
-
const engine = new ViolationEngine();
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* @task detect_violations
|
|
303
|
-
* @description Analyzes a frame of detections and telemetry to classify parking violations.
|
|
304
|
-
* @input {FrameDetections} frame - The telemetry and bounding boxes from the current frame.
|
|
305
|
-
* @output {ViolationResult[]} Results for each detected vehicle.
|
|
306
|
-
*/
|
|
307
|
-
async function handle(event, ctx): Promise<ViolationResult[]> {
|
|
308
|
-
ctx.log(`[VIOLATION DETECTOR RECEVIED EVENT] ${JSON.stringify(event)}`)
|
|
309
|
-
const frame = event.payload as FrameDetections
|
|
310
|
-
const engine = new ViolationEngine();
|
|
311
|
-
const result = engine.process(frame);
|
|
312
|
-
ctx.log(`[VioladtionDetectionResult]:${JSON.stringify(result)}`)
|
|
313
|
-
return result
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* @task get_agent_info
|
|
318
|
-
* @description Returns operational status and region information.
|
|
319
|
-
*/
|
|
320
|
-
async function get_agent_info() {
|
|
321
|
-
return {
|
|
322
|
-
...engine.getStats(),
|
|
323
|
-
capabilities: ["Geographic Projection", "Parking Map Query", "Temporal Tracking", "Violation Classification"],
|
|
324
|
-
version: "1.0.0-ng"
|
|
325
|
-
};
|
|
326
|
-
}
|
package/example/cef.config.yaml
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
agentServicePubKey: "0x788b3863773214f0791d7be9714e6c3445518592590bebf8119833462c023b75"
|
|
2
|
-
workspaces:
|
|
3
|
-
- name: Freemont
|
|
4
|
-
description: Freemont
|
|
5
|
-
streams:
|
|
6
|
-
- name: DSC 142
|
|
7
|
-
description: DSC 142
|
|
8
|
-
selectors:
|
|
9
|
-
- name: illegalParkingDetection
|
|
10
|
-
conditions:
|
|
11
|
-
- event_type:illegalParking
|
|
12
|
-
deployments:
|
|
13
|
-
- name: Illegal Parking Detection
|
|
14
|
-
description: Illegal Parking Detection
|
|
15
|
-
engagement: Illegal Parking detection
|
|
16
|
-
isActive: true
|
|
17
|
-
triggers:
|
|
18
|
-
- name: all-events
|
|
19
|
-
conditions:
|
|
20
|
-
- "*"
|
|
21
|
-
engagementRules: []
|
|
22
|
-
deploymentId: dep-21e72017
|
|
23
|
-
streamId: stream-f5213550
|
|
24
|
-
workspaceId: "2198"
|
|
25
|
-
engagements:
|
|
26
|
-
- name: Illegal Parking detection
|
|
27
|
-
description: Illegal Parking Detection
|
|
28
|
-
file: ./engagements/engagement.ts
|
|
29
|
-
version: 1.0.0
|
|
30
|
-
engagementId: eng-2f8b9517
|
|
31
|
-
agents:
|
|
32
|
-
- name: Object Detection
|
|
33
|
-
alias: objectDetection
|
|
34
|
-
description: Object Detection Agent
|
|
35
|
-
version: 1.0.0
|
|
36
|
-
tasks:
|
|
37
|
-
- name: Yolo
|
|
38
|
-
alias: yolo
|
|
39
|
-
file: ./agents/object-detection/tasks/yolo.ts
|
|
40
|
-
parameters:
|
|
41
|
-
properties:
|
|
42
|
-
image:
|
|
43
|
-
type: string
|
|
44
|
-
required: []
|
|
45
|
-
type: object
|
|
46
|
-
returns:
|
|
47
|
-
properties:
|
|
48
|
-
totalDetections:
|
|
49
|
-
type: number
|
|
50
|
-
detections:
|
|
51
|
-
type: array
|
|
52
|
-
processingTime:
|
|
53
|
-
type: number
|
|
54
|
-
type: object
|
|
55
|
-
agentId: agent-628677bd
|
|
56
|
-
- name: Parking Violation Detector
|
|
57
|
-
alias: parkingViolationDetector
|
|
58
|
-
description: Parking Violation Detector
|
|
59
|
-
version: 1.0.0
|
|
60
|
-
tasks:
|
|
61
|
-
- name: Detect
|
|
62
|
-
alias: detect
|
|
63
|
-
file: ./agents/parking-violation-detector/tasks/detect.ts
|
|
64
|
-
parameters:
|
|
65
|
-
properties:
|
|
66
|
-
timestamp:
|
|
67
|
-
type: number
|
|
68
|
-
detections:
|
|
69
|
-
type: array
|
|
70
|
-
telemetry:
|
|
71
|
-
type: object
|
|
72
|
-
required: []
|
|
73
|
-
type: object
|
|
74
|
-
returns:
|
|
75
|
-
properties:
|
|
76
|
-
value:
|
|
77
|
-
type: array
|
|
78
|
-
type: object
|
|
79
|
-
agentId: agent-b89132b6
|
|
80
|
-
cubbies:
|
|
81
|
-
- alias: syncMission
|
|
82
|
-
name: Sync Mission
|
|
83
|
-
description: Synchronized drone mission data and violation records
|
|
84
|
-
migrations:
|
|
85
|
-
- version: 1
|
|
86
|
-
up: |
|
|
87
|
-
CREATE TABLE missions (id TEXT PRIMARY KEY, status TEXT NOT NULL, drone_id TEXT, started_at TEXT, ended_at TEXT, created_at TEXT DEFAULT (datetime('now')));
|
|
88
|
-
CREATE TABLE violations (id TEXT PRIMARY KEY, mission_id TEXT NOT NULL, type TEXT NOT NULL, latitude REAL, longitude REAL, confidence REAL, detected_at TEXT NOT NULL, FOREIGN KEY (mission_id) REFERENCES missions(id));
|
|
89
|
-
CREATE INDEX idx_violations_mission ON violations(mission_id);
|
|
90
|
-
cubbyId: 53d8630e-b8ab-4382-9973-5396dea72a80
|
|
91
|
-
agentServiceId: "2620"
|