Skip to content

feat: add LLM-safe OBD diagnostics layer - #16

Merged
virtuscyber merged 8 commits into
masterfrom
feature/8-obd-ai-bootstrap-ci
Apr 11, 2026
Merged

virtuscyber merged 8 commits into
masterfrom
feature/8-obd-ai-bootstrap-ci

Conversation

@virtuscyber

Copy link
Copy Markdown
Owner

Summary

  • add the obd_ai layer for safe LLM-driven vehicle diagnostics
  • expose a read-only diagnostic tool surface, deterministic health scan, guardrails, audit logging, and a callable server entrypoint
  • refresh bootstrap, simulation-backed tests, and CI so the new layer is reproducible in development and automation

What landed

  • approved command catalog and session manager foundation
  • JSON-safe serializers for OBD responses and metadata
  • read-only LLM diagnostic tools
  • deterministic basic_health_scan
  • HTTP/function-calling server entrypoint with docs
  • policy guardrails, approval placeholders, and audit logging
  • obdsim-backed integration/safety regression harness
  • editable install/dev extras/CI modernization for obd_ai

Validation

  • python3 -m pytest -q tests/test_obd_ai_*.py
  • python3 -m pytest -q
  • python3 -m build
  • python3 -m tox -e py313 -- tests/test_obd_ai_*.py

Notes

  • simulation-backed tests skip cleanly when --port is not provided
  • the LLM-facing surface stays read-only by default
  • destructive actions remain blocked or approval-gated placeholders

Closes #1
Closes #2
Closes #3
Closes #4
Closes #5
Closes #6
Closes #7
Closes #8
Closes #9

@augmentcode

augmentcode Bot commented Apr 11, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: This PR introduces a new obd_ai layer that exposes a constrained, read-only diagnostics surface intended for LLM/function-calling agents.

Changes:

  • Add approved command catalog + policy engine to allowlist safe reads and block raw/force/destructive paths
  • Add JSON-safe serializers for OBD responses/status/DTCs and connection metadata
  • Add OBDAISession/OBDAISessionManager wrappers and OBDAIReadOnlyToolSurface (incl. deterministic basic_health_scan)
  • Add runnable HTTP/CLI tool server (obd-ai-server) with /health, /tools, and call endpoints
  • Add audit event primitives + sinks and a comprehensive pytest suite (with optional obdsim integration)
  • Modernize packaging/dev extras + CI/tox to test/build the new layer across Python versions

Technical Notes: The exposed surface stays read-only by default; destructive actions (e.g., CLEAR_DTC) return structured approval/blocked responses and are logged via audit events.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 4 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread obd_ai/tools.py
if input_error is not None:
return input_error

include_support = bool(payload.get("include_support", True))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

obd_ai/tools.py:146 — list_supported_commands defaults include_support to True, which means calling it before connect_vehicle will fail with disconnected_adapter even though the approved catalog could be listed offline. Consider whether the default behavior should avoid requiring a live connection unless support info is explicitly requested.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread obd_ai/tools.py
self._session = self._session_manager.open_session(**payload)

metadata = self._session.connection_metadata()
if not metadata["is_connected"]:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

obd_ai/tools.py:95 — on a disconnected adapter, connect_vehicle returns an error but leaves self._session open; that can retain/lock the underlying serial resources even though the call failed. Consider closing the session before returning the disconnected_adapter error payload.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread obd_ai/server.py

if self.path == "/call":
tool_name = payload.get("tool")
input_payload = payload.get("input", {})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

obd_ai/server.py:177 — POST /call doesn’t validate that input is a JSON object; if a client sends a non-object (e.g., string/array), the tool surface’s dict(input or {}) will raise and you’ll respond with server_error instead of a clear 400 invalid_request. Consider rejecting non-object input at the HTTP boundary (and/or in OBDAIFunctionServer.call_tool).

Severity: medium

Other Locations
  • obd_ai/server.py:122

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread obd_ai/server.py
return 0

if args.command == "call":
payload = json.loads(args.input_json)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

obd_ai/server.py:299 — the call CLI subcommand will raise an uncaught JSONDecodeError if --input-json isn’t valid JSON, which produces a stack trace instead of a clean CLI error. Consider handling JSON parsing failures and exiting with a friendly message.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

@virtuscyber
virtuscyber merged commit 6f03d59 into master Apr 11, 2026
5 checks passed
@virtuscyber
virtuscyber deleted the feature/8-obd-ai-bootstrap-ci branch April 11, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment