23 KiB
23 KiB
Changelog
All notable changes to EverOS are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
[1.2.1] - 2026-07-29
Added
[embedding]and[rerank]are now soft runtime dependencies — EverOS boots and serves requests with only[llm]configured. Missing or misconfigured embedding / rerank / multimodal providers no longer abort startup; the corresponding accessor logs<provider>_capability_build_failedand reportsavailable=False. Features degrade gracefully into three tiers: Tier 1 ([llm]only) → KEYWORD search + add/flush + md writes + cascade sync; Tier 2 (+ [embedding]) → adds VECTOR/HYBRID search + reflection + skill extraction + backfill; Tier 3 (+ [rerank]) → adds AGENTIC search + knowledge write/search. Tier upgrades require a server restart. Downgrades are read-safe: knowledge documents stay readable/renamable/deletable after a Tier-3 → Tier-2 downgrade; only write / search endpoints return 422.everos cascade backfillCLI command — three-phase interactive backfill (vectors→clusters→skills, or--phase all) for upgrading Tier-1 rows to Tier-2 after[embedding]is configured. Each phase prints row/token estimates and blocks ony/N;--yes/-yfor CI. Exit codes:0success,1user declined,2phase preconditions unmet,3server running,4completed-with-failures,130SIGINT.- LanceDB schema v2 — the six business tables (
episode,atomic_fact,foresight,agent_case,agent_skill,knowledge_topic) now allowvector NULL. Cascade writes rows without vectors when[embedding]is unavailable; a later backfill fills them in. Migration runs once on first startup under a cross-processmemory_root_lock(fcntl.flock), followed byoptimize(cleanup_older_than=timedelta(0))per table to physically prune older manifest versions. - Startup unbackfilled-rows banner — after LanceDB lifespan, an
unconditional sweep emits
unbackfilled_memory_rowswhen rows withvector IS NULLexist, pointing ateveros cascade backfillin the hint text. - PyPI Trusted Publishing workflow — tag-triggered
.github/workflows/release.ymlbuilds, smoke-tests, and uploads via OIDC (no stored token) behind thereleaseenvironment's manual-approval gate. Version-tag mismatch aborts publish. Companion/releaseskill lives under.claude/skills/release/.
Changed
ProviderNotConfiguredError→ HTTP 422CAPABILITY_UNAVAILABLE— write / search endpoints that need embed or rerank now return 422 with a section-aware hint (points ateveros.tomlsection, never atEVEROS_*env vars) instead of erroring at startup or 500-ing at request time.GET /healthreturns a PydanticHealthResponsemodel — with typedcapabilitiesanddisabled_featuresfields, so OpenAPI codegen produces real shapes instead ofadditionalProperties: true.MemoryRoot.default()→MemoryRoot.resolve()— the classmethod that resolves the memory root from--root/EVEROS_ROOT/ default was renamed to make its behavior explicit (resolvewalks the precedence chain;defaultwas ambiguous with "default location").MemoryRootis publicly exported fromeveros.core.persistence; callers outside the repo may have used the old name. Adefault()alias is kept as a backward-compatibility shim that forwards toresolve()and emits aDeprecationWarning. The alias will be removed in a future major release — update call sites when convenient.- Uncalibrated recall scores moved to their own name —
KEYWORDand single-routeVECTORsearches now report their top score asrecall_top_score_raw;recall_top_scoreis reserved for the calibrated methods (HYBRIDLR sigmoid,AGENTICcross-encoder), whose values share a comparable[0, 1]scale. Langfuse aggregates scores by name, so the previous single name meant a chart could average an unbounded BM25 score together with a probability. Every recall score also carriesmetadata = {"method": ..., "calibrated": ...}now, a structured field that can be split on, alongside the existing human-readable comment. Dashboards built onrecall_top_scorefor keyword search need to switch to the new name. - Docs and examples now use
/api/v2— README, QUICKSTART, thedocs/reference set, the Langfuse example, andeveros demo --liveall call the canonical/api/v2prefix instead of/api/v1./api/v1keeps resolving to the same handlers, so nothing breaks; it is now described as a legacy compatibility alias that may be removed in a future major release rather than a permanent one. New integrations should target/api/v2. cluster_repo.find_cluster_id_for_membernow requires(app_id, project_id, owner_id)— reverse-index lookups JOINClusterfor scope filtering.entry_idis per-owner unique by design; the reverse index alone could collide across owners writing on the same day.- All six cascade handlers register unconditionally — Tier-3 → Tier-2/1 downgrade no longer strands DELETE / PATCH events. Embed-requiring branches inside each handler body-guard on capability availability at execution time.
- Interactive TTY log level defaults to WARNING — avoids INFO log lines
drowning out backfill y/N prompts; non-interactive / CI stays at INFO.
--verbose/-vforces INFO. click>=8.1promoted to first-class dependency — was previously transitive via typer.typer.Abortandclick.exceptions.Abortare distinct classes under typer 0.15+ (typer vendored click); the interrupt catch incascade backfillcovers both.- Test harness pins
EVEROS_ROOTto a temp path —conftest.pyscrubs everyEVEROS_*env var so a developer's~/.everos/everos.tomlcannot make tests accidentally green against a real provider.
Fixed
- Fixes present in
1.1.4but missing from1.2.0— cascade retry classification + total-retry budget, the delete/modify race, the embedding empty-data guard, and episode extraction retries (each detailed under 1.1.4) were absent from the branch1.2.0was built from, so1.2.0regressed to pre-1.1.4 behaviour on all of them. See Security below for the path traversal. - Filename validation on knowledge upload — NUL byte and > 255-byte
UTF-8 filenames now fail fast with
InvalidInputError → HTTP 400instead of surfacing OS errors as 500 with a half-written md file. - HTML upload no longer takes the UTF-8 fast-path — knowledge
upload's plaintext short-circuit uses an explicit allowlist
(
text/plain,text/markdown,text/x-rst,text/x-markdown) plus known extensions;text/htmlis deliberately excluded so HTML still goes through everalgo'sclean_html_for_llm. Prevents 503 when a Tier-3 user without[multimodal]uploads a markdown doc. - Broken table-of-contents links in
docs/api.md— the endpoint anchors still pointed at the pre-1.2.0#post-apiv1…slugs after the headings moved to/api/v2, so all five endpoint links in the TOC were dead.
Removed
- README "Star us" section — cleanup.
Security
- Knowledge upload path traversal (CWE-22) — see the 1.1.4 entry for
the fix description. Affected: every release before
1.1.4, and1.2.0. Not affected:1.1.4. Fixed in:1.2.1. The fix shipped in1.1.4but was not present on the branch1.2.0was built from, so upgrading1.1.4→1.2.0reintroduced it.
[1.2.0] - 2026-07-24
This release is missing fixes that shipped in
1.1.4, including a knowledge-upload path traversal (CWE-22). See the Security section under 1.2.1 for the affected-version range.
Added
/api/v2API prefix — every business endpoint (memory/*,ome/*,knowledge/*) is now served under/api/v2, aligning the open-source API with the EverOS Cloud contract./api/v1is retained as a legacy compatibility alias: both prefixes resolve to the same handlers with identical request/response contracts, so existing integrations keep working unchanged. Infrastructure endpoints (/health,/metrics) stay unversioned.- Native OpenTelemetry tracing — memory operations (add / flush, memcell
boundary, episode extraction, search, and OME reflection) export to any
OTLP backend (e.g. Langfuse) as nested traces carrying LLM/embedding token
usage, per-request correlation, and recall-quality scores. Off by default;
enabled via the
[observability]config with the optionalotelextra. Content capture (query / extracted memory) is opt-in and redaction-aware.
1.1.4 - 2026-07-20
The entries below reflect the code shipped as
everos==1.1.4on PyPI. The 1.1.4 sdist was built from the internal release lane and contains fixes that were not represented in this file when 1.1.4 was tagged; this section restores them so the changelog matches the wheel.
Fixed
- Knowledge upload path traversal (CWE-22) — the original-file write
path is now contained to the document directory; adversarial filenames
(
.., absolute paths, symlink games) are rejected onPOST /api/v1/knowledge/documentsandPOST /api/v2/knowledge/documents. - Cascade reliability — retry classification, budget, and races — the
worker catches
ExternalServiceError(embedding / LLM / rerank transient failures) and retries inline up to 3 times before markingretryable=True; a total retry budget of 12 attempts across scanner cycles bounds retries on prolonged outages. The reconciler no longer re-enqueuespending/processingrows on stable mtime (previously overwrote the worker'smark_done);failedrows withretryable=Falseon stable mtime skip auto-retry so users can edit and re-save. SQLiteREALfloat precision loss in mtime comparisons is now absorbed via a 10 ms tolerance. LanceDBoptimize()failures escalate to adrop_index + create_indexrebuild after 5 consecutive misses (workaround forlance-format/lance#7653panic path). - Cascade delete/modify race — when a file disappears after its modified event is queued, the worker processes it as a deletion instead of leaving a stale indexed row and permanently failed queue item.
- Embedding provider raises on empty API data — the provider now
raises
EmbeddingServiceErrorwhen the API returns HTTP 200 with an emptydataarray (previously silently returned zero-length vectors, corrupting search). - Episode extraction retries on malformed LLM output — the
/flushsynchronous path retries everalgoValueError(typically OpenRouter truncated responses) twice with 1 s / 2 s backoff before surfacing a 500. - Langfuse live-server traces use only real telemetry — synthetic child spans are now limited to responses that provide stage details, while real servers emit accurate top-level latency, output, and recall-quality scores.
Added
- Optional
dimensionsparameter for MRL-capable embedding models — opt-in via[embedding] dimensions = Nineveros.toml; forwarded to the API for server-side truncation with re-normalization (OpenAI text-embedding-3-*, Qwen3-Embedding). - LLM
finish_reasondiagnostic warnings — logscontent_len/content_tail/modelwhen the provider returns a non-stopfinish_reason, aiding OpenRouter truncation triage. - Langfuse integration example — added an OpenTelemetry-based wrapper for tracing EverOS add, flush/extract, search, and reflection operations, with a built-in mock and support for connecting to a real EverOS server.
Changed
everalgo-user-memorybumped 0.3.1 → 0.3.2.
1.1.3 - 2026-07-10
Fixed
- LanceDB FTS optimize crash and disk growth — disabled unused positional data in OR-mode BM25 indexes, automatically rebuilds affected indexes, and escalates repeated optimize failures so cleanup cannot fail silently.
1.1.2 - 2026-07-07
Fixed
- Agent-track search broken by
deprecated_by IS NULLfilter —compile_filters()unconditionally appended adeprecated_by IS NULLclause to every LanceDB query, but onlyepisodeandatomic_facttables have this column. Agent-track search (agent_case,agent_skill) failed on any method. The clause is now conditional onowner_type == "user".
1.1.1 - 2026-07-06
Added
- DashScope rerank provider — Aliyun Bailian
gte-rerank-v2adapter; configure withrerank.provider = "dashscope"ineveros.toml. everos demoTUI command — Textual-based interactive CLI demo for showcasing EverOS core features.- Benchmark runner — full LoCoMo benchmark suite:
benchmarks/run.pywith TOML configuration, automated ingestion, search evaluation, and scoring. - Hybrid search: heap-expand algorithm — rewrote
hierarchy.pyto heap-driven lazy expansion with global top-N competition, replacing the serial four-layer pipeline.
Fixed
- Knowledge: atomic upsert prevents StaleDataError — cascade handler
switched from get→update to
INSERT ... ON CONFLICT DO UPDATE, fixing concurrent cascade race conditions. - API: OpenAPI version read from
__version__— no longer hardcoded to0.1.0; version now stays in sync withpyproject.toml. - Profile middleware no longer swallows exceptions — inner handler errors now re-raise correctly instead of silently returning HTTP 200.
Performance
- Cascade optimize throttle 1s → 10s — reduced unnecessary LanceDB
optimize()I/O by raising the minimum interval between calls.
CI / Build
- CI Python version matrix — test and integration jobs now run on both Python 3.12 and 3.13.
- pyproject.toml improvements — added
project.urls,Typing :: Typedclassifier, relaxedjiebaversion constraint, removed unusedpython-dotenvdependency, cleaned up sdist include list, addedRUFlint rules and coverage configuration. make ciincludes coverage —citarget now runslint + test + integration + cov.
Documentation
- Fixed stale references across 13 files (v1.1.0 freshness sweep).
- Added GitHub sync guide (
docs/github-sync.md). - Added v1.1.0 release notes and v1.0.0 migration guide as standalone docs.
- Added
README.zh-CN.md(Chinese README). - Expanded
QUICKSTART.mdwith source install instructions anduv runusage notes. - Clarified cascade
optimize()semantics in docstrings and runbook.
1.1.0 - 2026-06-24
Added
- Knowledge base subsystem — full-stack document management exposed via
/api/v1/knowledge/*. Upload documents (PDF / HTML / DOCX via multimodal parser), CRUD operations, and hybrid search (BM25 + vector + rerank + category boost). Ships with a 20-category default taxonomy (.taxonomy.md, auto-generated on first use). Original uploaded files are preserved alongside extracted Markdown. New settings group:knowledge.*(search tuning,max_upload_bytes, etc.). - Reflection V1 — offline memory self-improvement engine.
Select → Merge → Re-extract → Deprecate: clusters related episodes within
existing 7-day windows, merges them via LLM, re-extracts consolidated
episodes, and deprecates the originals. Runs as an OME strategy
(
reflect_episodes); configure viaome.toml([strategies.reflect_episodes], cron0 2 * * 1), changes are hot-reloaded within ~2 s, no restart needed; disabled by default. Requireseveralgo-user-memory>=0.3.1. - Standardized error response contract. All API errors now return a
canonical envelope with a semantic
ErrorCode(10 codes:NOT_FOUND,CONFLICT,INVALID_INPUT,EXTRACTION_EMPTY,UNSUPPORTED_FORMAT,EXTERNAL_SERVICE_UNAVAILABLE,CAPABILITY_UNAVAILABLE,CONFIGURATION_ERROR,INTERNAL_ERROR,BAD_REQUEST), per-type exception handlers with MRO dispatch, and anErrorResponsePydantic model visible in OpenAPI docs. Replaces the v1.0 two-code scheme (HTTP_ERROR/SYSTEM_ERROR). - Search: hierarchical fact eviction (Layer-4) with
min_scorefloor — low-confidence atomic facts are evicted before fusion, improving precision. - Knowledge search degradation guidance — when the embedding or rerank
provider fails at call time, the knowledge search route enriches the
error message with actionable guidance (e.g. retry with
method=keyword, which needs no embedding) before returning503. - Knowledge topic recaller — dual-column BM25 recall for knowledge topics, integrated into the search manager alongside existing recall types.
Changed
everos initnow generatesgpt-4.1-minias the default LLM model (wasgpt-4o-mini). Existing user configurations are not affected.- API error
codevalues have changed. v1.0 returned onlyHTTP_ERROR(all 4xx) andSYSTEM_ERROR(all 5xx). v1.1 returns fine-grained semantic codes (see Added above). Clients that match onerror.codestring values need to update. The envelope structure (request_id+error.{code, message, timestamp, path}) is unchanged. - DDD-aligned exception hierarchy — domain errors reorganized:
ValidationError→InvalidInputError;DocumentAlreadyExistsError→DuplicateDocumentError;EmbeddingError→EmbeddingServiceError;RerankError→RerankServiceError;LLMError→LLMServiceError(at the boundary);MultimodalErrorsplit intoUnsupportedModalityError(domain) +MultimodalNotEnabledError(infrastructure). New base classes:CapabilityError,ConfigurationError. infra/restructured — storage adapters moved underinfra/persistence/{markdown,sqlite,lancedb}; each sub-package's__init__.pyis the sole public API (enforced by import-linter).- Parser capability extracted to
component/parser(shared by memorize and knowledge upload paths).
Fixed
- Knowledge search no longer returns a bare
500 INTERNAL_ERRORwhen the embedding or rerank provider is unconfigured._require_search_providersnow raisesConfigurationError→500 CONFIGURATION_ERROR. A provider that is configured but fails at call time still surfaces as503 EXTERNAL_SERVICE_UNAVAILABLE. - Knowledge document uploads are capped at
knowledge.max_upload_bytes(default 50 MiB); oversized uploads are rejected with422before parsing. - Knowledge search
queryis bounded to 2000 chars. GET /knowledge/documents?sort_by=updated_atis now accepted.POST /knowledge/documentsreturnsoriginal_file_pathso callers no longer need a follow-upGETto locate the preserved upload.- Rerank providers no longer echo the upstream HTTP response body into the
client-facing
503message (vLLM / DeepInfra); the body is logged instead. - Knowledge FK cascade race — removed the foreign key on
knowledge_topics.doc_idthat caused delete-order race conditions; cascade cleanup handled at application level. - Knowledge
replace_document— atomic PUT: backup old Markdown before re-extraction; removed explicit SQLite delete for atomicity. - Knowledge duplicate
doc_idrejected on create; title collision resolved by appendingdoc_idto directory name. - Knowledge
md_pathresolution fixed indelete_document(was not resolved againstmemory_root). - OME file-handle leak — portalocker file handle is now closed on lock contention instead of being left open.
- jieba / Python 3.12 compatibility — deferred jieba import to avoid
SyntaxErrorfrom invalid escape sequences; suppressedDeprecationWarningin tests. - Test isolation — tests no longer leak
.envstate or depend on module import ordering.
Documentation
- Added knowledge base technical documentation.
- Corrected the onboarding flow:
everos initwriteseveros.toml+ome.toml(TOML), not a.envfile; removed the nonexistent--xdg/--env-fileoptions and the false0600-permissions claim fromREADME.md/QUICKSTART.md; fixed the stable-version line (v1.0.1) and completed thedocs/cli.mdcommand tree. - Updated error handling docs to match the new DDD exception hierarchy.
1.0.1 - 2026-06-16
Security
- Path-traversal hardening for caller-supplied identifiers.
sender_id(which flows through toowner_idand becomes a directory segment on the episode write path) now carries the same path-safety guard asapp_id/project_id: a character whitelist plus rejection of the./..tokens. The whitelist admits@and+so real-world ids (email-style, plus-addressing) still pass. - Defense-in-depth write containment.
MarkdownWriternow rejects any write target that resolves outside the configured memory root, before any filesystem touch (both the writemkdirand the append read-modify-write read). This backstop holds even if an identifier reaches the writer unsanitised (e.g. anowner_idset in the extract pipeline rather than from the DTO). The API layer maps the resulting error to HTTP 400.
Documentation
- Add a multimodal usage guide and correct the multimodal error semantics after end-to-end verification.
- Rename the algorithm library to
everalgoacross docs and code comments (no code identifiers changed). - Fix accuracy drift found in an adversarial doc audit; reflect the
everalgopackages being published and the v1.0.0 stable status.
1.0.0 - 2026-06-03
First public release of EverOS — a Markdown-first memory extraction framework for AI agents.
Added
- Markdown as source of truth — all memory persists as plain
.mdfiles you can open, edit, grep, and version with Git. - Lightweight three-piece storage — Markdown (truth) + SQLite (state / queue / audit) + LanceDB (vector + BM25 + scalar index). No external services required.
- Hybrid retrieval — BM25, vector, and scalar filtering in a single LanceDB query.
- Cascade index sync — editing a
.mdfile triggers a file watcher → entry-level diff → sub-second LanceDB sync. - Dual-track memory — user-track (Episodes / Profiles) and agent-track (Cases / Skills).
- Multi-source extraction — conversations, workflows, agent traces, and file knowledge.
- CLI + HTTP API — the
everoscommand-line tool and a FastAPI server, async-first throughout. - Pluggable providers — LLM / embedding / rerank via the OpenAI-compatible protocol (works with OpenAI, OpenRouter, vLLM, Ollama, …).
- Decoupled algorithms — memory extraction algorithms live in the standalone
everalgo-*libraries published on PyPI.