[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "remembra" version = "0.16.0" description = "Universal memory layer for AI applications. Self-host in minutes." readme = "README.md" license = { text = "MIT" } requires-python = ">=3.11" authors = [ { name = "DolphyTech", email = "admin@dolphytech.com" }, ] maintainers = [ { name = "Damany Dolphy", email = "admin@dolphytech.com" }, ] keywords = [ "ai", "memory", "llm", "rag", "vector-search", "embeddings", "chatbot", "agent", "mcp", "model-context-protocol", "langchain", "openai", ] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed", ] # Core SDK only needs httpx dependencies = [ "bcrypt>=5.0.0", "httpx>=0.27.0", "slowapi>=0.1.9", ] [project.optional-dependencies] # Full server dependencies server = [ "fastapi>=0.115.0", "uvicorn[standard]>=0.32.0", "pydantic>=2.9.0", "pydantic-settings>=2.6.0", "qdrant-client>=1.12.0,<2.0.0", "python-ulid>=3.0.0", "pyotp>=2.9.0", "qrcode[pil]>=7.4.0", "structlog>=24.4.0", "aiosqlite>=0.20.0", "openai>=1.0.0", "tiktoken>=0.7.0", "bcrypt>=4.0.0", "slowapi>=0.1.9", "python-multipart>=0.0.9", "PyJWT>=2.8.0", "email-validator>=2.0.0", ] # MCP server dependencies # NOTE: structlog is required transitively — remembra.mcp.server imports # remembra.security.error_sanitizer which uses structlog. Without it, the # `remembra-mcp` binary crashes at import with ModuleNotFoundError when # installed via `pipx install .[mcp]` alone. mcp = [ "mcp>=1.0.0", "structlog>=24.4.0", ] # LangChain integration langchain = [ "langchain-core>=0.3.0", ] # LangGraph integration (BaseStore long-term memory) langgraph = [ "langgraph>=0.2.0", ] # OpenAI Agents SDK integration (Session protocol) openai-agents = [ "openai-agents>=0.1.0", ] # CrewAI integration crewai = [ "crewai>=0.80.0", ] # Anthropic Claude integration (entity extraction, LLM provider) anthropic = [ "anthropic>=0.39.0", ] # Encryption at rest (AES-256-GCM) encryption = [ "cryptography>=42.0.0", ] # Cloud / SaaS dependencies (billing, metering) cloud = [ "resend>=0.7.0", ] # Advanced retrieval (optional reranking) rerank = [ "sentence-transformers>=2.5.0", ] # OpenTelemetry tracing (optional, for production observability) tracing = [ "opentelemetry-api>=1.20.0", "opentelemetry-sdk>=1.20.0", "opentelemetry-exporter-otlp>=1.20.0", "opentelemetry-instrumentation-fastapi>=0.40b0", ] # Development dependencies dev = [ "pytest>=8.3.0", "pytest-asyncio>=0.24.0", "pytest-cov>=6.0.0", "ruff>=0.8.0", "mypy>=1.13.0", "build>=1.0.0", "twine>=5.0.0", "types-dateparser>=1.2.0", ] # All dependencies (SDK + Server + Rerank + MCP + Integrations + Cloud) all = [ "remembra[server,rerank,mcp,langchain,crewai,cloud,anthropic,encryption]", ] [project.urls] Homepage = "https://github.com/remembra-ai/remembra" Documentation = "https://github.com/remembra-ai/remembra#readme" Repository = "https://github.com/remembra-ai/remembra.git" Issues = "https://github.com/remembra-ai/remembra/issues" Changelog = "https://github.com/remembra-ai/remembra/blob/main/CHANGELOG.md" [project.scripts] remembra = "remembra.main:run" remembra-server = "remembra.main:run" remembra-mcp = "remembra.mcp.server:main" remembra-bridge = "remembra.tools.bridge:main" remembra-install-codex = "remembra.tools.codex:main" remembra-install = "remembra.tools.agents:main" remembra-doctor = "remembra.tools.doctor:main" # --------------------------------------------------------------------------- # Hatch build config # --------------------------------------------------------------------------- [tool.hatch.build.targets.wheel] packages = ["src/remembra"] [tool.hatch.build.targets.sdist] include = [ "/src", "/tests", "/README.md", "/LICENSE", "/pyproject.toml", ] # --------------------------------------------------------------------------- # Ruff # --------------------------------------------------------------------------- [tool.ruff] src = ["src"] target-version = "py311" line-length = 130 [tool.ruff.lint] select = ["E", "F", "I", "UP", "B", "SIM", "ANN"] ignore = [ "ANN001", # Missing type annotation for function argument - some are intentional "ANN201", # Missing return type - some are intentional for factories/Any returns "ANN401", # Dynamically typed expressions (Any) "B008", # Function call in default arg - intentional for FastAPI Depends() "B904", # Exception chaining - intentional for HTTP error transformation "B024", # ABC without abstract method - sometimes intentional "B027", # Empty method in ABC without @abstractmethod - sometimes intentional "SIM102", # Collapsible if - sometimes less readable when combined "SIM105", # contextlib.suppress - often less readable "SIM108", # Ternary operator - sometimes less readable for complex conditions ] [tool.ruff.lint.per-file-ignores] "tests/**/*.py" = ["ANN", "I"] # Don't require type annotations or import sorting in tests "src/remembra/extraction/prompts/*.py" = ["E501"] # Prompts can have long lines for readability "src/remembra/extraction/consolidator.py" = ["E501"] # Prompt strings "src/remembra/extraction/extractor.py" = ["E501"] # Prompt strings "src/remembra/extraction/matcher.py" = ["E501"] # Prompt strings "src/remembra/extraction/entities.py" = ["E501"] # Prompt strings [tool.ruff.lint.isort] known-first-party = ["remembra"] # --------------------------------------------------------------------------- # Mypy # --------------------------------------------------------------------------- [tool.mypy] python_version = "3.11" strict = true files = ["src/remembra"] plugins = ["pydantic.mypy"] [[tool.mypy.overrides]] # Third-party libs without type stubs, and optional runtime deps that are # imported behind try/except (not installed in the type-check env). module = [ "qdrant_client.*", "structlog.*", "dateparser.*", "sentence_transformers.*", "aiosmtplib.*", "anthropic.*", "opentelemetry.*", ] ignore_missing_imports = true # --------------------------------------------------------------------------- # Pytest # --------------------------------------------------------------------------- [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] addopts = ["--cov=remembra", "--cov-report=term-missing", "--cov-report=xml"] markers = [ "integration: tests requiring external services or network access", ] [tool.coverage.run] source = ["src/remembra"] omit = ["*/tests/*"] [dependency-groups] dev = [ "mkdocs>=1.6.1", "mkdocs-material>=9.7.3", ]