8000 feat(ontology): connect NVIDIA Auto-Ontology through a private REST adapter by adeelahmad · Pull Request #720 · adeelahmad/lense · GitHub
[go: up one dir, main page]

Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/clicks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ permissions:
jobs:
clicks:
name: Clicks and keystrokes per feature
runs-on: ${{ fromJSON(vars.CI_RUNNER || '"ubuntu-latest"') }}
# Playwright 1.56's browser/dependency bundle supports Ubuntu 24.04, not the rolling ubuntu-latest (26.04).
runs-on: ${{ fromJSON(vars.CI_RUNNER || '"ubuntu-24.04"') }}
timeout-minutes: 60
steps:
- uses: actions/checkout@v7
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ listed under [In progress](#in-progress), and what comes next under [Planned](#p
ones that run as a program (`npx`, `uvx`) run in a sandboxed container of their own, off until you turn it on. Add one
with a form or by pasting another app's config, its tokens sealed and each of its tools switched on or off, or pick a
ready-made one: GitHub's own server, or a browser (a headless Chromium in a sandbox of its own) the assistant opens,
reads, clicks and types in, asking before anything that acts on a page. Settings › AI assistant › MCP servers lists
reads, clicks and types in, asking before anything that acts on a page. An optional
[Auto-Ontology integration](docs/auto-ontology.md) connects an existing deployment for semantic
terms and SQL-backed answers, with private extensions and sealed API tokens. Settings › AI assistant › MCP servers lists
them all, and agents list and add them over MCP. The MCP runner, the browser and monitoring are containers Lens starts
next to itself from the web app, through the machine's upgrade agent, each off until an admin turns it on. Install
skills and plugins from marketplaces in the open plugin format, or from a repository or an archive, and keep your own
Expand Down
11 changes: 11 additions & 0 deletions changelog.d/auto-ontology.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
### Added

- Optional NVIDIA Auto-Ontology integration through its authenticated public REST gateway: semantic term search,
readiness, answerability and SQL-backed answers with bounded rows and source provenance. Reuses private MCP
extensions, sealed tokens, tool controls and the activity ledger; adds no default services or dependencies.
Predictive uploads and persistent upstream conversations are disabled.

### Fixed

- Keep the Clicks workflow's default runner on Ubuntu 24.04, which its pinned Playwright browser bundle supports,
instead of letting the moving Ubuntu label break browser installation on 26.04.
1 change: 1 addition & 0 deletions changelog.d/fix-syslog-tls-shutdown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix syslog-over-TLS shutdown to send `close_notify` before closing the connection, preventing log loss when TLS 1.3 servers send session tickets. Cleanup remains bounded by the connection timeout and always releases the socket. Regression tests cover strict TLS 1.2 and 1.3 receivers and failed shutdown cleanup.
5 changes: 5 additions & 0 deletions docs/assistant.md
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,11 @@ runs (until then its switch is there to turn it on). **GitHub** puts GitHub's ow
`GET /api/v1/extensions/mcp/presets` (admins), each with the spec to save and, for the browser, whether its container
is on and answering.

**NVIDIA Auto-Ontology** connects an existing deployment's public web gateway with its API token: semantic term
search, readiness, answerability and SQL-backed answers. It uses a REST adapter, not the upstream OAuth MCP server,
and adds no services to Lens. It starts private; sharing delegates the token owner's upstream data access to every
recipient. Questions can incur model costs. See [Auto-Ontology](auto-ontology.md) for setup, tools and limits.

**Settings › AI assistant › MCP servers** lists the servers added, each with how many of its tools the assistant is
offered and a link to its page, with **Add MCP server** and the switches that run the MCP runner and the browser on
this machine. Agents do the same with the MCP tools `mcp_servers`, which lists the servers (header and env names, never
Expand Down
74 changes: 74 additions & 0 deletions docs/auto-ontology.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# NVIDIA Auto-Ontology

Lens can connect an existing [NVIDIA Auto-Ontology](https://github.com/NVIDIA/auto-ontology) deployment to its
assistant. This optional integration searches the deployment's semantic catalog, checks whether a question is covered,
and asks questions that return an answer, generated SQL and result rows.

It connects to Auto-Ontology's **public web gateway REST API**, using the existing MCP extension controls in Lens.
It does not replace Lens's SurrealDB graph, extract an ontology from Lens's archive, install Auto-Ontology, or send the
archive to it. No extra package or service is added to the default Lens install.

## Connect

1. In your Auto-Ontology deployment, connect the relational data sources and compile the semantic layer. Follow
[its setup guide](https://github.com/NVIDIA/auto-ontology#quickstart). Keep its backend and ingestion ports private.
2. Create an API token in Auto-Ontology's user menu, **API Tokens**, for an account with only the data access you need.
3. In Lens, as an admin, open **Extensions → Add MCP server → Ready-made → Set up NVIDIA Auto-Ontology**.
4. Enter `AUTO_ONTOLOGY_URL`, the public web **origin** (for example `https://ontology.example.com` or, on a trusted
local network, `http://auto-ontology-frontend:3000`), and `AUTO_ONTOLOGY_API_TOKEN`. Do not add `/mcp`, `/api`, a
query string, or a private backend/ingestion port. Use HTTPS outside a trusted local network: HTTP exposes the token
to anyone who can observe that network.
5. Choose **Test**, then **Add** (or Enter). The test makes one bounded glossary read; it verifies gateway access,
not semantic readiness. Ask the assistant to run `auto_ontology__check_readiness` before asking about the data.

The extension starts private. Its address, token, visibility, enabled state and per-tool switches are editable from
its page. Tokens are sealed at rest and masked in the API and manifests, using Lens's existing credential storage.
An agent can set it up with the `add_mcp_server` tool and `preset: auto_ontology`, supplying the same two values, or
through the [extensions API](assistant.md#adding-an-mcp-server).

Auto-Ontology's own MCP server uses interactive OAuth, which this bridge does not implement. Its MCP address cannot
be substituted for the public web origin, and a static API token cannot be used as its OAuth credential.

## Tools

| Tool | What it does |
|---|---|
| `auto_ontology__check_readiness` | Reads compilation status and source counts, without a model call. `ready: null` means the token cannot inspect every readiness check, not that the deployment is broken. |
| `auto_ontology__search_terms` | Searches business terms, with `query`, `limit` (1–100, default 20), and `offset` (0–10,000). |
| `auto_ontology__get_term` | Reads one exact term ID from search results, including relationships and mapped tables. |
| `auto_ontology__check_answerable` | Asks upstream which concepts cover `question`; coverage is guidance, not proof. May call its models. |
| `auto_ontology__ask_question` | Asks `question` and returns the upstream answer, SQL, source, and rows. `max_rows` is 1–100 (default 25); `row_count` and `truncated` describe the returned set. May call its models. |

For example: “Use Auto-Ontology to check whether the catalog covers quarterly revenue, then show revenue by region.
Include the SQL and say if any rows were left out.” The answer identifies the external deployment as its source.
Lens does not independently certify the generated SQL or execute it against its own database.

Questions are stateless: Lens does not send an upstream `conversation_id`, earlier chat messages, or evidence from
the archive automatically. Predictive queries are explicitly disabled (`prediction: false`), so the bridge does not
trigger Auto-Ontology's optional KumoRFM table uploads. There are no ingestion, compilation, mutation or arbitrary SQL
execution tools in this integration. The deployment's own models still process the question and its connected data.

## Access, safety and cost

**The configured API token owner supplies the upstream permissions.** Sharing the extension lets every Lens user who
can use it query the data that token can read. Lens namespace permissions do not become Auto-Ontology permissions.
Keep it private unless every recipient is authorized to read that external data; use separate least-privileged
tokens/extensions when different groups need different access. Revoking the token in Auto-Ontology stops its use.

The bridge reuses Lens's extension access checks, tool switches and third-party-content approval protections. Results
are untrusted external data. Only five fixed read operations are exposed. Tokens are bound to the extension, gateway
origin and adapter; redirects are refused rather than forwarding a credential. Raw upstream errors are not echoed.

Replies are capped at 2 MB. Questions have a 15-minute total processing limit checked between received chunks, plus
a 30-second network read timeout. A slow, failed or incomplete answer is reported without retrying it: the upstream
model or query may already have run. A malformed or oversized reply is not presented as a successful partial answer.

Calls appear in the activity ledger. Answerability and question calls are marked **unpriced**, since upstream does
not report reliable token usage or cost. Calls use Lens's model budget hook, but unpriced remote calls cannot be
reliably capped by a USD budget. Configure model limits and budgets in Auto-Ontology and its provider too.

This bridge targets the public contracts documented in upstream's
[API specification](https://github.com/NVIDIA/auto-ontology/blob/main/docs/openapi/auto-ontology-api.json) and
[conversation API](https://github.com/NVIDIA/auto-ontology/blob/main/docs/conversation-api.md). Contract tests use
local responses, not a live deployment or paid models. A deployment smoke test remains necessary when upgrading
Auto-Ontology: test credentials, readiness, term search and one known-answer question before sharing the extension.
4 changes: 4 additions & 0 deletions docs/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ server can't be reached Lens retries, waiting up to 30 seconds between tries, an
ones are dropped and counted. **Send a test line** sends one message to the saved server, even while sending is off,
and Settings → Logs shows how many lines the API has sent and dropped and the last error.

TLS connections send a clean shutdown notification before closing, so the receiver can finish reading queued
messages. Shutdown waits at most the connection timeout (5 seconds by default) for the server's reply, then releases
the socket even if the server does not reply. This is transport shutdown, not an acknowledgment that logs were stored.

rsyslog, syslog-ng, Graylog, Grafana Loki (through promtail or Alloy's syslog receiver), Splunk, Papertrail and most
log tools take RFC 5424 syslog.

Expand Down
1 change: 1 addition & 0 deletions docs/requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ request, to another check that proves the same thing; loosening a requirement or
| Tools: a prompt, a web request, a graph drawn on the canvas, or sandboxed Python | [test_extensions.py](https://github.com/adeelahmad/lense/blob/main/fastapi_backend/tests/api/test_extensions.py) `test_tools_and_skills_in_a_conversation`, `test_tools_drawn_on_the_canvas`, `test_python_tools_run_apart_and_only_admins_write_them` |
| Skills, hooks and MCP servers, by code, on the canvas or by asking | [test_extensions.py](https://github.com/adeelahmad/lense/blob/main/fastapi_backend/tests/api/test_extensions.py) `test_written_as_code_shared_and_versioned`, `test_change_tools_ask_first_and_hooks`, `test_made_in_chat_behind_an_approval`; [journeys.mjs](https://github.com/adeelahmad/lense/blob/main/ci/clicks/journeys.mjs) `extension-add`; [baseline.json](https://github.com/adeelahmad/lense/blob/main/ci/clicks/baseline.json) `extension-add` ≤ 3 clicks |
| Remote MCP servers connect by address | [test_mcp_servers.py](https://github.com/adeelahmad/lense/blob/main/fastapi_backend/tests/api/test_mcp_servers.py) `test_an_admin_adds_a_server_and_the_assistant_uses_it` |
| Optional Auto-Ontology REST bridge: semantic terms, readiness, answerability and SQL-backed answers; private extensions, sealed token, bounded responses, no redirects, predictions or shared upstream conversation | [test_auto_ontology.py](https://github.com/adeelahmad/lense/blob/main/fastapi_backend/tests/domain/test_auto_ontology.py) `AutoOntologyTests`; [test_auto_ontology.py](https://github.com/adeelahmad/lense/blob/main/fastapi_backend/tests/api/test_auto_ontology.py) `test_auto_ontology_is_private_sealed_and_callable`, `test_auto_ontology_config_and_run_keep_the_adapter`; [mcp-server-ui.test.tsx](https://github.com/adeelahmad/lense/blob/main/nextjs-frontend/__tests__/mcp-server-ui.test.tsx) `sets Auto-Ontology up through its public gateway with a private token` |
| MCP servers that run as a program (`npx`, `uvx`) run in a sandboxed container of their own | [test_mcp_servers.py](https://github.com/adeelahmad/lense/blob/main/fastapi_backend/tests/api/test_mcp_servers.py) `test_a_server_that_runs_as_a_program_runs_in_the_runner`; [mcp-runner.yml](https://github.com/adeelahmad/lense/blob/main/.github/workflows/mcp-runner.yml) `Runs an npm server and a PyPI server` |
| Ready-made servers: the browser (a headless Chromium in a sandbox of its own, one session for everyone) and GitHub added in a click; the MCP runner, the browser and monitoring started and stopped from the web app through the upgrade agent, or the line to run shown without one | [test_services.py](https://github.com/adeelahmad/lense/blob/main/fastapi_backend/tests/api/test_services.py) `test_each_profile_is_turned_on_and_off_on_its_own`, `test_no_agent_shows_the_line_to_run`, `test_only_admins`; [test_mcp_servers.py](https://github.com/adeelahmad/lense/blob/main/fastapi_backend/tests/api/test_mcp_servers.py) `test_the_browser_preset_keeps_one_session`; [mcp-server-ui.test.tsx](https://github.com/adeelahmad/lense/blob/main/nextjs-frontend/__tests__/mcp-server-ui.test.tsx) `adds the browser with one click once its container runs`, `turns the browser's container on first, when it isn't running`, `sets GitHub up with the token typed in its place` |
| Settings › AI assistant › MCP servers lists every server with its tools and the containers' switches; agents list and add servers over MCP | [test_mcp_servers.py](https://github.com/adeelahmad/lense/blob/main/fastapi_backend/tests/api/test_mcp_servers.py) `test_agents_list_and_add_servers`; [mcp-server-ui.test.tsx](https://github.com/adeelahmad/lense/blob/main/nextjs-frontend/__tests__/mcp-server-ui.test.tsx) `lists each server with its tools, and the containers' switches` |
Expand Down
Loading
Loading
0