AI memory engine with identity preservation โ remember everything, forget nothing
Project description
๐ evaOS (Electric Sheep)
AI memory that remembers who you are.
Identity-preserving memory engine for AI agents.
Your agent wakes up tomorrow and still knows who it is.
What's New in v1.2
๐ v1.2 is the cognitive pipeline release โ a complete memory lifecycle from wake to sleep, with intelligent retrieval, context compilation, and production observability.
- Session Boot Loader โ Deterministic boot sequence loads continuity context (handoff, identity, commitments, preferences) at session start
- Task-Mode Classification โ Zero-LLM query classification into 8 task modes (debug, plan, write, recall, etc.) for intelligent retrieval routing
- Retrieval Policy Engine โ Task-mode-driven channel selection: which retrieval channels to query, with what budget weights
- Context Compiler โ Assembles retrieval results into injection-ready bundles with strict token budgeting and priority-based compression
- Injection Slot Manager โ Deterministic assignment of compiled bundles to prompt positions (system prefix โ post-system โ pre-user โ appendix)
- Mid-Turn Re-Retrieval โ Detects topic shifts and new entities mid-conversation, triggering supplemental memory retrieval
- Working Memory Cache โ Fast in-memory session store with LRU eviction and TTL, checked before DB queries
- Token Budget Overhaul โ Context-window-fraction budgeting, slot-priority allocation, and multi-level compression (evidence โ compact โ pointer)
- Promotion Scoring โ Six-factor weighted scoring for session โ long-term memory promotion during sleep
- Model Routing โ Three-tier model routing (fast/main/reasoning) with operation-to-tier mapping and fallback chains
- Metrics & Quality Gates โ Pipeline observability with counters, histograms, gauges, and threshold-based quality gates
- Feature Flags โ Deterministic hash-based feature gating for gradual rollout control
- Circuit Breaker โ Per-provider circuit breaker for quota/rate-limit resilience (reads continue when writes are blocked)
See the CHANGELOG for the full list of changes, and the v1.2 documentation for architecture deep-dives.
Why evaOS?
Most AI memory systems are glorified vector stores. They dump embeddings into a database and call it "memory." The result: progressive identity drift (your agent slowly forgets who it is), junk accumulation (10,000 useless coding-session memories), and no lifecycle (no consolidation, no forgetting, no sleep).
evaOS is a cognitive memory engine grounded in memory research. It extracts claims, resolves entities, protects core identity, and runs dream cycles to consolidate and prune โ just like biological memory.
Install
pip install evaos
With vector search (recommended):
pip install "evaos[vec]"
All extras (LLM providers, HTTP API, MCP server):
pip install "evaos[all]"
30-Second Quickstart
CLI:
# Initialize a new memory store
evaos init
# Teach it something
evaos remember "Andrew is the founder of 100Yen Org. He lives in Bangkok."
# Ask it later
evaos recall "Where does Andrew live?"
# โ Andrew lives in Bangkok. He is the founder of 100Yen Org.
# Ask your memory (Dialectic Engine โ new in v1.1)
evaos ask "What do I know about Andrew's work?"
# โ Multi-step reasoning across your memory graph
Python SDK:
import asyncio
from evaos import Cortex
async def main():
cortex = Cortex(db_path="my_memory.db", profile="companion")
await cortex.initialize()
# Start a session
await cortex.wake(session_id="session_001")
# Store information โ claim extraction happens automatically
await cortex.remember("Andrew is the founder of 100Yen Org. He lives in Bangkok.")
# Retrieve relevant memories for an LLM prompt
context = await cortex.retrieve("Where does Andrew live?")
print(context.context_block)
# โ "Andrew lives in Bangkok. He is the founder of 100Yen Org."
# End the session
await cortex.sleep(session_id="session_001")
asyncio.run(main())
That's it. Memories persist in a local SQLite database, searchable via hybrid BM25 + vector retrieval.
Features
๐ง 5-Layer Memory Model
| Layer | What It Does |
|---|---|
| Extraction | LLM-powered claim extraction with noise filtering (skips "changed line 47 of auth.py") |
| Entity Resolution | Fuzzy deduplication โ "Andrew", "andrew", "@andrew" โ same person |
| Reconciliation | Smart conflict resolution: ADD / UPDATE / SUPERSEDE / NOOP |
| Cornerstones | Immutable identity anchors that resist drift and accidental deletion |
| Token Budget | Assembles memory context within configurable token ceilings |
๐ Dream Cycles & Staged Sleep Pipeline
Circadian engine with sleep/wake/dream phases. The staged sleep pipeline (S1โS2โS3โS4) consolidates session memories, promotes important claims, builds handoff packets for session continuity, and carries forward open loops. During dream cycles, evaOS runs Ebbinghaus decay, calculates identity drift, and generates curiosity seeds.
๐ Commitments & Open Loops (v1.2)
First-class tracking of agent commitments and unresolved threads. Commitments track promises with due dates. Open loops track dangling threads across sessions. Stale loops auto-resolve after 5 cycles. Both inject into session boot context for continuity.
โก Activation Routing (v1.2)
Wake pipeline (W1โW4) enriches memories with activation metadata โ intrinsic type, stability, explicitness โ and writes structured activation policies. Zero LLM cost. Enables intelligent memory surfacing based on context, not just similarity.
๐ฌ Dialectic Engine (v1.1)
Ask your memory natural-language questions. Fast path for simple lookups, agentic multi-step QueryPlanner for complex reasoning across your memory graph.
๐ฅ Peer Modeling (v1.1)
Track relationships between entities. Auto-creates peer records from entity resolution, builds relationship representations, and integrates with dream cycles for periodic peer refresh.
๐ธ๏ธ Brain Graph
File-watcher + auto-registration document memory graph. Index your docs, specs, and decisions โ query them alongside conversational memory.
๐ Graph Visualization (v1.1)
Force-directed graph data endpoints for visualizing memory relationships: nodes, edges, paths, and neighbors.
๐ฅ๏ธ Dashboard (v1.1)
8-page web UI for exploring your memory engine: memories, entities, cornerstones, peers, brain graph, events, configuration, and health status.
๐ Webhooks (v1.1)
Subscribe to 16 event types with reliable webhook delivery, automatic retry, and event filtering.
๐ Hybrid Retrieval
BM25 full-text search + vector similarity with Reciprocal Rank Fusion. Optional agentic re-ranking for high-stakes queries.
๐ก๏ธ Resilience (v1.1)
- LLM retry with exponential backoff and provider cascade
- Embedding model switch protection (prevents silent vector corruption)
- API key redaction in all log output
- SQLite integrity checks on startup
- 40 write locks, NaN validation, OOM protection
๐ Five Interfaces
| Interface | Use Case |
|---|---|
| CLI | evaos remember, evaos recall, evaos ask, evaos dream |
| HTTP API | FastAPI REST server โ evaos serve |
| MCP Server | Model Context Protocol for agent frameworks โ evaos mcp |
| TypeScript SDK | @evaos/client โ typed client for Node.js applications |
| OpenClaw Plugin | eva-memory โ drop-in memory plugin for OpenClaw agents |
Python SDK Reference
The Cortex class is the recommended way to embed evaOS memory into Python applications.
from evaos import Cortex
# Default โ uses OpenAI, stores in cortex.db
cortex = Cortex()
# Customised
cortex = Cortex(
db_path="~/my_app/memory.db",
profile="companion", # companion | developer | local | minimal
llm_provider="openai", # openai | anthropic | ollama
extract_model="gpt-4.1-nano-2025-04-14",
embed_model="text-embedding-3-small",
)
# From a config file
cortex = Cortex.from_config("~/.config/cortex.toml")
Core methods
| Method | Description |
|---|---|
await cortex.initialize() |
Initialize storage + apply migrations |
await cortex.wake(session_id) |
Start a session, load cornerstones |
await cortex.remember(content) |
Store text/conversation; extraction is automatic |
await cortex.retrieve(query) |
Hybrid BM25 + vector search, returns context block |
await cortex.ask(query) |
Dialectic engine โ ask your memory questions |
await cortex.sleep(session_id) |
End session, trigger consolidation |
await cortex.dream() |
Run overnight reconsolidation cycle manually |
await cortex.seal_cornerstone(label, content) |
Pin an identity anchor |
await cortex.check_drift() |
Drift scores for all cornerstones |
await cortex.feedback(claim_id, "helpful") |
Rate a retrieved memory |
await cortex.health() |
System health dict |
await cortex.stats() |
Memory counts (claims, entities, cornerstones, sessions) |
await cortex.export(format="json") |
Export all active memories |
TypeScript SDK
npm install @evaos/client
import { CortexClient } from '@evaos/client';
const client = new CortexClient({
baseUrl: 'http://localhost:8420',
apiKey: 'your-api-key',
});
// Store a memory
await client.remember('Andrew is the founder of 100Yen Org.');
// Retrieve memories
const results = await client.recall('Who is Andrew?');
console.log(results.context_block);
See sdks/typescript/ for full documentation.
OpenClaw Plugin
evaOS ships an OpenClaw plugin (eva-memory) that bridges your agent's memory to a running Cortex instance. Drop it into your OpenClaw setup for automatic memory recall and capture.
// openclaw.plugin.json (included in openclaw-plugin/)
{
"id": "eva-memory",
"kind": "memory"
// configSchema: cortexUrl, apiKey, ownerId, autoRecall, autoCapture, ...
}
What it does:
- before_agent_start โ retrieves relevant memories and injects them into context
- agent_end โ captures conversation content as new memories (fire-and-forget)
- session_start / session_end โ calls wake/sleep for session lifecycle
- Tools exposed:
cortex_search,cortex_remember,cortex_forget
See openclaw-plugin/ for the full source and configuration schema.
Architecture
Full Pipeline: Wake โ Boot โ Retrieve โ Compile โ Inject โ Re-Retrieve โ Sleep
โโโโโโโโโโโโโโโโโโโโโ SESSION LIFECYCLE โโโโโโโโโโโโโโโโโโโโโ
โ โ
โ WAKE MID-TURN SLEEP โ
โ โโโโ โโโโโโโโ โโโโโ โ
โ โ
โ โโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Wake โ โ Retrieve โ โ Sleep Pipeline โ โ
โ โ Pipelineโ โ Pipeline โ โ S1 Consolidation โ โ
โ โ W1โW4 โ โ BM25+Vector โ โ S2 Promotion โ โ
โ โโโโโโฌโโโโโ โ +RRF+Rerank โ โ S3 Handoff โ โ
โ โ โโโโโโโโโฌโโโโโโโ โ S4 Carry-Forward โ โ
โ โผ โ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโ โ โฒ โ
โ โ Boot โ โผ โ โ
โ โ Loader โ โโโโโโโโโโโโโโโโโ โโโโโโโดโโโโโโโ โ
โ โ (hand- โ โTask-Mode โ โ Circadian โ โ
โ โ off, โ โClassifier โ โ Engine โ โ
โ โ identityโ โโโโโโโโโฌโโโโโโโโ โ (dream, โ โ
โ โ prefs) โ โ โ decay) โ โ
โ โโโโโโฌโโโโโ โผ โโโโโโโโโโโโโโ โ
โ โ โโโโโโโโโโโโโโโโโ โ
โ โ โRetrieval โ โ
โ โ โPolicy Engine โ โ
โ โ โโโโโโโโโฌโโโโโโโโ โ
โ โ โ โ
โ โ โผ โ
โ โ โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโ โ
โ โ โ Context โ โ Re-Retrieval โ โ
โ โ โ Compiler โโโโ (topic shift, โ โ
โ โ โ (bundle + โ โ new entities) โ โ
โ โ โ compress) โ โโโโโโโโโโโโโโโโโ โ
โ โ โโโโโโโโโฌโโโโโโโโ โ
โ โ โ โ
โ โ โผ โ
โ โ โโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโบโ Injection โ โ
โ โ Slot Manager โ โ
โ โ (prompt โ โ
โ โ assembly) โ โ
โ โโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโ CROSS-CUTTING SERVICES โโโโโโโโโโโโโโโโโโโ
โ โ
โ Working Memory Cache Token Budget Manager โ
โ Model Router (3-tier) Promotion Scorer (6-factor) โ
โ Metrics Collector Quality Gates โ
โ Feature Flags Circuit Breaker โ
โ Feedback System Contradiction Tracker โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโ INFRASTRUCTURE โโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโ โ
โ โ CLI โ HTTP API โ MCP โ TypeScript SDK โ โ
โ โโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Extraction โ Entity Res. โ Reconciliation โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ Cornerstones โ Drift Calc โ Dialectic Engine โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ Peer Modeling โ Brain Graph โ Webhooks/Events โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ Commitments โ Open Loops โ Activation Router โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ SQLite + FTS5 + sqlite-vec โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Configuration
evaOS uses a cortex.toml config file:
[cortex]
storage_backend = "sqlite"
[cortex.storage]
db_path = "evaos.db"
[cortex.extraction]
model = "gpt-4.1-nano"
coding_noise_filter = true
[cortex.cornerstones]
max_count = 7
drift_threshold = 0.05
[cortex.circadian]
dream_cycle_enabled = true
dream_cycle_hour_utc = 8
auto_sleep_after_minutes = 30
[cortex.deprecation]
forgetting_curve = "ebbinghaus"
See docs/ for full configuration reference and architecture deep-dives.
v1.2 Documentation
| Document | Description |
|---|---|
| Architecture Overview | Full v1.2 pipeline walkthrough |
| Config Reference | All new TOML fields with defaults and validation rules |
| Integration Guide | Developer guide for configuring and extending v1.2 subsystems |
| Working Memory API | Working memory cache API reference |
| Token Budget API | Token budget manager API reference |
| Promotion Scoring API | Multi-factor promotion scoring API reference |
| Model Routing API | Three-tier model routing API reference |
| Changelog | Sprint-by-sprint changelog for v1.2 |
CLI Reference
evaos init [--profile companion|coding|enterprise]
evaos remember "text"
evaos recall "query"
evaos ask "question" # Dialectic engine (v1.1)
evaos ask "question" --agentic # Multi-step reasoning
evaos cornerstones list
evaos cornerstones seal --label "name" --content "text"
evaos dream
evaos stats
evaos health
evaos export [--format json|sql]
evaos serve [--port 8000]
evaos mcp
evaos backup [--output path]
Dashboard
evaOS includes a built-in web dashboard for exploring and managing your memory engine.
evaos serve
# Dashboard available at http://localhost:8420/dashboard
Pages: Memories ยท Entities ยท Cornerstones ยท Peers ยท Brain Graph ยท Events ยท Config ยท Health
Project Structure
cortex/ # 148 Python modules | ~52K lines
โโโ core/ # Extraction, entity resolution, reconciliation, retrieval, contradictions,
โ # working memory, token budget, promotion, task-mode, retrieval policy,
โ # context compiler, injection slots, boot loader, re-retrieval,
โ # metrics, quality gates, feature flags
โโโ storage/ # SQLite adapter with FTS5 + vector support, 11 query mixins, v3-v9 migrations
โโโ brain_graph/ # Document memory graph with file watching
โโโ circadian/ # Sleep/wake/dream cycle engine (CircadianEngine + CuriosityEngine)
โโโ sleep/ # Staged sleep pipeline: S1 consolidation โ S2 promotion โ S3 handoff โ S4 carry-forward
โโโ capture/ # Wake pipeline: W1-W4 activation routing, episode adapter
โโโ commitments/ # Commitment/open loop tracking + carry-forward
โโโ deprecation/ # Ebbinghaus decay pipeline
โโโ identity/ # Cornerstone guardian + drift calculator
โโโ config/ # TOML config loading + profiles
โโโ api/ # FastAPI HTTP server (85 endpoints), 18 route modules
โโโ integrations/ # MCP server (15 tools) + plugin interface
โโโ dialectic/ # Dialectic engine (ask your memory)
โโโ peers/ # Peer modeling (relationship tracking)
โโโ events/ # Event emitter + webhook dispatcher
โโโ llm/ # Multi-provider LLM abstraction with fallback
โโโ cli.py # Click-based CLI (1,360 lines)
โโโ sdk.py # High-level Cortex class for external consumers
โโโ types.py # Shared dataclasses and types
dashboard/ # 8-page web UI (SPA)
sdks/typescript/ # @evaos/client TypeScript SDK
openclaw-plugin/ # eva-memory OpenClaw plugin (TypeScript)
Benchmarks
evaOS ships a benchmark suite that measures core operation latency and throughput. All benchmarks use mocked LLM/embedding providers โ we measure evaOS code performance, not API latency.
Run benchmarks
# Full suite (retrieval at 10K scale takes ~2-3 min)
python -m benchmarks.run_benchmarks
# Skip slow 10K retrieval during development
python -m benchmarks.run_benchmarks --skip-retrieval
# Individual suites
python -m benchmarks.bench_retrieval
python -m benchmarks.bench_remember
python -m benchmarks.bench_consolidation
Results are saved to benchmarks/results/latest.json.
What's measured
| Suite | What | Scales |
|---|---|---|
bench_retrieval |
vector search, FTS (BM25), hybrid RRF | 100 / 1k / 10k claims |
bench_remember |
extract + embed + store pipeline | single / batch 10 / batch 50 |
bench_consolidation |
sleep() consolidation pass |
100 / 500 / 1k claims |
Metrics: p50 / p95 / p99 latency in ms, 50 runs per measurement (10 for consolidation). Vectors: 1024-dim, deterministic seed=42.
Docker
Run evaOS as a container โ no Python setup required.
Quick start
# Clone the repo (or just grab the docker-compose.yml)
git clone https://github.com/100yenadmin/electric-sheep.git
cd electric-sheep
# Set your API keys
export OPENAI_API_KEY=sk-...
export VOYAGE_API_KEY=pa-...
# Start the server
docker compose up -d
The HTTP API is now available at http://localhost:8420.
Build the image manually
docker build -t evaos .
docker run -d \
-p 8420:8420 \
-v evaos-data:/data \
-e OPENAI_API_KEY=$OPENAI_API_KEY \
-e VOYAGE_API_KEY=$VOYAGE_API_KEY \
evaos
Environment variables
| Variable | Default | Description |
|---|---|---|
CORTEX_DB_PATH |
/data/cortex.db |
Path to the SQLite database |
CORTEX_API_KEY |
(none) | API key to protect the HTTP server |
OPENAI_API_KEY |
(none) | OpenAI API key for LLM operations |
OPENAI_BASE_URL |
(none) | Custom OpenAI-compatible base URL |
VOYAGE_API_KEY |
(none) | Voyage AI key for embeddings |
Persistent storage
The container stores cortex.db in /data by default. The docker-compose.yml creates a named volume (evaos-data) that survives container restarts and updates.
Health check
curl http://localhost:8420/api/v1/health
The container exposes a built-in healthcheck on the same endpoint (30s interval, 5s timeout, 3 retries).
Contributing
See CONTRIBUTING.md for dev setup, testing, and PR guidelines.
License
MIT โ 100Yen Org
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file evaos-1.2.0.tar.gz.
File metadata
- Download URL: evaos-1.2.0.tar.gz
- Upload date:
- Size: 905.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebdef1af700413120a9d4ba53a9a597110a7ff09a1a3e04b0ab84f12f0d05eb7
|
|
| MD5 |
68d5227e70943b24fec5ed3e7f81e209
|
|
| BLAKE2b-256 |
4883494997a95ea2e749e89d1e88dbbe06207022511ae3b20a2d73b662dd330e
|
Provenance
The following attestation bundles were made for evaos-1.2.0.tar.gz:
Publisher:
publish.yml on 100yenadmin/electric-sheep
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
evaos-1.2.0.tar.gz -
Subject digest:
ebdef1af700413120a9d4ba53a9a597110a7ff09a1a3e04b0ab84f12f0d05eb7 - Sigstore transparency entry: 1090440383
- Sigstore integration time:
-
Permalink:
100yenadmin/electric-sheep@bcc1deb4082921684d126f1ae69d90536d2c90db -
Branch / Tag:
refs/tags/v1.2.1 - Owner: https://github.com/100yenadmin
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bcc1deb4082921684d126f1ae69d90536d2c90db -
Trigger Event:
release
-
Statement type:
File details
Details for the file evaos-1.2.0-py3-none-any.whl.
File metadata
- Download URL: evaos-1.2.0-py3-none-any.whl
- Upload date:
- Size: 627.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed08e3853a105839f7eb195fd681975ec95d62b252e501c1a080dbdd44f98747
|
|
| MD5 |
cf02400fb2c82bda885f5e1837d9d69c
|
|
| BLAKE2b-256 |
21537d3c007085ab3732e8eddbee7b5d294a182b710ec1726d9acf0927cf45c4
|
Provenance
The following attestation bundles were made for evaos-1.2.0-py3-none-any.whl:
Publisher:
publish.yml on 100yenadmin/electric-sheep
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
evaos-1.2.0-py3-none-any.whl -
Subject digest:
ed08e3853a105839f7eb195fd681975ec95d62b252e501c1a080dbdd44f98747 - Sigstore transparency entry: 1090440387
- Sigstore integration time:
-
Permalink:
100yenadmin/electric-sheep@bcc1deb4082921684d126f1ae69d90536d2c90db -
Branch / Tag:
refs/tags/v1.2.1 - Owner: https://github.com/100yenadmin
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bcc1deb4082921684d126f1ae69d90536d2c90db -
Trigger Event:
release
-
Statement type: