Skip to content

Rule engine: read retrieval documents that arrive as JSON strings - #66

Open
avalyset wants to merge 2 commits into
SimulaMet:mainfrom
avalyset:fix/rule-engine-json-string-documents
Open

avalyset wants to merge 2 commits into
SimulaMet:mainfrom
avalyset:fix/rule-engine-json-string-documents

Conversation

@avalyset

@avalyset avalyset commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

The bundled Open WebUI instrumentation (deploy/openwebui-subpath/subpath.patch) sets gen_ai.retrieval.documents on retrieval spans to a list of JSON strings, one per document (document_id, file_id, chunk_id, rank, score, and content when document capture is on). Since #65, _units in audits/agentic/rule_engine.py keeps only list elements that are already dicts, so on those traces every retrieval_document rule saw zero documents: "At least 1 retrieved document" reported FAIL with "0 matching retrieval_document unit(s)" although the span carried documents.
This decodes string elements with json.loads, the same handling the retrieval check had before #65, and skips strings that are not valid JSON or do not decode to an object. Dict elements and the case where the whole attribute is one JSON string go through the same path as before.
The new test in audits/agentic/tests/test_rule_engine.py uses a document in the Open WebUI shape plus an invalid string: the count and retrieval.text checks pass, and a retrieval.source check is INCONCLUSIVE because these documents carry no source; a JSON-string document that does carry a source still matches. The test fails on main and passes with the change.
The same cause reached the semantic judge's evidence packet: _retrieved_sources in audits/agentic/semantic_judge.py passed each element of the attribute to _source_values as is, so every Open WebUI document became one retrieval_source_ids entry holding the whole JSON string. It now parses elements that decode to a JSON object or list and passes them on like dict documents, so the packet lists the document's source or file_id; any other string stays a source name as before. The new test in audits/agentic/tests/test_semantic_judge_execution.py fails on the first commit and passes with the second.
pytest -n 4 -m "not embedded_hatchet" (no API keys in the environment, the local-Ollama live test deselected) gave 1378 passed, 2 skipped on main, 1379 passed, 2 skipped after the first commit and 1380 passed, 2 skipped after the second; ruff check . is clean.

AI disclosure: implemented with Claude Code.

Open WebUI's instrumentation sets gen_ai.retrieval.documents to a list of
JSON strings. _units only kept dict elements, so rules on retrieved
documents saw zero documents on those traces. Decode string elements and
skip ones that are not valid JSON.
The evidence packet passed each element of gen_ai.retrieval.documents to
_source_values as is, so a document sent as a JSON string became one
source ID holding the whole string. Parse elements that decode to an
object or a list; other strings stay source names as before.

This branch has not been deployed

No deployments
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