smart-spatial-system 0.2.3__tar.gz → 0.2.4__tar.gz

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.
Files changed (432) hide show
  1. {smart_spatial_system-0.2.3/smart_spatial_system.egg-info → smart_spatial_system-0.2.4}/PKG-INFO +1 -1
  2. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/llm_spec_generator.py +128 -22
  3. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/feature_scoring.py +23 -1
  4. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/pyproject.toml +1 -1
  5. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4/smart_spatial_system.egg-info}/PKG-INFO +1 -1
  6. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_feature_scoring.py +44 -0
  7. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_llm_spec_generator.py +130 -0
  8. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/LICENSE +0 -0
  9. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/README.md +0 -0
  10. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/__init__.py +0 -0
  11. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/auth.py +0 -0
  12. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/main.py +0 -0
  13. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/__init__.py +0 -0
  14. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/data_source_connectors.py +0 -0
  15. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/data_sources.py +0 -0
  16. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/plugins_settings.py +0 -0
  17. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/projects.py +0 -0
  18. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/query_planner.py +0 -0
  19. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/requests_outputs.py +0 -0
  20. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/system.py +0 -0
  21. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/uploads.py +0 -0
  22. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/routers/weights.py +0 -0
  23. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/api/support.py +0 -0
  24. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/__init__.py +0 -0
  25. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/__init__.py +0 -0
  26. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/area_perimeter_calc.example.yaml +0 -0
  27. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/area_perimeter_calc.yaml +0 -0
  28. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/attribute_statistics.example.yaml +0 -0
  29. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/attribute_statistics.yaml +0 -0
  30. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/band_math.example.yaml +0 -0
  31. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/band_math.yaml +0 -0
  32. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/buffer_analysis.example.yaml +0 -0
  33. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/buffer_analysis.yaml +0 -0
  34. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/centroid_extractor.example.yaml +0 -0
  35. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/centroid_extractor.yaml +0 -0
  36. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/core_vector.example.yaml +0 -0
  37. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/core_vector.yaml +0 -0
  38. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/crs_transformer.example.yaml +0 -0
  39. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/crs_transformer.yaml +0 -0
  40. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/data_writer_exporter.example.yaml +0 -0
  41. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/data_writer_exporter.yaml +0 -0
  42. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/dissolve_aggregator.example.yaml +0 -0
  43. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/dissolve_aggregator.yaml +0 -0
  44. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/distance_calculator.example.yaml +0 -0
  45. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/distance_calculator.yaml +0 -0
  46. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/feature_enrichment.example.yaml +0 -0
  47. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/feature_enrichment.yaml +0 -0
  48. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/feature_scoring.example.yaml +0 -0
  49. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/feature_scoring.yaml +0 -0
  50. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/geocoding_resolver.example.yaml +0 -0
  51. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/geocoding_resolver.yaml +0 -0
  52. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/geometry_validator.example.yaml +0 -0
  53. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/geometry_validator.yaml +0 -0
  54. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/local_raster_loader.example.yaml +0 -0
  55. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/local_raster_loader.yaml +0 -0
  56. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/local_vector_loader.example.yaml +0 -0
  57. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/local_vector_loader.yaml +0 -0
  58. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/ndvi_calculator.example.yaml +0 -0
  59. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/ndvi_calculator.yaml +0 -0
  60. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/nearest_neighbor.example.yaml +0 -0
  61. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/nearest_neighbor.yaml +0 -0
  62. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/postgis_connector.example.yaml +0 -0
  63. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/postgis_connector.yaml +0 -0
  64. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_clip_mask.example.yaml +0 -0
  65. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_clip_mask.yaml +0 -0
  66. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_reclassify.example.yaml +0 -0
  67. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_reclassify.yaml +0 -0
  68. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_statistics.example.yaml +0 -0
  69. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_statistics.yaml +0 -0
  70. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_threshold.example.yaml +0 -0
  71. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_threshold.yaml +0 -0
  72. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_to_vector.example.yaml +0 -0
  73. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/raster_to_vector.yaml +0 -0
  74. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/risk_enrichment.example.yaml +0 -0
  75. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/risk_enrichment.yaml +0 -0
  76. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/slope_aspect.yaml +0 -0
  77. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spatial_intersection.example.yaml +0 -0
  78. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spatial_intersection.yaml +0 -0
  79. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spatial_join.example.yaml +0 -0
  80. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spatial_join.yaml +0 -0
  81. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spatial_predicate.example.yaml +0 -0
  82. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spatial_predicate.yaml +0 -0
  83. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spatial_query_filter.example.yaml +0 -0
  84. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spatial_query_filter.yaml +0 -0
  85. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spectral_indices.example.yaml +0 -0
  86. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/spectral_indices.yaml +0 -0
  87. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/wms_wfs_fetcher.example.yaml +0 -0
  88. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/wms_wfs_fetcher.yaml +0 -0
  89. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/zonal_statistics.example.yaml +0 -0
  90. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/config/plugins/zonal_statistics.yaml +0 -0
  91. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/__init__.py +0 -0
  92. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/audit.py +0 -0
  93. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/capability_registry.py +0 -0
  94. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/capability_router.py +0 -0
  95. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/capability_scoring.py +0 -0
  96. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/data_source_service.py +0 -0
  97. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/error_contract.py +0 -0
  98. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/feedback.py +0 -0
  99. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/feedback_proposal_service.py +0 -0
  100. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/input_error_mapping.py +0 -0
  101. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/input_reference_resolver.py +0 -0
  102. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/kernel_artifacts.py +0 -0
  103. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/learning_signals.py +0 -0
  104. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/llm_client.py +0 -0
  105. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/llm_gate.py +0 -0
  106. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/llm_intent_planner.py +0 -0
  107. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/loader_plugin_contract.py +0 -0
  108. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/map_layer_service.py +0 -0
  109. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/map_layers.py +0 -0
  110. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/models.py +0 -0
  111. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/natural_query_runner.py +0 -0
  112. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/output_service.py +0 -0
  113. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/output_storage.py +0 -0
  114. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/pipeline_executor.py +0 -0
  115. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/plan_builder.py +0 -0
  116. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/__init__.py +0 -0
  117. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/capability_resolver.py +0 -0
  118. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/dag.py +0 -0
  119. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/dag_executor.py +0 -0
  120. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/error_mapping.py +0 -0
  121. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/kernel_execution_bridge.py +0 -0
  122. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/kernel_plan_adapter.py +0 -0
  123. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/llm_query_spec.py +0 -0
  124. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/op_catalog.py +0 -0
  125. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/output_parity.py +0 -0
  126. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/planner.py +0 -0
  127. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/postgis_semantic_resolver.py +0 -0
  128. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/query_spec_contract.py +0 -0
  129. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/report_spec.py +0 -0
  130. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/runner.py +0 -0
  131. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/semantic_planning_context.py +0 -0
  132. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/planning/spec.py +0 -0
  133. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/plugin_config_store.py +0 -0
  134. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/plugin_error_mapping.py +0 -0
  135. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/plugin_modules.py +0 -0
  136. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/plugin_runtime_service.py +0 -0
  137. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/plugin_state.py +0 -0
  138. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/production_response.py +0 -0
  139. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/project_service.py +0 -0
  140. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/project_store.py +0 -0
  141. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/provider_error_mapping.py +0 -0
  142. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/query_execution_service.py +0 -0
  143. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/query_parser.py +0 -0
  144. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/request_history_service.py +0 -0
  145. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/response_assembler.py +0 -0
  146. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/response_builder.py +0 -0
  147. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/router_decision.py +0 -0
  148. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/routing_aware_natural_query_runner.py +0 -0
  149. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/routing_aware_plan_builder.py +0 -0
  150. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/runtime_paths.py +0 -0
  151. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/service.py +0 -0
  152. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/statistics.py +0 -0
  153. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/upload_service.py +0 -0
  154. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/upload_storage.py +0 -0
  155. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/weight_proposals.py +0 -0
  156. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/weight_store_persistence.py +0 -0
  157. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/orchestrator/weighted_router.py +0 -0
  158. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/__init__.py +0 -0
  159. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/_shared/__init__.py +0 -0
  160. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/_shared/local_path_validation.py +0 -0
  161. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/_shared/numeric_validation.py +0 -0
  162. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/_shared/plugin_config.py +0 -0
  163. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/area_perimeter_calc.py +0 -0
  164. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/attribute_statistics.py +0 -0
  165. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/band_math.py +0 -0
  166. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/buffer_analysis.py +0 -0
  167. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/centroid_extractor.py +0 -0
  168. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/core_vector.py +0 -0
  169. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/crs_transformer.py +0 -0
  170. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/data_writer_exporter.py +0 -0
  171. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/dissolve_aggregator.py +0 -0
  172. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/distance_calculator.py +0 -0
  173. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/feature_enrichment.py +0 -0
  174. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/geocoding_resolver.py +0 -0
  175. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/geometry_validator.py +0 -0
  176. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/local_raster_loader.py +0 -0
  177. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/local_vector_loader.py +0 -0
  178. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/ndvi_analysis.py +0 -0
  179. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/ndvi_calculator.py +0 -0
  180. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/nearest_neighbor.py +0 -0
  181. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/pdf_renderer.py +0 -0
  182. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/postgis_connector.py +0 -0
  183. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/raster_clip_mask.py +0 -0
  184. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/raster_reclassify.py +0 -0
  185. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/raster_statistics.py +0 -0
  186. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/raster_threshold.py +0 -0
  187. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/raster_to_vector.py +0 -0
  188. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/real_estate_scoring.py +0 -0
  189. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/real_estate_spatial_enrichment.py +0 -0
  190. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/report_builder.py +0 -0
  191. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/risk_enrichment.py +0 -0
  192. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/slope_aspect.py +0 -0
  193. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/spatial_intersection.py +0 -0
  194. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/spatial_join.py +0 -0
  195. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/spatial_predicate.py +0 -0
  196. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/spatial_query_filter.py +0 -0
  197. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/spectral_indices.py +0 -0
  198. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/wms_wfs_fetcher.py +0 -0
  199. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/plugins/zonal_statistics.py +0 -0
  200. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/setup.cfg +0 -0
  201. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/__init__.py +0 -0
  202. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/__main__.py +0 -0
  203. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/__init__.py +0 -0
  204. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/__init__.py +0 -0
  205. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/data_source_service.py +0 -0
  206. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/feedback_proposal_service.py +0 -0
  207. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/llm_intent_adapter.py +0 -0
  208. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/map_layer_service.py +0 -0
  209. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/output_service.py +0 -0
  210. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/planning_execution_policy.py +0 -0
  211. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/planning_response_adapter.py +0 -0
  212. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/plugin_runtime_service.py +0 -0
  213. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/project_service.py +0 -0
  214. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/__init__.py +0 -0
  215. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/accessibility_query_spec.py +0 -0
  216. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/direct_query_dispatch.py +0 -0
  217. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/natural_query_context.py +0 -0
  218. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/natural_query_dispatch.py +0 -0
  219. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/natural_query_execution.py +0 -0
  220. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/natural_query_failure.py +0 -0
  221. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/natural_query_persistence.py +0 -0
  222. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/planning_context.py +0 -0
  223. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/planning_execution.py +0 -0
  224. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/planning_persistence.py +0 -0
  225. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/planning_response.py +0 -0
  226. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/postgis_planning_context.py +0 -0
  227. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_analysis_inspector.py +0 -0
  228. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_classifier.py +0 -0
  229. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_context.py +0 -0
  230. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_document_renderer.py +0 -0
  231. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_missing_inputs.py +0 -0
  232. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_ranking_artifacts.py +0 -0
  233. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_ranking_direct_handler.py +0 -0
  234. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_ranking_execution.py +0 -0
  235. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_ranking_query_spec.py +0 -0
  236. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_ranking_response.py +0 -0
  237. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_report_payload.py +0 -0
  238. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution/real_estate_scoring.py +0 -0
  239. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_execution_service.py +0 -0
  240. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/query_spec_enrichment.py +0 -0
  241. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/real_estate_spatial_helpers.py +0 -0
  242. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/request_history_service.py +0 -0
  243. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/system_status_query_handler.py +0 -0
  244. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/upload_service.py +0 -0
  245. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/vector_display_handler.py +0 -0
  246. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/vector_geojson_helpers.py +0 -0
  247. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/application/services/vector_query_classifier.py +0 -0
  248. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/cli.py +0 -0
  249. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/domain/__init__.py +0 -0
  250. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/domain/contracts/__init__.py +0 -0
  251. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/domain/models/__init__.py +0 -0
  252. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/infrastructure/__init__.py +0 -0
  253. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/infrastructure/stores/__init__.py +0 -0
  254. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/interfaces/__init__.py +0 -0
  255. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/interfaces/api/__init__.py +0 -0
  256. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/interfaces/api/routers/__init__.py +0 -0
  257. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/plugins/__init__.py +0 -0
  258. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/runtime/__init__.py +0 -0
  259. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/shared/__init__.py +0 -0
  260. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/workflows/__init__.py +0 -0
  261. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/workflows/ndvi/__init__.py +0 -0
  262. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system/workflows/real_estate/__init__.py +0 -0
  263. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system.egg-info/SOURCES.txt +0 -0
  264. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system.egg-info/dependency_links.txt +0 -0
  265. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system.egg-info/entry_points.txt +0 -0
  266. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system.egg-info/requires.txt +0 -0
  267. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/smart_spatial_system.egg-info/top_level.txt +0 -0
  268. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/templates/__init__.py +0 -0
  269. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/templates/reports/__init__.py +0 -0
  270. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/templates/reports/real_estate_report.html +0 -0
  271. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_accessibility_query_spec.py +0 -0
  272. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_auth.py +0 -0
  273. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_contract_smoke.py +0 -0
  274. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_data_source_connectors_e2e.py +0 -0
  275. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_map_layers.py +0 -0
  276. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_mvp.py +0 -0
  277. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_outputs.py +0 -0
  278. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_projects.py +0 -0
  279. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_structured_error_normalization.py +0 -0
  280. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_upload_plugin_resolver.py +0 -0
  281. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_api_uploads.py +0 -0
  282. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_area_perimeter_calc.py +0 -0
  283. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_attribute_statistics.py +0 -0
  284. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_band_math.py +0 -0
  285. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_buffer_analysis.py +0 -0
  286. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_centroid_extractor.py +0 -0
  287. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_cli.py +0 -0
  288. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_crs_transformer.py +0 -0
  289. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_data_source_service.py +0 -0
  290. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_data_writer_exporter.py +0 -0
  291. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_deterministic_planner.py +0 -0
  292. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_dissolve_aggregator.py +0 -0
  293. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_distance_calculator.py +0 -0
  294. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_document_file_report_contract.py +0 -0
  295. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_end_to_end_natural_query_pipeline.py +0 -0
  296. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_error_contract.py +0 -0
  297. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_feature_enrichment.py +0 -0
  298. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_frontend_api_surface_contract.py +0 -0
  299. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_geocoding_resolver.py +0 -0
  300. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_geocoding_resolver_error_redaction.py +0 -0
  301. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_geometry_validator.py +0 -0
  302. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_input_error_mapping.py +0 -0
  303. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_input_reference_resolver.py +0 -0
  304. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_input_reference_resolver_contract.py +0 -0
  305. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_kernel_artifacts.py +0 -0
  306. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_kernel_execution_bridge.py +0 -0
  307. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_kernel_plan_adapter.py +0 -0
  308. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_llm_intent_adapter.py +0 -0
  309. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_llm_raster_queryspec_normalization.py +0 -0
  310. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_llm_spec_generator_prenormalize.py +0 -0
  311. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_llm_spec_generator_semantic_context.py +0 -0
  312. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_llm_spec_generator_semantic_query_database_enrich.py +0 -0
  313. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_llm_spec_generator_semantic_queryspec_repair.py +0 -0
  314. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_loader_plugin_contract.py +0 -0
  315. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_local_path_validation.py +0 -0
  316. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_local_raster_loader.py +0 -0
  317. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_local_raster_loader_contract.py +0 -0
  318. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_local_vector_loader.py +0 -0
  319. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_local_vector_loader_contract.py +0 -0
  320. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_map_layer_contract.py +0 -0
  321. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_map_layer_service.py +0 -0
  322. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_ndvi_calculator.py +0 -0
  323. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_nearest_neighbor.py +0 -0
  324. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_numeric_validation.py +0 -0
  325. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_op_catalog_semantic_aliases.py +0 -0
  326. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_audit.py +0 -0
  327. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_audit_integration.py +0 -0
  328. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_data_source_service_integration.py +0 -0
  329. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_feedback.py +0 -0
  330. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_feedback_integration.py +0 -0
  331. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_keyword_scoring_router.py +0 -0
  332. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_learning_signals.py +0 -0
  333. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_learning_signals_integration.py +0 -0
  334. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_llm_gate.py +0 -0
  335. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_llm_gate_integration.py +0 -0
  336. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_map_layer_service_integration.py +0 -0
  337. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_natural_query_pipeline.py +0 -0
  338. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_output_service_integration.py +0 -0
  339. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_production_response.py +0 -0
  340. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_production_response_integration.py +0 -0
  341. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_project_service_integration.py +0 -0
  342. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_query_execution_service_integration.py +0 -0
  343. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_registry_router.py +0 -0
  344. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_router_decision.py +0 -0
  345. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_router_decision_integration.py +0 -0
  346. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_routing_aware_plan_builder.py +0 -0
  347. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_runtime_paths.py +0 -0
  348. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_service.py +0 -0
  349. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_service_domain_boundary_contract.py +0 -0
  350. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_service_integration.py +0 -0
  351. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_service_postgis_dedup_contract.py +0 -0
  352. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_statistics.py +0 -0
  353. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_statistics_integration.py +0 -0
  354. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_upload_service_integration.py +0 -0
  355. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_weight_proposals.py +0 -0
  356. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_weight_proposals_integration.py +0 -0
  357. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_weight_store_persistence.py +0 -0
  358. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_weight_store_persistence_integration.py +0 -0
  359. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_weighted_router.py +0 -0
  360. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_orchestrator_weighted_router_integration.py +0 -0
  361. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_output_service.py +0 -0
  362. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_output_storage.py +0 -0
  363. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_pdf_renderer.py +0 -0
  364. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_phase3_kernel_registry_coverage.py +0 -0
  365. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_phase3_output_parity.py +0 -0
  366. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_phase3_postgis_provider_kernel_execution.py +0 -0
  367. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_planning_dag_executor.py +0 -0
  368. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_planning_dag_executor_async_capability.py +0 -0
  369. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_planning_error_mapping.py +0 -0
  370. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_planning_execution_policy.py +0 -0
  371. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_planning_raster_op_catalog_mapping.py +0 -0
  372. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_planning_raster_queryspec_execution.py +0 -0
  373. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_planning_registry_backed_raster_execution.py +0 -0
  374. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_planning_registry_backed_real_estate_execution.py +0 -0
  375. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_planning_runner.py +0 -0
  376. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_plugin_boundary_contract.py +0 -0
  377. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_plugin_config.py +0 -0
  378. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_plugin_config_store.py +0 -0
  379. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_plugin_error_mapping.py +0 -0
  380. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_plugin_modules.py +0 -0
  381. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_postgis_connector.py +0 -0
  382. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_postgis_connector_percent_escape.py +0 -0
  383. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_postgis_semantic_resolver.py +0 -0
  384. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_project_service.py +0 -0
  385. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_project_store.py +0 -0
  386. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_provider_error_mapping.py +0 -0
  387. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_query_dispatch_domain_boundary_contract.py +0 -0
  388. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_query_execution_postgis_planning_context.py +0 -0
  389. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_query_execution_service.py +0 -0
  390. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_query_execution_service_domain_import_boundary_contract.py +0 -0
  391. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_query_response_shape_golden.py +0 -0
  392. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_query_spec_enrichment.py +0 -0
  393. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_raster_capability_registry_contract.py +0 -0
  394. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_raster_clip_mask.py +0 -0
  395. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_raster_reclassify.py +0 -0
  396. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_raster_statistics.py +0 -0
  397. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_raster_threshold.py +0 -0
  398. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_raster_to_vector.py +0 -0
  399. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_real_estate_ranking_bridge.py +0 -0
  400. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_real_estate_ranking_golden.py +0 -0
  401. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_real_estate_ranking_query_spec_planning.py +0 -0
  402. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_real_estate_scoring_plugin.py +0 -0
  403. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_real_estate_spatial_enrichment_plugin.py +0 -0
  404. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_real_estate_spatial_helpers.py +0 -0
  405. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_report_builder.py +0 -0
  406. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_report_spec.py +0 -0
  407. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_request_document_download_contract.py +0 -0
  408. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_response_assembler.py +0 -0
  409. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_response_output_contract.py +0 -0
  410. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_risk_enrichment.py +0 -0
  411. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_runtime_paths.py +0 -0
  412. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_semantic_planning_context.py +0 -0
  413. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_service_auto_postgis_semantic_context.py +0 -0
  414. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_service_planning_artifacts.py +0 -0
  415. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_service_postgis_runtime_connection_injection.py +0 -0
  416. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_service_semantic_planning_context.py +0 -0
  417. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_service_strict_loader_contract.py +0 -0
  418. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_service_structured_error_normalization.py +0 -0
  419. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_slope_aspect.py +0 -0
  420. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_spatial_intersection.py +0 -0
  421. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_spatial_join.py +0 -0
  422. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_spatial_query_filter.py +0 -0
  423. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_spectral_indices.py +0 -0
  424. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_system_status_query_handler.py +0 -0
  425. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_upload_service.py +0 -0
  426. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_upload_storage.py +0 -0
  427. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_vector_display_handler.py +0 -0
  428. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_vector_geojson_helpers.py +0 -0
  429. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_vector_query_classifier.py +0 -0
  430. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_wms_wfs_fetcher.py +0 -0
  431. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_wms_wfs_fetcher_error_redaction.py +0 -0
  432. {smart_spatial_system-0.2.3 → smart_spatial_system-0.2.4}/tests/test_zonal_statistics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smart_spatial_system
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Plugin-based GeoAI backend: natural-language questions become QuerySpecs, DAG plans, and map/table/report outputs.
5
5
  Author: Araz Shah
6
6
  License-Expression: MIT
@@ -1071,6 +1071,21 @@ Important mappings:
1071
1071
  - "score/rank":
1072
1072
  use score_features then rank_features.
1073
1073
 
1074
+ - CRITICAL - every scoring factor MUST include an explicit "type". There is
1075
+ NO default - a factor with no "type" is rejected, it does not fall back
1076
+ to anything. (An earlier version of this system defaulted a missing
1077
+ "type" to "boolean" silently; for a distance field that meant every
1078
+ score came out 0.0 for every feature, with no error - that default no
1079
+ longer exists.) Valid types: "boolean", "boolean_bonus",
1080
+ "inverse_distance", "risk_level", "inverse_level", "threshold",
1081
+ "condition", "direct", "numeric", "inverse_numeric". A distance field
1082
+ (anything you computed with spatial_nearest/nearest_neighbor/distance_to)
1083
+ needs "type": "inverse_distance" and a numeric "max_distance":
1084
+ {{"name": "near_metro", "field": "distance_to_metro",
1085
+ "type": "inverse_distance", "max_distance": 800, "weight": 1}}
1086
+ WRONG (missing "type" - rejected, not defaulted):
1087
+ {{"field": "distance_to_metro", "weight": -1}}
1088
+
1074
1089
  - CRITICAL - scoring against MORE THAN ONE computed field (e.g. distance to
1075
1090
  several different amenities/references): each computation must be CHAINED
