Skip to content

Releases: espetro/cauce

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 08 Oct 15:46
1e7cc6f

Prebuilt cauce binaries. Fully self-contained (engines + UI + AI + archive compiled in). macOS: xattr -d com.apple.quarantine ./cauce after untarring. The ddgs exec engine needs a source checkout + python3 (uv sync --project sdk/python --extra ddgs) — custom builds only.

What's Changed

  • feat(history): origin labels + durable answer_log + session-ID answer URLs by @espetro in #255
  • chore(release): v0.8.1 by @espetro in #256

Full Changelog: v0.8.0...v0.8.1

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 07 Oct 16:48
830b460

Prebuilt cauce binaries. Fully self-contained (engines + UI + AI + archive compiled in). macOS: xattr -d com.apple.quarantine ./cauce after untarring. The ddgs exec engine needs a source checkout + python3 (uv sync --project sdk/python --extra ddgs) — custom builds only.

What's Changed

Full Changelog: v0.7.0...v0.8.0

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 27 Sep 12:52

Prebuilt cauce binaries. Fully self-contained (engines + UI + AI + archive compiled in). macOS: xattr -d com.apple.quarantine ./cauce after untarring. The ddgs exec engine needs a source checkout + python3 (uv sync --project sdk/python --extra ddgs) — custom builds only.

What's Changed

Full Changelog: v0.6.0...v0.7.0

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 11:12

Prebuilt cauce binaries. Fully self-contained (engines + UI + AI + archive compiled in). macOS: xattr -d com.apple.quarantine ./cauce after untarring. The ddgs exec engine needs a source checkout + python3 (uv sync --project sdk/python --extra ddgs) — custom builds only.

What's Changed

Full Changelog: v0.5.0...v0.6.0

v0.5.0

Choose a tag to compare

@devin-ai-integration devin-ai-integration released this 25 Sep 17:33

Prebuilt cauce binaries. Fully self-contained (engines + UI + AI + archive compiled in). macOS: xattr -d com.apple.quarantine ./cauce after untarring. The ddgs exec engine needs a source checkout + python3 (uv sync --project sdk/python --extra ddgs) — custom builds only.

