chore: initialize EverOS 1.0.0

md-first memory extraction framework for AI agents.

Markdown is the single source of truth; SQLite holds state and LanceDB
provides the rebuildable vector + BM25 + scalar index. The codebase follows
a single-direction DDD layering (entrypoints -> service -> memory -> infra,
with component / core / config cross-cutting) enforced by import-linter.

Engineering surface:
- Coding conventions in .claude/rules/ (path-scoped) and workflows in
  .claude/skills/ (/commit, /new-branch, /pr).
- GitHub Actions CI runs make lint + test + integration; pre-commit mirrors
  the gates locally (ruff, hygiene hooks, gitlint commit-msg).
- Commit messages follow Conventional Commits, enforced by gitlint.
- make lint also enforces datetime two-zone discipline and OpenAPI drift.
This commit is contained in:
Elliot Chen
2026-06-05 22:35:51 +08:00
commit 518b8eca85
636 changed files with 160553 additions and 0 deletions

View File

@ -0,0 +1,78 @@
"""OME event base class + built-in tick events.
All business events should subclass BaseEvent. OME emits three built-in
ticks for engine-driven triggers (Cron / Idle / Manual).
"""
from __future__ import annotations
import importlib
from datetime import datetime
from functools import cache
from typing import Any
from uuid import uuid4
from pydantic import BaseModel, ConfigDict, Field
from everos.component.utils.datetime import get_utc_now
class BaseEvent(BaseModel):
"""Base for all events flowing through OME.
Subclasses must be Pydantic v2 models (immutable) so `model_dump_json` /
`model_validate_json` work for crash-recovery payload persistence.
"""
model_config = ConfigDict(frozen=True, extra="forbid")
event_id: str = Field(default_factory=lambda: uuid4().hex)
ts: datetime = Field(default_factory=get_utc_now)
@classmethod
def topic(cls) -> str:
"""Stable cross-process identifier of this event class.
Returns ``"<module>:<class>"`` (colon-separated, mirroring the
Python event-sourcing community convention). Used by OME to
persist event identity into RunRecord.event_topic and to re-import
the class during crash recovery via ``resolve_topic``.
"""
return f"{cls.__module__}:{cls.__name__}"
@cache
def resolve_topic(topic: str) -> type[BaseEvent]:
"""Inverse of ``BaseEvent.topic()``; imports and returns the class.
Cached because crash recovery may resolve the same topic many times in
a tight loop, and ``importlib.import_module`` is non-trivial.
"""
module_name, sep, cls_name = topic.partition(":")
if not sep or not cls_name:
raise ValueError(f"invalid event topic: {topic!r}")
mod: Any = importlib.import_module(module_name)
cls = getattr(mod, cls_name, None)
if not (isinstance(cls, type) and issubclass(cls, BaseEvent)):
raise TypeError(f"topic {topic!r} did not resolve to a BaseEvent subclass")
return cls
class CronTick(BaseEvent):
"""Engine-emitted event for a strategy with `trigger=Cron(...)`."""
strategy_name: str
class IdleTick(BaseEvent):
"""Engine-emitted event for a strategy with `trigger=Idle(...)`."""
strategy_name: str
bucket_key: str
idle_seconds: int
class ManualTick(BaseEvent):
"""Engine-emitted event for `engine.trigger_manual(name, event=None)`."""
strategy_name: str