-
Notifications
You must be signed in to change notification settings - Fork 2
features output formatters
Active contributors: Magnus Hedemark
Maps the internal SearchResult dataclass to two output formats: SearXNG-compatible JSON and agent-native YAML+Markdown. The formatter module lives in slopsearx/formatter.py and is the last step in the search pipeline, after results have been collected, deduplicated, and ranked.
-
format_json()(slopsearx/formatter.py) — produces a SearXNG-compatible JSON response dict. Accepts the ranked result list plus optional metadata (answers, corrections, infoboxes, suggestions, unresponsive engines, meta extensions). -
format_yaml_markdown()(slopsearx/formatter.py) — produces a YAML document with structured data, followed by---, then a Markdown## Results Summarysection with readable prose. Designed for AI agent consumption. -
_result_to_searxng()(slopsearx/formatter.py) — maps a singleSearchResultto a 23-field SearXNG dict. All 23 SearXNG MainResult fields are present; null fields are preserved asNonefor JSON serialization. -
_iso_to_epoch()(slopsearx/formatter.py) — converts an ISO 8601 datetime string to Unix epoch seconds, or returnsNoneif the input is empty or unparseable.
The JSON formatter (format_json()) produces a response that is a superset of SearXNG's output. The same fields are present, plus meta.* extensions at the top level.
The AdapterResponse now includes three extended fields that are aggregated from all engine responses: answers (list of dicts with answer content), corrections (list of suggested query correction strings), and infoboxes (list of structured info box dicts). These are passed through to the JSON response and populated when adapters return them.
Response structure:
{
"query": "search query",
"results": [...],
"number_of_results": 10,
"answers": [],
"corrections": [],
"infoboxes": [],
"suggestions": [],
"unresponsive_engines": [],
"meta": {
"response_time_ms": 1234,
"cached": false,
"query_id": "abc123",
"engine_status": {
"brave": {"status": "ok", "latency_ms": 320},
"duckduckgo": {"status": "blocked", "latency_ms": 0}
}
}
}Each result in the results array includes all 23 SearXNG MainResult fields:
url, title, content, engine, engines, score, positions, category,
publishedDate, pubdate, length, thumbnail, img_src, iframe_src,
audio_src, views, author, metadata, template, parsed_url,
open_group, close_group, priority
The YAML+Markdown formatter (format_yaml_markdown()) produces a two-part response:
- YAML header — structured data with query, meta (response time, cached, query_id, engine health), and an array of results with url, title, engine, content, score, position, and publication date.
-
Markdown body — a
## Results Summarysection with a human-readable summary: number of engines that responded, total results, elapsed time, and the top 5 result snippets.
The response is selected by the format query parameter (format=json is default, format=yaml triggers the YAML+Markdown formatter).
A backward-compatible format_yaml() wrapper converts legacy dict-based results to SearchResult objects and delegates to format_yaml_markdown().
-
slopsearx/formatter.py— all formatter logic
-
Search result types — the
SearchResultdataclass that formatters consume - System architecture — where formatting fits in the request flow