1076
1091
  onto the previous one's output, not all computed separately from the
@@ -1686,12 +1701,12 @@ def _validate_operation_input_roles(spec: QuerySpec) -> None:
1686
1701
  _NEAREST_OPS_WITH_DISTANCE_FIELD = {"spatial_nearest", "nearest_neighbor", "filter_by_distance"}
1687
1702
 
1688
1703
 
1689
- def _extract_scoring_factor_fields(params: dict[str, Any]) -> list[str]:
1704
+ def _extract_scoring_factors(params: dict[str, Any]) -> list[dict[str, Any]]:
1690
1705
  """
1691
- Pull the "field" name out of every factor a score_features op's
1692
- params declare, across the shapes _normalize_scoring_spec (in
1693
- plugins/feature_scoring.py) accepts: top-level "factors", or
1694
- "scoring_spec.factors", or the older nested "scoring_spec.scoring.factors".
1706
+ Pull the raw factor dicts out of a score_features op's params, across
1707
+ the shapes _normalize_scoring_spec (in plugins/feature_scoring.py)
1708
+ accepts: top-level "factors", or "scoring_spec.factors", or the older
1709
+ nested "scoring_spec.scoring.factors".
1695
1710
  """
1696
1711
  factors = params.get("factors")
1697
1712
 
@@ -1707,10 +1722,19 @@ def _extract_scoring_factor_fields(params: dict[str, Any]) -> list[str]:
1707
1722
  if not isinstance(factors, list):
1708
1723
  return []
1709
1724
 
1725
+ return [factor for factor in factors if isinstance(factor, dict)]
1726
+
1727
+
1728
+ def _extract_scoring_factor_fields(params: dict[str, Any]) -> list[str]:
1729
+ """
1730
+ Pull the "field" name out of every factor a score_features op's
1731
+ params declare - see _extract_scoring_factors for the shapes this
1732
+ covers.
1733
+ """
1710
1734
  return [
1711
1735
  str(factor["field"])
1712
- for factor in factors
1713
- if isinstance(factor, dict) and factor.get("field")
1736
+ for factor in _extract_scoring_factors(params)
1737
+ if factor.get("field")
1714
1738
  ]
1715
1739
 
1716
1740
 
@@ -1770,6 +1794,64 @@ def _ancestor_refs(start_ref: str, ops_by_output: dict[str, OperationSpec]) -> s
1770
1794
  return seen
1771
1795
 
1772
1796
 
1797
+ # Kept in sync by hand with plugins/feature_scoring.py's _score_factor -
1798
+ # there is no single source of truth to generate this from (unlike
1799
+ # OP_CATALOG for operations), so a new factor type added there needs
1800
+ # adding here too.
1801
+ _VALID_SCORING_FACTOR_TYPES = {
1802
+ "boolean",
1803
+ "boolean_bonus",
1804
+ "inverse_distance",
1805
+ "risk_level",
1806
+ "inverse_level",
1807
+ "threshold",
1808
+ "condition",
1809
+ "direct",
1810
+ "numeric",
1811
+ "inverse_numeric",
1812
+ }
1813
+
1814
+
1815
+ def _validate_score_features_factor_types(spec: QuerySpec) -> None:
1816
+ """
1817
+ Catch a score_features factor with no "type" before the plan is
1818
+ returned, not when it silently scores everything 0.0.
1819
+
1820
+ plugins/feature_scoring.py's _score_factor has no default for a
1821
+ missing "type" (it raises) - but that only fires at execution time,
1822
+ several steps and possibly minutes of API-billed retries away from
1823
+ the generation step that produced the bad spec. This catches the
1824
+ identical condition immediately, with the same "there is no safe
1825
+ default" reasoning, right where the LLM's output is still available
1826
+ to name in the error.
1827
+ """
1828
+ for op in spec.operations:
1829
+ if op.op != "score_features":
1830
+ continue
1831
+
1832
+ for factor in _extract_scoring_factors(op.params):
1833
+ factor_type = factor.get("type")
1834
+ field_name = factor.get("field") or factor.get("name") or "<unnamed>"
1835
+
1836
+ if not factor_type:
1837
+ raise LLMSpecGenerationError(
1838
+ f"score_features (output={op.output!r}) has a factor "
1839
+ f"for field {field_name!r} with no 'type'. There is no "
1840
+ "safe default - every factor must specify one "
1841
+ f"explicitly: {sorted(_VALID_SCORING_FACTOR_TYPES)!r}. "
1842
+ "A distance field almost always wants "
1843
+ "'inverse_distance' with 'max_distance' set."
1844
+ )
1845
+
1846
+ if factor_type not in _VALID_SCORING_FACTOR_TYPES:
1847
+ raise LLMSpecGenerationError(
1848
+ f"score_features (output={op.output!r}) has a factor "
1849
+ f"for field {field_name!r} with unsupported type "
1850
+ f"{factor_type!r}. Valid types: "
1851
+ f"{sorted(_VALID_SCORING_FACTOR_TYPES)!r}."
1852
+ )
1853
+
1854
+
1773
1855
  def _validate_score_features_field_chaining(spec: QuerySpec) -> None:
1774
1856
  """
1775
1857
  Catch a score_features op reading from a ref that never accumulated a
@@ -1854,25 +1936,48 @@ def _crs_transform_target_crs(
1854
1936
  ref: str, ops_by_output: dict[str, OperationSpec]
1855
1937
  ) -> str | None:
1856
1938
  """
1857
- The target_crs a ref was reprojected to, if ref is literally the
1858
- output of a crs_transform operation - None otherwise (ref is a raw
1859
- entity, or the output of some other operation).
1860
-
1861
- Deliberately not a full ancestor walk (contrast _ancestor_refs): this
1862
- only recognizes reprojection immediately before the distance op, which
1863
- is exactly the shape both the correct pattern
1864
- (accessibility_query_spec.py) and the observed bug produce - crs_transform
1865
- feeding straight into the distance operation. Walking further back
1866
- would let this claim to know a ref's CRS through operations that don't
1867
- preserve one (a join, a filter combining two layers), which is a
1868
- guess this module has no basis for making.
1939
+ The target_crs a ref was reprojected to - either directly (ref is the
1940
+ output of a crs_transform operation), or inherited by walking back
1941
+ through a chain of distance/nearest-neighbor operations on their
1942
+ source side, since those operations don't reproject and so preserve
1943
+ whatever CRS their source input was already in.
1944
+
1945
+ That chain-walk matters for exactly the case
1946
+ accessibility_query_spec.py's own multi-amenity chain produces (and
1947
+ any equivalent LLM-generated chain): only the FIRST spatial_nearest
1948
+ step's source is directly a crs_transform output -
1949
+ "sites_metric" -> spatial_nearest(metro) -> "sites_with_metro" ->
1950
+ spatial_nearest(schools, source="sites_with_metro") -> ... - every
1951
+ later step's source is the previous step's output, not a
1952
+ crs_transform output. An earlier version of this function checked
1953
+ only the literal ref and treated every one of those later steps as
1954
+ "not traceable", which made this validator raise on a plan that was
1955
+ completely correct - caught by testing this exact function against
1956
+ accessibility_query_spec.py's own generated chain, not by inspection.
1957
+
1958
+ Still deliberately narrow on the OTHER side, though: this only walks
1959
+ through the vector-preserving "source" role of a chain of distance
1960
+ ops, never through a join, a filter combining two layers, or any
1961
+ other operation that doesn't obviously preserve a single input's CRS -
1962
+ those remain untraceable (None), which is the conservative direction
1963
+ to be wrong in.
1869
1964
  """
1870
1965
  op = ops_by_output.get(ref)
1871
- if op is None or op.op != "crs_transform":
1966
+ if op is None:
1872
1967
  return None
1873
1968
 
1874
- target_crs = op.params.get("target_crs")
1875
- return str(target_crs) if target_crs else None
1969
+ if op.op == "crs_transform":
1970
+ target_crs = op.params.get("target_crs")
1971
+ return str(target_crs) if target_crs else None
1972
+
1973
+ roles = _DISTANCE_OPS_VECTOR_ROLES.get(op.op)
1974
+ if roles is not None:
1975
+ this_role, _other_role = roles
1976
+ upstream_ref = op.inputs.get(this_role)
1977
+ if upstream_ref:
1978
+ return _crs_transform_target_crs(str(upstream_ref), ops_by_output)
1979
+
1980
+ return None
1876
1981
 
1877
1982
 
1878
1983
  def _validate_distance_op_crs_symmetry(spec: QuerySpec) -> None:
@@ -1982,6 +2087,7 @@ class LLMQuerySpecGenerator:
1982
2087
  spec = query_spec_from_dict(data, raw_query_fallback=raw_query)
1983
2088
  spec = normalize_llm_query_spec_for_planning(spec)
1984
2089
  _validate_operation_input_roles(spec)
2090
+ _validate_score_features_factor_types(spec)
1985
2091
  _validate_score_features_field_chaining(spec)
1986
2092
  _validate_distance_op_crs_symmetry(spec)
1987
2093
  return spec
@@ -228,7 +228,29 @@ def _score_factor(properties: dict[str, Any], factor: dict[str, Any]) -> tuple[f
228
228
  if not isinstance(factor, dict):
229
229
  raise ValueError("Each scoring factor must be a dict.")
230
230
 
231
- factor_type = str(factor.get("type") or "boolean")
231
+ raw_factor_type = factor.get("type")
232
+ if not raw_factor_type:
233
+ # A missing "type" used to default to "boolean" silently. For any
234
+ # factor scoring a non-boolean field - a distance, most commonly -
235
+ # that produces a wrong, near-constant score (0.0 whenever the
236
+ # field is falsy, which for a distance means "exactly zero") with
237
+ # no error at all: this is how a whole batch of LLM-generated
238
+ # scoring specs that omitted "type" on a distance factor came out
239
+ # 0.0 for every feature, indistinguishable from a real degenerate
240
+ # result. "boolean" is a valid, explicit choice (still supported
241
+ # below) - it must never be the unstated default for a field whose
242
+ # actual meaning this function has no way to guess.
243
+ field_name = factor.get("field") or factor.get("name") or "<unnamed>"
244
+ raise ValueError(
245
+ f"Scoring factor for field {field_name!r} has no 'type'. There "
246
+ "is no safe default - specify one explicitly: 'boolean', "
247
+ "'boolean_bonus', 'inverse_distance', 'risk_level', "
248
+ "'inverse_level', 'threshold', 'condition', 'direct', "
249
+ "'numeric', or 'inverse_numeric'. A distance field almost "
250
+ "always wants 'inverse_distance' with 'max_distance' set."
251
+ )
252
+
253
+ factor_type = str(raw_factor_type)
232
254
  name = str(factor.get("name") or factor.get("field") or factor_type)
233
255
  field = str(factor.get("field") or "")
234
256
  value = _get_property(properties, field) if field else None
@@ -12,7 +12,7 @@ build-backend = "setuptools.build_meta"
12
12
  # "Open design questions" for why a namespace migration was deliberately
13
13
  # not done here.
14
14
  name = "smart_spatial_system"
15
- version = "0.2.3"
15
+ version = "0.2.4"
16
16
  description = "Plugin-based GeoAI backend: natural-language questions become QuerySpecs, DAG plans, and map/table/report outputs."
17
17
  readme = "README.md"
18
18
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smart_spatial_system
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Plugin-based GeoAI backend: natural-language questions become QuerySpecs, DAG plans, and map/table/report outputs.
5
5
  Author: Araz Shah
6
6
  License-Expression: MIT
@@ -1,6 +1,8 @@
1
1
  import sys
2
2
  from pathlib import Path
3
3
 
4
+ import pytest
5
+
4
6
  ROOT = Path(__file__).resolve().parents[1]
5
7
  if str(ROOT) not in sys.path:
6
8
  sys.path.insert(0, str(ROOT))
@@ -115,3 +117,45 @@ def test_op_catalog_contains_feature_scoring_ops():
115
117
 
116
118
  assert score_op.capability_name == "score_features"
117
119
  assert rank_op.capability_name == "rank_features"
120
+
121
+
122
+ # ------------------------------------------------------------------ #
123
+ # Missing "type" on a scoring factor: no silent default
124
+ # ------------------------------------------------------------------ #
125
+
126
+ def test_score_features_raises_when_a_factor_has_no_type():
127
+ """
128
+ Regression test: a missing "type" used to default to "boolean"
129
+ silently. For a distance field, _truthy(0.0) is False and
130
+ _truthy(any nonzero distance) is True, so every feature ended up with
131
+ a near-constant, meaningless score instead of an error - exactly how
132
+ a full batch of LLM-generated scoring specs that omitted "type" on a
133
+ distance factor came out 0.0 for every feature.
134
+ """
135
+ spec = {
136
+ "output_field": "score",
137
+ "factors": [
138
+ {"field": "distance_to_poi", "weight": 1},
139
+ ],
140
+ }
141
+
142
+ with pytest.raises(ValueError, match="distance_to_poi"):
143
+ score_features(_sample_features(), scoring_spec=spec)
144
+
145
+
146
+ def test_score_features_boolean_type_still_works_when_explicit():
147
+ """
148
+ "boolean" itself is a perfectly valid, still-supported type - only an
149
+ UNSTATED type is rejected.
150
+ """
151
+ spec = {
152
+ "output_field": "score",
153
+ "factors": [
154
+ {"field": "__in_polygon__", "type": "boolean", "weight": 1},
155
+ ],
156
+ }
157
+
158
+ result = score_features(_sample_features(), scoring_spec=spec)
159
+ a = result.features[0]["properties"]
160
+ b = result.features[1]["properties"]
161
+ assert a["score"] > b["score"]
@@ -1306,3 +1306,133 @@ def test_domain_guidance_documents_reprojecting_both_sides_of_a_distance_op():
1306
1306
 
1307
1307
  assert "needs BOTH of" in system_prompt
1308
1308
  assert "target_crs" in system_prompt
1309
+
1310
+
1311
+ # ------------------------------------------------------------------ #
1312
+ # Bug 6: a scoring factor with no "type" used to default to "boolean"
1313
+ # ------------------------------------------------------------------ #
1314
+
1315
+ def _multi_amenity_chained_ops(factor_params: dict) -> list[dict]:
1316
+ """
1317
+ The exact plan shape from the reported case: four layers correctly
1318
+ reprojected to the same CRS, three spatial_nearest steps correctly
1319
+ chained (Bug 4's and Bug 5's fixes both satisfied) - only the
1320
+ score_features factors are missing "type".
1321
+ """
1322
+ return [
1323
+ {"op": "crs_transform", "inputs": {"vector": "sites"}, "params": {"target_crs": "EPSG:31256"}, "output": "sites_metric"},
1324
+ {"op": "crs_transform", "inputs": {"vector": "metro"}, "params": {"target_crs": "EPSG:31256"}, "output": "metro_metric"},
1325
+ {"op": "crs_transform", "inputs": {"vector": "schools"}, "params": {"target_crs": "EPSG:31256"}, "output": "schools_metric"},
1326
+ {"op": "crs_transform", "inputs": {"vector": "parks"}, "params": {"target_crs": "EPSG:31256"}, "output": "parks_metric"},
1327
+ {"op": "spatial_nearest", "inputs": {"source": "sites_metric", "target": "metro_metric"}, "params": {"distance_field": "distance_to_metro"}, "output": "sites_with_metro"},
1328
+ {"op": "spatial_nearest", "inputs": {"source": "sites_with_metro", "target": "schools_metric"}, "params": {"distance_field": "distance_to_schools"}, "output": "sites_with_schools"},
1329
+ {"op": "spatial_nearest", "inputs": {"source": "sites_with_schools", "target": "parks_metric"}, "params": {"distance_field": "distance_to_parks"}, "output": "sites_with_parks"},
1330
+ {
1331
+ "op": "score_features",
1332
+ "inputs": {"vector": "sites_with_parks"},
1333
+ "params": {
1334
+ "factors": [
1335
+ {"field": "distance_to_metro", **factor_params},
1336
+ {"field": "distance_to_schools", **factor_params},
1337
+ {"field": "distance_to_parks", **factor_params},
1338
+ ]
1339
+ },
1340
+ "output": "scored_sites",
1341
+ },
1342
+ {"op": "rank_features", "inputs": {"vector": "scored_sites"}, "params": {"score_field": "score", "rank_field": "rank"}, "output": "ranked_sites"},
1343
+ ]
1344
+
1345
+
1346
+ def _multi_amenity_spec_json(factor_params: dict) -> dict:
1347
+ return {
1348
+ "raw_query": "rank sites by accessibility",
1349
+ "goal": "score_accessibility",
1350
+ "entities": [
1351
+ {"ref": "sites", "kind": "vector"},
1352
+ {"ref": "metro", "kind": "vector"},
1353
+ {"ref": "schools", "kind": "vector"},
1354
+ {"ref": "parks", "kind": "vector"},
1355
+ ],
1356
+ "operations": _multi_amenity_chained_ops(factor_params),
1357
+ "outputs": [{"kind": "vector", "source": "ranked_sites"}],
1358
+ }
1359
+
1360
+
1361
+ def test_generate_raises_when_a_scoring_factor_has_no_type():
1362
+ """
1363
+ Regression test for the exact reported case: a plan with correct
1364
+ chaining (Bug 4) and correct, symmetric CRS reprojection (Bug 5) still
1365
+ came back degenerate - all 20/20 runs in the batch that surfaced this
1366
+ scored every feature 0.0, because every factor omitted "type" and it
1367
+ silently defaulted to "boolean". Must now raise before the plan is
1368
+ even returned.
1369
+ """
1370
+ llm_json = _multi_amenity_spec_json({"weight": -1})
1371
+
1372
+ client = StaticLLMClient(json.dumps(llm_json, ensure_ascii=False))
1373
+ generator = LLMQuerySpecGenerator(client)
1374
+
1375
+ with pytest.raises(LLMSpecGenerationError, match="no 'type'"):
1376
+ generator.generate("rank sites by accessibility")
1377
+
1378
+
1379
+ def test_generate_raises_on_an_unsupported_factor_type():
1380
+ llm_json = _multi_amenity_spec_json({"type": "made_up_type", "weight": 1})
1381
+
1382
+ client = StaticLLMClient(json.dumps(llm_json, ensure_ascii=False))
1383
+ generator = LLMQuerySpecGenerator(client)
1384
+
1385
+ with pytest.raises(LLMSpecGenerationError, match="unsupported type"):
1386
+ generator.generate("rank sites by accessibility")
1387
+
1388
+
1389
+ def test_generate_accepts_a_correct_multi_amenity_chain_with_explicit_types():
1390
+ """
1391
+ The fully-correct equivalent of the reported plan: chained, CRS-matched,
1392
+ and every factor carries an explicit type. This is also the regression
1393
+ test for a real false positive found while verifying this fix: an
1394
+ earlier version of _validate_distance_op_crs_symmetry only recognized
1395
+ a ref as reprojected when it was DIRECTLY a crs_transform output, so it
1396
+ incorrectly rejected the second and third spatial_nearest steps in
1397
+ exactly this chain (their source is the previous step's output, not a
1398
+ crs_transform output) - a plan structurally identical to
1399
+ accessibility_query_spec.py's own generated chain.
1400
+ """
1401
+ llm_json = _multi_amenity_spec_json(
1402
+ {"type": "inverse_distance", "max_distance": 1000, "weight": 1}
1403
+ )
1404
+
1405
+ client = StaticLLMClient(json.dumps(llm_json, ensure_ascii=False))
1406
+ spec = LLMQuerySpecGenerator(client).generate("rank sites by accessibility")
1407
+
1408
+ assert [op.op for op in spec.operations] == [
1409
+ "crs_transform",
1410
+ "crs_transform",
1411
+ "crs_transform",
1412
+ "crs_transform",
1413
+ "spatial_nearest",
1414
+ "spatial_nearest",
1415
+ "spatial_nearest",
1416
+ "score_features",
1417
+ "rank_features",
1418
+ ]
1419
+
1420
+ plan = DeterministicPlanner().build(spec)
1421
+ assert [node.capability_name for node in plan.nodes] == [
1422
+ "transform_vector_crs",
1423
+ "transform_vector_crs",
1424
+ "transform_vector_crs",
1425
+ "transform_vector_crs",
1426
+ "find_nearest_neighbors",
1427
+ "find_nearest_neighbors",
1428
+ "find_nearest_neighbors",
1429
+ "score_features",
1430
+ "rank_features",
1431
+ ]
1432
+
1433
+
1434
+ def test_domain_guidance_documents_that_factor_type_has_no_default():
1435
+ system_prompt = build_llm_messages("q")[0]["content"]
1436
+
1437
+ assert "NO default" in system_prompt
1438
+ assert "inverse_distance" in system_prompt