Skip to content

feat(obd_ai): expose diagnostic tools via callable server - #14

Open
virtuscyber wants to merge 1 commit into
feature/4-basic-health-scanfrom
feature/5-obd-ai-server
Open

virtuscyber wants to merge 1 commit into
feature/4-basic-health-scanfrom
feature/5-obd-ai-server

Conversation

@virtuscyber

Copy link
Copy Markdown
Owner

Refs #5

Stacked on top of #4.

Includes:

  • callable server entrypoint
  • CLI tool listing and invocation surface
  • docs and tests for MCP/function-calling integration

@augmentcode

augmentcode Bot commented Apr 11, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: This PR adds a runnable “tool server” layer on top of obd_ai so external LLM/function-calling agents can invoke the existing read-only diagnostic tool surface over a simple JSON/HTTP transport.

Changes:

  • Introduces obd_ai/server.py with a callable registry (OBDAIFunctionServer) backed by OBDAIReadOnlyToolSurface
  • Exposes HTTP endpoints: GET /health, GET /tools, POST /call, and POST /tools/<tool_name>
  • Adds a CLI entrypoint for listing tools and making one-shot calls (python -m obd_ai.server …)
  • Adds an installable script entrypoint (obd-ai-server) via pyproject.toml
  • Adds docs describing usage and endpoints (MkDocs nav updated accordingly)
  • Adds tests covering tool definition listing, tool invocation through the function server, and basic HTTP transport behavior

Technical Notes: The server intentionally limits the exposed surface to safe, read-only diagnostic operations and reuses the same structured payloads/errors as the in-process tool API.

🤖 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/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.

POST /call accepts any JSON type for the input field, but OBDAIReadOnlyToolSurface methods do dict(input or {}), so non-object inputs (e.g., [1,2]) will raise and get reported as a generic server_error rather than a 400-level client error. Consider validating input is a JSON object here (similar to _read_json_body) so malformed requests reliably return invalid_request.

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
"""Create a threaded HTTP server exposing the read-only tool surface."""

app = OBDAIFunctionServer(surface=surface)
server = ThreadingHTTPServer((host, port), _OBDAIHTTPRequestHandler)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ThreadingHTTPServer will process requests concurrently against a single shared OBDAIFunctionServer/OBDAIReadOnlyToolSurface instance, but the surface holds mutable session state (self._session) that doesn’t appear thread-safe. Concurrent calls (e.g., connect_vehicle racing with read_sensor) could lead to inconsistent session/connection behavior or closed-while-in-use errors.

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
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.

In the CLI call path, json.loads(args.input_json) will raise JSONDecodeError on invalid JSON and print a stack trace, whereas the HTTP server returns a structured invalid_json payload. Consider handling decode failures here so CLI users get a clear, consistent error message.

Severity: low

Fix This in Augment

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


base_url = f"http://127.0.0.1:{server.server_port}"
try:
with urllib.request.urlopen(f"{base_url}/tools") as response:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

These urllib.request.urlopen(...) calls don’t set a timeout, so a server regression (or port bind issue) can cause the test to hang until the overall CI timeout rather than failing quickly. Consider adding a small timeout to both requests to make the test suite more robust.

Severity: medium

Other Locations
  • tests/test_obd_ai_server.py:113

Fix This in Augment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant