pyterrainMap 1.0.0__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 (98) hide show
  1. pyterrainmap-1.0.0/.gitignore +76 -0
  2. pyterrainmap-1.0.0/AI_INTEGRATION.md +488 -0
  3. pyterrainmap-1.0.0/ARCHITECTURE.md +547 -0
  4. pyterrainmap-1.0.0/ARCHITECTURE_BOUNDARIES.md +437 -0
  5. pyterrainmap-1.0.0/ARCHITECTURE_COMPLETE_WEEK19.md +502 -0
  6. pyterrainmap-1.0.0/BANDWIDTH_OPTIMIZATION.md +526 -0
  7. pyterrainmap-1.0.0/Cargo.lock +3552 -0
  8. pyterrainmap-1.0.0/Cargo.toml +87 -0
  9. pyterrainmap-1.0.0/DATA_INTEGRITY.md +815 -0
  10. pyterrainmap-1.0.0/DOCUMENTATION_INDEX.md +254 -0
  11. pyterrainmap-1.0.0/GETTING_STARTED.md +803 -0
  12. pyterrainmap-1.0.0/IMPLEMENTATION_ROADMAP.md +670 -0
  13. pyterrainmap-1.0.0/INSTALLATION.md +388 -0
  14. pyterrainmap-1.0.0/LAYERED_CACHING_ARCHITECTURE.md +636 -0
  15. pyterrainmap-1.0.0/LICENSE +21 -0
  16. pyterrainmap-1.0.0/OSS_POLICY.md +350 -0
  17. pyterrainmap-1.0.0/PARALLEL_INFERENCE_ARCHITECTURE.md +726 -0
  18. pyterrainmap-1.0.0/PKG-INFO +459 -0
  19. pyterrainmap-1.0.0/PREDICTIVE_CACHING_ARCHITECTURE.md +647 -0
  20. pyterrainmap-1.0.0/PRODUCTION_STORAGE_ARCHITECTURE.md +1195 -0
  21. pyterrainmap-1.0.0/PYPROJECT_SETUP.md +248 -0
  22. pyterrainmap-1.0.0/PYTHON_BINDINGS.md +402 -0
  23. pyterrainmap-1.0.0/README.md +407 -0
  24. pyterrainmap-1.0.0/READY_TO_BUILD.md +239 -0
  25. pyterrainmap-1.0.0/REPRESENTATION_TYPE_SYSTEM.md +647 -0
  26. pyterrainmap-1.0.0/ROS_BRIDGE_ARCHITECTURE.md +437 -0
  27. pyterrainmap-1.0.0/ROS_BRIDGE_DELIVERY.md +417 -0
  28. pyterrainmap-1.0.0/ROS_BRIDGE_IMPLEMENTATION_COMPLETE.md +562 -0
  29. pyterrainmap-1.0.0/ROS_MOVEIT_INTEGRATION.md +723 -0
  30. pyterrainmap-1.0.0/SECURITY_AUDITABILITY_ARCHITECTURE.md +946 -0
  31. pyterrainmap-1.0.0/SESSION_WEEK19_COMPLETE.md +344 -0
  32. pyterrainmap-1.0.0/SIMULATION_INTEGRATION.md +662 -0
  33. pyterrainmap-1.0.0/TEMPORAL_NORMALIZATION.md +371 -0
  34. pyterrainmap-1.0.0/UNIVERSAL_ROBOT_INTEROPERABILITY.md +744 -0
  35. pyterrainmap-1.0.0/VISION.md +352 -0
  36. pyterrainmap-1.0.0/WEEK19_SUMMARY.md +310 -0
  37. pyterrainmap-1.0.0/pyproject.toml +140 -0
  38. pyterrainmap-1.0.0/pyterrainmap/okf_sensor_profiles.py +70 -0
  39. pyterrainmap-1.0.0/python/examples/basic_analysis.py +23 -0
  40. pyterrainmap-1.0.0/python/pyterrain_map/__init__.py +83 -0
  41. pyterrainmap-1.0.0/python/pyterrain_map/api.py +285 -0
  42. pyterrainmap-1.0.0/python/pyterrain_map/cli.py +131 -0
  43. pyterrainmap-1.0.0/python/pyterrain_map/setup_wizard.py +467 -0
  44. pyterrainmap-1.0.0/python/pyterrain_map/statguardian_integration.py +329 -0
  45. pyterrainmap-1.0.0/python/pyterrain_map/storage/__init__.py +21 -0
  46. pyterrainmap-1.0.0/python/pyterrain_map/storage/adls.py +319 -0
  47. pyterrainmap-1.0.0/python/pyterrain_map/storage/base.py +260 -0
  48. pyterrainmap-1.0.0/python/pyterrain_map/storage/gcs.py +271 -0
  49. pyterrainmap-1.0.0/python/pyterrain_map/storage/local.py +249 -0
  50. pyterrainmap-1.0.0/python/pyterrain_map/storage/s3.py +287 -0
  51. pyterrainmap-1.0.0/python/pyterrain_ros/__init__.py +14 -0
  52. pyterrainmap-1.0.0/python/pyterrain_ros/adapters/__init__.py +11 -0
  53. pyterrainmap-1.0.0/python/pyterrain_ros/adapters/base.py +98 -0
  54. pyterrainmap-1.0.0/python/pyterrain_ros/adapters/lidar.py +230 -0
  55. pyterrainmap-1.0.0/python/pyterrain_ros/adapters/thermal.py +201 -0
  56. pyterrainmap-1.0.0/python/pyterrain_ros/platforms/__init__.py +228 -0
  57. pyterrainmap-1.0.0/python/pyterrain_ros/transforms/__init__.py +14 -0
  58. pyterrainmap-1.0.0/python/pyterrain_ros/transforms/coordinate_frames.py +310 -0
  59. pyterrainmap-1.0.0/python/pyterrain_ros/transforms/tf_listener.py +331 -0
  60. pyterrainmap-1.0.0/quality_contracts/multi_sensor_consistency.yaml +68 -0
  61. pyterrainmap-1.0.0/quality_contracts/sensor_calibration.yaml +74 -0
  62. pyterrainmap-1.0.0/quality_contracts/temporal_coordinates.yaml +74 -0
  63. pyterrainmap-1.0.0/quality_contracts/terrain_anomalies.yaml +80 -0
  64. pyterrainmap-1.0.0/src/anomaly/mod.rs +578 -0
  65. pyterrainmap-1.0.0/src/api/mod.rs +614 -0
  66. pyterrainmap-1.0.0/src/api_tls/mod.rs +421 -0
  67. pyterrainmap-1.0.0/src/caching/mod.rs +618 -0
  68. pyterrainmap-1.0.0/src/cesium_integration/mod.rs +825 -0
  69. pyterrainmap-1.0.0/src/change_detection/mod.rs +668 -0
  70. pyterrainmap-1.0.0/src/cli/mod.rs +573 -0
  71. pyterrainmap-1.0.0/src/data_sources/mod.rs +568 -0
  72. pyterrainmap-1.0.0/src/export/mod.rs +636 -0
  73. pyterrainmap-1.0.0/src/export_security/mod.rs +500 -0
  74. pyterrainmap-1.0.0/src/fusion/mod.rs +624 -0
  75. pyterrainmap-1.0.0/src/intelligence/mod.rs +775 -0
  76. pyterrainmap-1.0.0/src/lib.rs +213 -0
  77. pyterrainmap-1.0.0/src/parallel_execution/mod.rs +443 -0
  78. pyterrainmap-1.0.0/src/persistence/mod.rs +674 -0
  79. pyterrainmap-1.0.0/src/photogrammetry/mod.rs +684 -0
  80. pyterrainmap-1.0.0/src/predictive_caching/mod.rs +799 -0
  81. pyterrainmap-1.0.0/src/py.rs +56 -0
  82. pyterrainmap-1.0.0/src/py_api.rs +394 -0
  83. pyterrainmap-1.0.0/src/query/mod.rs +360 -0
  84. pyterrainmap-1.0.0/src/reconstruction_3d/mod.rs +551 -0
  85. pyterrainmap-1.0.0/src/reference_images/mod.rs +527 -0
  86. pyterrainmap-1.0.0/src/security/mod.rs +534 -0
  87. pyterrainmap-1.0.0/src/slam/mod.rs +520 -0
  88. pyterrainmap-1.0.0/src/spatial/mod.rs +310 -0
  89. pyterrainmap-1.0.0/src/spatial_reasoning/mod.rs +525 -0
  90. pyterrainmap-1.0.0/src/storage/backends.rs +463 -0
  91. pyterrainmap-1.0.0/src/storage/federation.rs +257 -0
  92. pyterrainmap-1.0.0/src/storage/mod.rs +332 -0
  93. pyterrainmap-1.0.0/src/storage/postgres.rs +355 -0
  94. pyterrainmap-1.0.0/src/temporal/mod.rs +351 -0
  95. pyterrainmap-1.0.0/src/tiles_3d/mod.rs +589 -0
  96. pyterrainmap-1.0.0/src/types.rs +609 -0
  97. pyterrainmap-1.0.0/src/weather_soil/mod.rs +807 -0
  98. pyterrainmap-1.0.0/tests/test_statguardian_integration.py +365 -0
@@ -0,0 +1,76 @@
1
+ # Rust
2
+ target/
3
+ Cargo.lock
4
+ **/*.rs.bk
5
+ *.pdb
6
+
7
+ # Python
8
+ __pycache__/
9
+ *.py[cod]
10
+ *$py.class
11
+ *.so
12
+ .Python
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ pip-wheel-metadata/
26
+ share/python-wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+
31
+ # Virtual environments
32
+ venv/
33
+ ENV/
34
+ env/
35
+ .venv
36
+
37
+ # IDEs
38
+ .vscode/
39
+ .idea/
40
+ *.swp
41
+ *.swo
42
+ *~
43
+ .DS_Store
44
+
45
+ # Project-specific
46
+ data/
47
+ output/
48
+ *.log
49
+ .env
50
+ .env.local
51
+ config.local.yaml
52
+
53
+ # Test coverage
54
+ .coverage
55
+ htmlcov/
56
+ .pytest_cache/
57
+ .tox/
58
+
59
+ # Build artifacts
60
+ *.o
61
+ *.a
62
+ *.dylib
63
+ *.dll
64
+ *.so
65
+
66
+ # Database
67
+ *.db
68
+ *.sqlite
69
+ *.sqlite3
70
+
71
+ # Images/cache
72
+ *.jpg
73
+ *.png
74
+ *.tif
75
+ *.tiff
76
+ cache/
@@ -0,0 +1,488 @@
1
+ # AI Integration Design
2
+
3
+ ## Core Principle
4
+
5
+ PyTerrain (PyTerrainMap + PyTerrainAI) is designed to work seamlessly with **both humans and AI systems**:
6
+
7
+ - **Human programmers:** Import as regular Python library, call directly
8
+ - **AI code generators:** Claude Code, Copilot, Codex can generate integration code
9
+ - **Scripts/Bots:** Call via HTTP API or direct library import
10
+ - **Interactive exploration:** Use in Jupyter, REPL, Claude Code notebooks
11
+
12
+ Type hints, documentation, and examples serve both humans and AI equally well.
13
+
14
+ ---
15
+
16
+ ## Design for AI Code Generation
17
+
18
+ ### 1. Type Hints Everywhere
19
+
20
+ AI needs clear type information to generate correct code.
21
+
22
+ ```python
23
+ # ✅ GOOD: AI knows exactly what to pass and what to expect
24
+ async def get_context(
25
+ bot_id: str,
26
+ mission: Mission,
27
+ location: GeoPoint,
28
+ radius_m: float = 50.0,
29
+ ) -> Context:
30
+ """Get mission-aligned context for bot"""
31
+ ...
32
+
33
+ # ❌ BAD: AI might guess wrong
34
+ async def get_context(bot_id, mission, location, radius=50):
35
+ """Get context"""
36
+ ...
37
+ ```
38
+
39
+ ### 2. Clear, Parseable Docstrings
40
+
41
+ AI extracts meaning from docstrings.
42
+
43
+ ```python
44
+ async def get_context(
45
+ bot_id: str,
46
+ mission: Mission,
47
+ location: GeoPoint,
48
+ radius_m: float = 50.0,
49
+ ) -> Context:
50
+ """
51
+ Get mission-aligned, temporal-decayed context for a bot.
52
+
53
+ This method:
54
+ 1. Checks bot permissions for mission
55
+ 2. Queries PyTerrainMap for observations
56
+ 3. Applies temporal decay
57
+ 4. Filters by mission (RBAC)
58
+ 5. Detects anomalies
59
+
60
+ Args:
61
+ bot_id: Unique bot identifier
62
+ mission: Mission type (security, inspection, monitoring, maintenance)
63
+ location: Target location (lat, lon)
64
+ radius_m: Query radius in meters (default 50)
65
+
66
+ Returns:
67
+ Context object with:
68
+ - observations: List of filtered, decayed observations
69
+ - anomalies: List of flagged anomalies
70
+ - suggested_actions: Recommended next steps
71
+ - timestamp: Query execution time
72
+
73
+ Raises:
74
+ PermissionError: If bot not authorized for mission at location
75
+ ValueError: If mission type invalid
76
+
77
+ Example:
78
+ context = await ai.get_context(
79
+ bot_id="security_1",
80
+ mission=Mission.SECURITY,
81
+ location=GeoPoint(40.123, -74.567)
82
+ )
83
+ print(f"Threats: {context.anomalies}")
84
+ """
85
+ ```
86
+
87
+ ### 3. Predictable, Deterministic APIs
88
+
89
+ AI needs to predict outcomes. No hidden state or side effects.
90
+
91
+ ```python
92
+ # ✅ GOOD: Pure function, predictable
93
+ def compute_z_score(value: float, mean: float, std: float) -> float:
94
+ """Compute z-score relative to mean/std"""
95
+ return abs(value - mean) / (std + 1e-6)
96
+
97
+ # ❌ BAD: Hidden state, unpredictable
98
+ def compute_z_score(value):
99
+ return abs(value - self.baseline.mean) / self.baseline.std # Depends on mutable state
100
+ ```
101
+
102
+ ### 4. Rich Examples
103
+
104
+ AI learns by pattern matching. Provide examples for every major flow.
105
+
106
+ ```python
107
+ # examples/security_patrol.py
108
+ async def security_patrol():
109
+ """Example: Security bot conducting patrol"""
110
+
111
+ map_service = PyTerrainMap()
112
+ ai_service = PyTerrainAI(map_service)
113
+
114
+ # Scenario: Security bot exploring Building_A
115
+ bot_id = "security_1"
116
+ building_location = GeoPoint(40.123, -74.567)
117
+
118
+ # Step 1: Plan phase (aerial view)
119
+ context = await ai_service.get_context(
120
+ bot_id=bot_id,
121
+ mission=Mission.SECURITY,
122
+ location=building_location,
123
+ radius_m=100,
124
+ detail_level=DetailLevel.AERIAL
125
+ )
126
+
127
+ # Step 2: Move toward anomalies
128
+ for anomaly in context.anomalies:
129
+ print(f"Investigating {anomaly.description} at {anomaly.location}")
130
+
131
+ # Step 3: Arrive and query detailed view
132
+ detailed = await ai_service.get_context(
133
+ bot_id=bot_id,
134
+ mission=Mission.SECURITY,
135
+ location=anomaly.location,
136
+ detail_level=DetailLevel.DETAILED
137
+ )
138
+
139
+ # Step 4: Report findings
140
+ await map_service.push_observation(Observation(
141
+ robot_id=bot_id,
142
+ location=anomaly.location,
143
+ sensor_type=SensorType.Camera,
144
+ value={"findings": "building_secure"},
145
+ confidence=0.95
146
+ ))
147
+ ```
148
+
149
+ ---
150
+
151
+ ## API Design for AI Consumption
152
+
153
+ ### HTTP REST API (For Agents, Scripts)
154
+
155
+ ```
156
+ POST /context
157
+ {
158
+ "bot_id": "security_1",
159
+ "mission": "security",
160
+ "location": {"lat": 40.123, "lon": -74.567},
161
+ "radius_m": 50.0,
162
+ "detail_level": "regional"
163
+ }
164
+
165
+ Response:
166
+ {
167
+ "timestamp": 1234567890,
168
+ "observations": [
169
+ {
170
+ "sensor_type": "camera",
171
+ "value": {...},
172
+ "confidence": 0.95,
173
+ "temporal_weight": 0.85,
174
+ "status": "verified"
175
+ }
176
+ ],
177
+ "anomalies": [
178
+ {
179
+ "type": "temperature_spike",
180
+ "severity": "high",
181
+ "location": {"lat": 40.124, "lon": -74.568}
182
+ }
183
+ ],
184
+ "suggested_actions": [
185
+ "Investigate thermal anomaly at (40.124, -74.568)",
186
+ "Check obstacle at (40.122, -74.566)"
187
+ ]
188
+ }
189
+ ```
190
+
191
+ ### Python API (For Direct Integration)
192
+
193
+ ```python
194
+ from pyterrain_ai import PyTerrainAI, Mission, DetailLevel
195
+ from pyterrain_map import PyTerrainMap, Observation, SensorType, GeoPoint
196
+
197
+ async def my_autonomous_system():
198
+ """AI system using PyTerrain"""
199
+
200
+ map_svc = PyTerrainMap()
201
+ ai_svc = PyTerrainAI(map_svc)
202
+
203
+ # AI queries map to understand environment
204
+ context = await ai_svc.get_context(
205
+ bot_id="my_bot",
206
+ mission=Mission.INSPECTION,
207
+ location=GeoPoint(40.123, -74.567),
208
+ detail_level=DetailLevel.REGIONAL
209
+ )
210
+
211
+ # AI processes context and makes decisions
212
+ if any(a.severity == "high" for a in context.anomalies):
213
+ print("Found critical issues!")
214
+
215
+ # AI reports findings
216
+ await map_svc.push_observation(Observation(
217
+ robot_id="my_bot",
218
+ location=GeoPoint(40.123, -74.567),
219
+ sensor_type=SensorType.Camera,
220
+ value={"observation": "damage_found"},
221
+ confidence=0.92
222
+ ))
223
+ ```
224
+
225
+ ### OpenAPI Schema (For AI Agents)
226
+
227
+ Auto-generate OpenAPI from Python type hints. Claude Code can read and follow schema.
228
+
229
+ ```yaml
230
+ /context:
231
+ post:
232
+ summary: "Get mission-aligned context for bot"
233
+ parameters:
234
+ - name: bot_id
235
+ type: string
236
+ description: "Unique bot identifier"
237
+ - name: mission
238
+ type: string
239
+ enum: [security, inspection, monitoring, maintenance]
240
+ - name: location
241
+ type: object
242
+ properties:
243
+ lat: number
244
+ lon: number
245
+ responses:
246
+ 200:
247
+ schema: Context
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Integration with Claude Code / Copilot
253
+
254
+ ### Example: Claude Code Generates Inspection Bot
255
+
256
+ **Prompt:**
257
+ ```
258
+ Create an inspection bot that:
259
+ 1. Queries PyTerrainMap for building damage
260
+ 2. Plans inspection route (avoid anomalies)
261
+ 3. Documents findings
262
+ 4. Returns damage report
263
+
264
+ Use PyTerrainAI to get mission context.
265
+ ```
266
+
267
+ **Claude Code generates:**
268
+ ```python
269
+ from pyterrain_ai import PyTerrainAI, Mission, DetailLevel
270
+ from pyterrain_map import PyTerrainMap
271
+
272
+ class InspectionBot:
273
+ def __init__(self, bot_id: str):
274
+ self.bot_id = bot_id
275
+ self.map = PyTerrainMap()
276
+ self.ai = PyTerrainAI(self.map)
277
+
278
+ async def inspect_building(self, location: GeoPoint) -> dict:
279
+ # Query for damage context
280
+ context = await self.ai.get_context(
281
+ bot_id=self.bot_id,
282
+ mission=Mission.INSPECTION,
283
+ location=location,
284
+ detail_level=DetailLevel.REGIONAL
285
+ )
286
+
287
+ # Find damage zones
288
+ damage = [a for a in context.anomalies if "damage" in a.type]
289
+
290
+ # Visit each damage zone
291
+ findings = []
292
+ for zone in damage:
293
+ detailed = await self.ai.get_context(
294
+ bot_id=self.bot_id,
295
+ mission=Mission.INSPECTION,
296
+ location=zone.location,
297
+ detail_level=DetailLevel.DETAILED
298
+ )
299
+ findings.append(self._document_damage(zone, detailed))
300
+
301
+ return {"bot": self.bot_id, "findings": findings}
302
+ ```
303
+
304
+ Why this works:
305
+ - ✅ Type hints guide code generation
306
+ - ✅ Clear docstrings explain what functions do
307
+ - ✅ Example usage shows patterns
308
+ - ✅ Predictable API (no hidden state)
309
+ - ✅ Returns structured data (JSON-serializable)
310
+
311
+ ---
312
+
313
+ ## Principles for AI Compatibility
314
+
315
+ ### 1. Type Hints Required
316
+
317
+ Every parameter and return value must have explicit type.
318
+
319
+ ```python
320
+ # ✅ GOOD
321
+ async def query(location: GeoPoint, radius_m: float) -> list[Observation]:
322
+ ...
323
+
324
+ # ❌ BAD
325
+ async def query(location, radius_m):
326
+ ...
327
+ ```
328
+
329
+ ### 2. No Magic or Implicit Behavior
330
+
331
+ AI can't infer intent. Be explicit.
332
+
333
+ ```python
334
+ # ✅ GOOD: AI knows what happens
335
+ context = await ai.get_context(
336
+ bot_id=bot_id,
337
+ mission=Mission.SECURITY,
338
+ location=location
339
+ )
340
+ # Returns: filtered, decayed, anomaly-flagged context
341
+
342
+ # ❌ BAD: AI might not know what query() does
343
+ data = await map.query(location)
344
+ ```
345
+
346
+ ### 3. Structured Returns
347
+
348
+ Return dataclasses or pydantic models, not dicts or tuples.
349
+
350
+ ```python
351
+ # ✅ GOOD: AI can introspect structure
352
+ @dataclass
353
+ class Context:
354
+ observations: list[Observation]
355
+ anomalies: list[Anomaly]
356
+ suggested_actions: list[str]
357
+
358
+ # ❌ BAD: AI can't know structure
359
+ return {
360
+ "data": [...],
361
+ "issues": [...],
362
+ }
363
+ ```
364
+
365
+ ### 4. Comprehensive Error Handling
366
+
367
+ Explicit exceptions that AI can catch and handle.
368
+
369
+ ```python
370
+ # ✅ GOOD: AI knows what can go wrong
371
+ try:
372
+ context = await ai.get_context(...)
373
+ except PermissionError:
374
+ print("Bot not authorized for this mission")
375
+ except ValueError:
376
+ print("Invalid mission type")
377
+
378
+ # ❌ BAD: Generic exception
379
+ except Exception as e:
380
+ print("Something went wrong")
381
+ ```
382
+
383
+ ### 5. Default Values for Common Cases
384
+
385
+ AI should be able to call with minimal args.
386
+
387
+ ```python
388
+ # ✅ GOOD: AI can call with just required params
389
+ context = await ai.get_context(
390
+ bot_id="bot_1",
391
+ mission=Mission.SECURITY,
392
+ location=GeoPoint(40.123, -74.567)
393
+ )
394
+ # Uses sensible defaults: radius_m=50, detail_level=REGIONAL
395
+
396
+ # ❌ BAD: Requires many parameters
397
+ context = await ai.get_context(
398
+ bot_id="bot_1",
399
+ mission="security",
400
+ lat=40.123,
401
+ lon=-74.567,
402
+ radius_m=50.0,
403
+ start_time=1234567890,
404
+ end_time=1234567900,
405
+ max_observations=100,
406
+ min_confidence=0.5,
407
+ )
408
+ ```
409
+
410
+ ---
411
+
412
+ ## Testing for AI Usage
413
+
414
+ Add tests that verify AI can call the API correctly:
415
+
416
+ ```python
417
+ async def test_ai_can_query_context():
418
+ """Verify AI agents can call get_context"""
419
+ ai = PyTerrainAI(map_service)
420
+
421
+ # Minimal call (like AI would)
422
+ context = await ai.get_context(
423
+ bot_id="bot_1",
424
+ mission=Mission.SECURITY,
425
+ location=GeoPoint(40.123, -74.567)
426
+ )
427
+
428
+ # Verify structure is what AI expects
429
+ assert hasattr(context, 'observations')
430
+ assert hasattr(context, 'anomalies')
431
+ assert hasattr(context, 'suggested_actions')
432
+ assert isinstance(context.observations, list)
433
+ ```
434
+
435
+ ---
436
+
437
+ ## Documentation for AI
438
+
439
+ Create a guide for LLMs to understand the system:
440
+
441
+ ```markdown
442
+ # PyTerrain for AI Systems
443
+
444
+ PyTerrain is a collaborative terrain mapping system designed for autonomous AI agents.
445
+
446
+ ## Quick Start for AI Agents
447
+
448
+ 1. **Import the libraries**
449
+ ```python
450
+ from pyterrain_map import PyTerrainMap, Observation, SensorType
451
+ from pyterrain_ai import PyTerrainAI, Mission
452
+ ```
453
+
454
+ 2. **Query for context**
455
+ ```python
456
+ context = await ai.get_context(bot_id, mission, location)
457
+ ```
458
+
459
+ 3. **Process context**
460
+ ```python
461
+ for anomaly in context.anomalies:
462
+ # Decide what to do based on anomaly
463
+ ```
464
+
465
+ 4. **Push observations**
466
+ ```python
467
+ await map_service.push_observation(Observation(...))
468
+ ```
469
+
470
+ ## API Reference
471
+
472
+ [Full API docs with all type signatures and examples]
473
+ ```
474
+
475
+ ---
476
+
477
+ ## Summary
478
+
479
+ PyTerrain is designed so that:
480
+ - ✅ Claude Code can generate bot implementations
481
+ - ✅ Copilot can suggest PyTerrain calls
482
+ - ✅ Codex can write integration code
483
+ - ✅ LLMs understand the API from docs
484
+ - ✅ Type hints guide code generation
485
+ - ✅ Examples show patterns
486
+ - ✅ Errors are explicit and catchable
487
+
488
+ This is **API design for the AI era**.