What's Changed

  • chore(repo): license split, DCO, repo hygiene by @espetro in #70
  • feat(workspace): cargo workspace, mise validate gate, CI, pre-push by @espetro in #71
  • feat(core): oxe-core domain types and traits (parent 4.2) by @espetro in #72
  • feat(engines): exec runtime, python SDK, ddgs_auto.py (W0-07) by @espetro in #73
  • feat(engines): replay engine, cassettes, and oxe record (W0-06) by @espetro in #74
  • feat(store-sqlite): schema, migrations, Store impl (W0-04) by @espetro in #75
  • feat(server): observability foundation (W0-05) by @espetro in #76
  • feat(core): config loader, interpolation, XDG dirs, resource-adaptive defaults (W0-11) by @espetro in #77
  • feat(core): SearchPipeline v0 (W0-08) by @espetro in #78
  • feat(server): axum JSON routes and the routes-table test (W0-09) by @espetro in #79
  • feat(server): HTMX search page and results partial (W0-10) by @espetro in #80
  • W0-12: golden path, budget and live gates by @espetro in #81
  • Wave-0 whole-wave review fixes by @espetro in #91
  • chore(infra): cut worktree target/ footprint ~60% and document the pattern by @espetro in #93
  • feat(core): HttpClient, Egress trait, token bucket, UA policy by @espetro in #94
  • feat(core): tier-2 FTS5 lexical cache (W1-10) by @espetro in #96
  • W1-07 Admission: singleflight, bounded queue, stale/429 by @espetro in #97
  • feat(engines): declarative YAML runtime + oxe engine test by @espetro in #101
  • feat(server): W1-13 loopback request guard and non-loopback bind refusal by @espetro in #102
  • feat(server,cli): MCP server over streamable HTTP and stdio (W1-08) by @espetro in #98
  • W1-06 Engine health: EWMA and circuit breaker, persisted by @espetro in #100
  • feat(cli): oxe tail JSONL pretty-printer (W2-09) by @espetro in #105
  • fix(core): validate CacheKey on deserialization by @espetro in #104
  • feat(engines): bing declarative spec and fixtures (W1-03) by @espetro in #106
  • fix(core): redact secret config paths regardless of value origin by @espetro in #103
  • feat(engines): wikipedia OpenSearch spec with fixtures (W1-05) by @espetro in #108
  • feat(engines): brave declarative spec and recorded fixtures (W1-04) by @espetro in #107
  • feat(metrics): W1-09 OTel registry, /metrics, /api/stats extension by @espetro in #99
  • chore(server): bump CURRENT_WAVE to 1 by @espetro in #112
  • feat: oxe serve --headless modes + cargo feature gates (W1-12) by @espetro in #111
  • fix(engines): eager exec spawn and re-warm after deadline kill by @espetro in #114
  • fix: wave-1 whole-review findings — mcp pipeline parity, redacted PUT, metrics label by @espetro in #115
  • feat(cli,docs): W1-11 cutover — live smoke canary, install + agent docs by @espetro in #113
  • fix(server): let *.localhost hosts reach /mcp by @espetro in #116
  • docs(install): OXE_ENGINES cannot pin embedded specs; disable ddgs in config by @espetro in #117
  • docs(agents): wave-1 cutover notes by @espetro in #118
  • refactor!: rename project oxe to cauce (crates, binary, env, paths, metrics) by @espetro in #124
  • fix(server): vendor htmx-2 json-enc extension by @espetro in #125
  • fix(engines): normalize empty Ok responses to NoResults + ddgs emits no_results by @espetro in #126
  • fix(search): strict 400 unknown_engines for pins naming unknown ids by @espetro in #127
  • fix: #89 polish batch — help exit code, blank-query 400, raw query in history by @espetro in #129
  • fix(server): serve embedded favicon at GET /favicon.ico by @espetro in #130
  • feat(w2-11): OpenSearch descriptor and cauce search CLI formats by @espetro in #132
  • feat(engines): exec protocol v2 forwards safesearch/time_range/params by @espetro in #128
  • feat(server): /cache admin page (W2-04) by @espetro in #133
  • feat(ui): add settings page and model picker by @espetro in #134
  • feat(server): /audit page and /trace/{id} timeline page (W2-06) by @espetro in #131
  • fix(ui): /audit + /trace accessibility and responsive follow-ups by @espetro in #139
  • feat(search): stream engine results over SSE by @espetro in #137
  • feat(ui): dashboard page by @espetro in #136
  • fix(ui): /settings loop findings (oob ids, cache deletes, contrast) by @espetro in #140
  • feat(ui): history page with nested clicks and cache state by @espetro in #135
  • feat(server): engines page at /engines (W2-05) by @espetro in #138
  • feat(ui): shared header, theme toggle, mobile nav (W2-08) by @espetro in #142
  • feat(core): open breaker on consecutive Parse/Transport errors (W3-07) by @espetro in #143
  • fix(config): engine id charset validation + injective fe_id (issue #141) by @espetro in #144
  • fix: reject invalid persisted engine ids in stats + reset (issue #145) by @espetro in #146
  • refactor(core): decompose pipeline.rs into a module directory (W3-08) by @devin-ai-integration[bot] in #153
  • refactor(server): decompose handlers.rs into a module directory by @devin-ai-integration[bot] in #162
  • refactor(store-sqlite): decompose store.rs into domain modules + escaping proptests by @devin-ai-integration[bot] in #165
  • test(engines): proptest declarative redirect/parse boundaries by @devin-ai-integration[bot] in #168
  • test(server): shared tests/support harness, routes.rs domain split, case tables by @devin-ai-integration[bot] in #169
  • refactor(server): extract Exa wire adapter from mcp.rs + boundary proptests by @devin-ai-integration[bot] in #164
  • refactor(server): decompose html.rs into page-domain modules by @devin-ai-integration[bot] in #163
  • refactor(core): decompose conformance.rs into domain modules by @devin-ai-integration[bot] in #167
  • docs(agents): MEMORY note — W3-08 follow-through hygiene batch by @devin-ai-integration[bot] in #170
  • refactor(core): decompose config.rs into a module directory by @devin-ai-integration[bot] in #166
  • feat(merge): configurable RRF k, reliability weights, host collapse + AMP URL folds (W3-03) by @devin-ai-integration[bot] in #171
  • feat(core): stale-while-revalidate tier-1 serve with cache hygiene (W3-02) by @devin-ai-integration[bot] in #172
  • feat(config): health.* pins for the W3-07 degraded breaker by @devin-ai-integration[bot] in #173
  • feat: engine relevance evals (W3-05) by @devin-ai-integration[bot] in #174
  • fix(engines): evaluate detect.blocked only on zero-match responses (#109) by @devin-ai-integration[bot] in #175
  • feat(server): serve GET /api/suggest for OpenSearch suggestions by @devin-ai-integration[bot] in #176
  • feat(engines): request.market lang→market map and {market} token (#110) by @devin-ai-integration[bot] in #177
  • feat(engines): nightly --live drift canary over shipped specs (W3-06) by @devin-ai-integration[bot] in #178
  • feat(core): ai::openai SSE chat client with tool-call assembly (W4-01) by @devin-ai-integration[bot] in #182
  • docs(plans): lift the W2-10 gate on W4-01 by @devin-ai-integration[bot] in #179
  • chore: scrub Bifrost references from codebase by @devin-ai-integration[bot] in https://g...
Read more

v0.4.0

Choose a tag to compare

@espetro espetro released this 17 Sep 08:02

Highlights

  • Web UI rewrite: Preact SPA in a new ui/ workspace (Vite + daisyUI), served by the Python server from the built bundle. AI answer mode with SSE streaming (tool steps, sources, related queries), DDG-style pill search bar with Search/AI toggle, virtualized continuous-scroll results, theme switcher, pagination, ?settings=open URL state.
  • AI answers end to end: POST /answer (SSE), GET /v1/models, answer caching, oxe[ai] optional extra (aisuite with openai/anthropic).
  • Settings API: GET/PUT /settings for the [ai] config section, POST /settings/test credential check, {env.NAME} interpolation.
  • Autocomplete & suggestions: GET /ac (DDG proxy), GET /suggest (own query history, OpenSearch format).
  • Pagination end to end; dev observability via OXE_DEV=1 JSON events.
  • Typed contracts: Pydantic response models, JSON error envelope, OpenAPI export with generated TS types.
  • Dashboard: /dashboard SPA page with GET /api/stats (searches/day, cache hit rate, latency percentiles).
  • Server: server.py split into an oxe/server/ package; SPA served via a minimal static mount + catch-all with content-negotiated 404s.

License

Relicensed from MIT to Apache 2.0 (Copyright Quino Terrasa).

Full changelog: https://github.com/espetro/oxe/blob/main/CHANGELOG.md

v0.3.1 - SQL-file layer, fuzzy search

Choose a tag to compare

@espetro espetro released this 15 Sep 08:23

Maintenance release: cleaner internals, smarter history search.

Added

  • auto backend name in OXE_BACKENDS (ddgs multi-engine sweep).
  • Fuzzy matching in /cache and /history search: typos like "pyton" find "python" rows. Uses rapidfuzz when installed (install with oxe[fuzzy]), stdlib difflib otherwise.

Changed

  • All SQL moved from inline strings to oxe/sql/*.sql, loaded via aiosql: named queries, documented, validated at import.
  • rapidfuzz is now an optional extra, keeping the default install lean.
  • sqlite3.Row access throughout the cache layer; dynamic WHERE building removed.

Full changelog: https://github.com/espetro/oxe/blob/main/CHANGELOG.md

v0.3.0 - pluggable multi-engine backends

Choose a tag to compare

@espetro espetro released this 14 Sep 22:59

First release with pluggable search backends.

Added

  • Multi-backend support via OXE_BACKENDS (JSON): single engine, fallback chain, or fanout compositor. Any engine the bundled ddgs library works: bing, brave, google, mojeek, yahoo, yandex, wikipedia.
  • DdgsBackend(engine) drives any ddgs engine through the same Exa-compatible translation layer; DDGBackend is the ddg specialization.
  • oxe.registry: builtins + engine names + oxe.backends entry-point discovery. Third-party backends register by name.
  • FallbackBackend (first non-empty wins, per-backend timeout) and FanoutBackend (concurrent query, merge + dedupe by URL).
  • Package-root exports: BackendError, FallbackBackend, FanoutBackend, SearchBackend, build_from_env.

Changed

  • Cache key includes the backend name; results from different engines never collide in one database.
# DDG first, fall back to bing
OXE_BACKENDS='["ddg", "bing"]' oxe

Full changelog: https://github.com/espetro/oxe/blob/main/CHANGELOG.md

v0.2.0

Choose a tag to compare

@espetro espetro released this 14 Sep 22:47

[0.2.0] - 2026-09-15

Added

  • Search log: every search (HTTP and MCP) writes a search_log row (query text + hash, cache/network source, result count, duration in ms, client) to the cache database, pruned by OXE_SEARCH_LOG_RETENTION_DAYS (default 30).
  • oxe stats CLI subcommand: builds a static stats dashboard (index.html, six inline-SVG panels, zero JavaScript) from the search log. Opens the SQLite file read-only, so it is safe against a live WAL database. Flags: --db, --out, --days.
  • GET /search?q=... with content negotiation: browsers get the rendered results page, Accept: application/json clients get Exa-shaped JSON from the same URL. Includes a share row (canonical link, copy JSON, copy link) and result paging via &p=.
  • /?q=X now redirects to /search?q=X, so .../search?q=%s can be registered as a browser search engine.
  • make_app(cache=None, on_result=None) factory in oxe.server for embedding: bring your own cache, or attach an on_result observer called with every search payload.
  • Result cards are mirrored server-side (favicon + domain, title, snippet, collapsed page-text preview), so /search?q= renders even before JavaScript runs.

Changed

  • Page templates extracted from Python string literals in oxe/ui.py to oxe/static/*.html, loaded via importlib.resources (packaged as package data).
  • Web UI reworked to a Google-style results anatomy per the screen specs in .agents/docs/screens/.
  • Search-log latency: do_search(..., with_duration=True) returns (payload, duration_ms); the MCP tool uses it to record real network latency.

Fixed

  • MCP exa_search search-log rows recorded duration_ms = NULL on every network search because the duration was only attached to the observer copy of the payload. Latency is now returned explicitly and logged for both HTTP and MCP searches.
  • Duplicate panel_client_split_rows definition (one with an incomplete body) removed from oxe/stats.py.

v0.1.3

Choose a tag to compare

@espetro espetro released this 14 Sep 18:03

Fixed

  • README "Browser-friendly URLs" section now documents a working setup. The previous portless oxe oxe snippet was broken because oxe reads OXE_PORT, not the generic PORT env var that portless sets for the proxied process. The new section recommends portless alias search 4479 (static route pointing at an oxmgr/systemd/launchd-supervised oxe) and provides a portless run fallback that explicitly stops the supervisor first.