""" VIMS Instance Creator Creates a new VIMS instance for any article/topic. Usage: python scripts/create_instance.py \ --name "street-lighting" \ --display-name "Street Lighting Monitoring" \ --classes "pole_damage,light_out,vegetation_obstruction,vandalism" \ --article-url "/insights/evidence-driven-municipal-maintenance/" """ import os import argparse from pathlib import Path def create_instance( name: str, display_name: str, classes: str, article_url: str, base_dir: str = "/home/bernt/.openclaw/workspace/vims-core/instances" ): """ Create new VIMS instance. Args: name: Instance name (directory name) display_name: Human-readable name classes: Comma-separated anomaly classes article_url: Related Landvex article URL base_dir: Base directory for instances """ instance_dir = Path(base_dir) / name instance_dir.mkdir(parents=True, exist_ok=True) # Create subdirectories (instance_dir / "data" / "raw").mkdir(parents=True, exist_ok=True) (instance_dir / "data" / "processed").mkdir(parents=True, exist_ok=True) (instance_dir / "data" / "annotations").mkdir(parents=True, exist_ok=True) (instance_dir / "models").mkdir(exist_ok=True) (instance_dir / "src").mkdir(exist_ok=True) class_list = [c.strip() for c in classes.split(",")] # Create detector module detector_code = f'''""" {name} Anomaly Detector Generated by VIMS Instance Creator Related article: {article_url} """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent.parent / "core")) from base_detector import VIMSBaseDetector, VIMSInstanceRegistry class {name.title().replace("-", "")}Detector(VIMSBaseDetector): """ Anomaly detector for {display_name}. Article: {article_url} """ TOPIC = "{name}" CLASS_NAMES = {{ {', '.join([f'{i}: "{c}"' for i, c in enumerate(class_list)])} }} SEVERITY_MAP = {{ {', '.join([f'"{c}": 3' for c in class_list])} }} def preprocess(self, image): """{name}-specific preprocessing.""" # TODO: Implement specific preprocessing return image def postprocess(self, raw_output): """{name}-specific postprocessing.""" # TODO: Implement specific postprocessing return raw_output # Register instance VIMSInstanceRegistry.register("{name}", {name.title().replace("-", "")}Detector) ''' (instance_dir / "src" / "detector.py").write_text(detector_code) # Create database setup db_code = f'''""" Database setup for {display_name} """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent.parent / "core")) from database import VIMSDatabase def setup(): """Initialize database for {name}.""" db = VIMSDatabase("{name}") db.create_schema(anomaly_classes={class_list}) print(f"Database initialized for {display_name}") if __name__ == "__main__": setup() ''' (instance_dir / "src" / "database.py").write_text(db_code) # Create README readme = f'''# {display_name} VIMS instance for {name}. ## Related Article [{article_url}](https://landvex.com{article_url}) ## Anomaly Classes {chr(10).join([f"- {c}" for c in class_list])} ## Quick Start 1. Add training images to `data/raw/` 2. Annotate using LabelImg (YOLO format) 3. Run preprocessing: `python src/detector.py` 4. Train model: `python src/detector.py --train` 5. Run inference: `python src/detector.py --predict data/test/image.jpg` ## API Once deployed, access via: - REST: `POST /api/{name}/predict` - WebSocket: `ws://host/ws/{name}/alerts` ''' (instance_dir / "README.md").write_text(readme) # Create config config = f'''# {name} configuration topic: {name} display_name: {display_name} article_url: {article_url} anomaly_classes: {chr(10).join([f" - {c}" for c in class_list])} model: base: yolov8n.pt input_size: 640 training: epochs: 100 batch_size: 16 ''' (instance_dir / "config.yaml").write_text(config) print(f"✅ Created VIMS instance: {name}") print(f" Location: {instance_dir}") print(f" Classes: {', '.join(class_list)}") print(f" Article: {article_url}") print() print("Next steps:") print(f" 1. cd {instance_dir}") print(" 2. Add training images to data/raw/") print(" 3. python src/database.py") print(" 4. python src/detector.py --train") def main(): parser = argparse.ArgumentParser(description="Create VIMS Instance") parser.add_argument("--name", required=True, help="Instance name (directory)") parser.add_argument("--display-name", required=True, help="Human-readable name") parser.add_argument("--classes", required=True, help="Comma-separated anomaly classes") parser.add_argument("--article-url", required=True, help="Related article URL") args = parser.parse_args() create_instance( name=args.name, display_name=args.display_name, classes=args.classes, article_url=args.article_url ) if __name__ == "__main__": main() ''' (instance_dir / "src" / "detector.py").write_text(detector_code) # Create database setup db_code = f'''""" Database setup for {display_name} """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent.parent / "core")) from database import VIMSDatabase def setup(): """Initialize database for {name}.""" db = VIMSDatabase("{name}") db.create_schema(anomaly_classes={class_list}) print(f"Database initialized for {display_name}") if __name__ == "__main__": setup() ''' (instance_dir / "src" / "database.py").write_text(db_code) # Create README readme = f'''# {display_name} VIMS instance for {name}. ## Related Article [{article_url}](https://landvex.com{article_url}) ## Anomaly Classes {chr(10).join([f"- {c}" for c in class_list])} ## Quick Start 1. Add training images to `data/raw/` 2. Annotate using LabelImg (YOLO format) 3. Run preprocessing: `python src/detector.py` 4. Train model: `python src/detector.py --train` 5. Run inference: `python src/detector.py --predict data/test/image.jpg` ## API Once deployed, access via: - REST: `POST /api/{name}/predict` - WebSocket: `ws://host/ws/{name}/alerts` ''' (instance_dir / "README.md").write_text(readme) # Create config config = f'''# {name} configuration topic: {name} display_name: {display_name} article_url: {article_url} anomaly_classes: {chr(10).join([f" - {c}" for c in class_list])} model: base: yolov8n.pt input_size: 640 training: epochs: 100 batch_size: 16 ''' (instance_dir / "config.yaml").write_text(config) print(f"✅ Created VIMS instance: {name}") print(f" Location: {instance_dir}") print(f" Classes: {', '.join(class_list)}") print(f" Article: {article_url}") print() print("Next steps:") print(f" 1. cd {instance_dir}") print(" 2. Add training images to data/raw/") print(" 3. python src/database.py") print(" 4. python src/detector.py --train") def main(): parser = argparse.ArgumentParser(description="Create VIMS Instance") parser.add_argument("--name", required=True, help="Instance name (directory)") parser.add_argument("--display-name", required=True, help="Human-readable name") parser.add_argument("--classes", required=True, help="Comma-separated anomaly classes") parser.add_argument("--article-url", required=True, help="Related article URL") args = parser.parse_args() create_instance( name=args.name, display_name=args.display_name, classes=args.classes, article_url=args.article_url ) if __name__ == "__main__": main()