Metadata-Version: 2.4
Name: forgememory-enterprise
Version: 1.0.0
Summary: Python SDK for ForgeMemory Enterprise — multi-tenant AI memory at scale
Project-URL: Homepage, https://forgememory.io
Project-URL: Documentation, https://forgememory.io/docs
Project-URL: Repository, https://github.com/MbartPhoto/ForgeMemoryEnterprise
Author-email: Bart Labs <hello@bartlabs.com>
License-Expression: BUSL-1.1
Keywords: ai,enterprise,forgememory,memory,multi-tenant
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.0
Provides-Extra: autogen
Requires-Dist: pyautogen>=0.2.0; extra == 'autogen'
Provides-Extra: crewai
Requires-Dist: crewai>=0.28.0; extra == 'crewai'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: langgraph
Requires-Dist: langgraph>=0.1.0; extra == 'langgraph'
Description-Content-Type: text/markdown

# ForgeMemory Enterprise Python SDK

Production-quality Python client for [ForgeMemory Enterprise](https://github.com/BartLabs/ForgeMemoryEnterprise) — multi-tenant AI memory at scale.

## Installation

```bash
pip install forgememory-enterprise
```

With framework adapters:

```bash
pip install "forgememory-enterprise[crewai]"     # CrewAI integration
pip install "forgememory-enterprise[langgraph]"   # LangGraph integration
pip install "forgememory-enterprise[autogen]"     # AutoGen integration
```

## Quick Start

```python
from forgememory_enterprise import EnterpriseClient
from forgememory_enterprise.types import CreateMemoryRequest

client = EnterpriseClient(api_key="fme_your_key", base_url="https://your-server:8201")

# Store a memory
mem = client.memory.create("tenant-123", CreateMemoryRequest(
    content="Q4 revenue target is $2.5M",
    memory_type="semantic",
    importance=8,
    tags=["finance"],
))

# Search memories
results = client.memory.search("tenant-123", "revenue target", limit=5)

# Get assembled LLM context
ctx = client.memory.context("tenant-123", "What are our targets?")
print(ctx.context)
```

## Server Address

`base_url` is a required parameter — the SDK never embeds server addresses:

```python
client = EnterpriseClient(api_key="fme_your_key", base_url="https://fme.example.com:8201")
```

For deployments that need dynamic LAN/Tailscale routing, use `_network.detect_base_url()` and pass the result as `base_url`. The detection function requires caller-supplied host names — no defaults are baked in:

```python
from forgememory_enterprise._network import detect_base_url

url = detect_base_url(lan_host="your-lan-host", tailscale_host="your-ts-host")
client = EnterpriseClient(api_key="fme_your_key", base_url=url)
```

For the MCP server, set one of:
- `FME_BASE_URL=https://your-server:8201` (preferred)
- `FME_LAN_HOST=<ip>` + `FME_TAILSCALE_HOST=<hostname>` (auto-detection)

## Sub-Managers

| Manager | Access | Operations |
|---------|--------|------------|
| `client.orgs` | `OrgManager` | Create/list orgs, users, branches, provision tenants |
| `client.tenants` | `TenantManager` | List, suspend, reactivate, delete, set quota |
| `client.api_keys` | `ApiKeyManager` | Create, list, revoke API keys |
| `client.agents` | `AgentRegistry` | Register, update, delete agents; sessions, heartbeat |
| `client.audit` | `AuditLogger` | Log actions, memory access, delegations; costs |
| `client.memory` | `MemoryClient` | CRUD, search, context, facts (per-tenant) |
| `client.admin` | `AdminClient` | Health, dashboard, pool stats |
| `client.entities` | `EntityGraphClient` | Entity CRUD, edges, BFS graph traversal |
| `client.ingest` | `IngestClient` | Document, email, meeting, calendar ingestion |

All managers are lazily initialized on first access.

## Agent Sessions

```python
with client.session("agent-1", "tenant-1") as sess:
    # Background heartbeat runs automatically
    client.audit.log_action("agent-1", sess.id, "tool_call", "web_search")
    client.memory.create("tenant-1", CreateMemoryRequest(content="Found info"))
# Session auto-ended (status=completed, or failed on exception)
```

## Framework Adapters

### CrewAI

```python
from forgememory_enterprise.adapters.crewai_adapter import ForgeMemoryTool, FMECrewObserver

tool = ForgeMemoryTool(client, tenant_id="t-123")
result = tool.run("search:customer preferences")

observer = FMECrewObserver(client, "agent-1", session_id)
observer.on_tool_use("search", "query")
observer.on_llm_call(tokens_in=500, tokens_out=200, cost_usd=0.005)
```

### LangGraph

```python
from forgememory_enterprise.adapters.langgraph_adapter import (
    make_memory_retrieve_node, make_memory_store_node, make_memory_context_node
)

retrieve = make_memory_retrieve_node(client, "t-123")
store = make_memory_store_node(client, "t-123")
# Add to your graph as nodes
```

### AutoGen

```python
from forgememory_enterprise.adapters.autogen_adapter import fme_tool, inject_context

@fme_tool(client, tenant_id="t-123")
def search_memory(query: str) -> str:
    """Search organizational memory."""
    ...

context = inject_context(client, "t-123", "project status")
```

### OpenClaw

```python
from forgememory_enterprise.adapters.openclaw_adapter import FMEOpenClawPlugin

plugin = FMEOpenClawPlugin(client, tenant_id="t-123")
results = plugin.search("customer preferences")
plugin.store("New finding from browsing session")
```

## Error Handling

```python
from forgememory_enterprise import (
    AuthenticationError,   # 401 — invalid/expired key
    ForbiddenError,        # 403 — insufficient permissions
    NotFoundError,         # 404 — resource not found
    BudgetExceededError,   # 402 — agent budget exceeded
    RateLimitedError,      # 429 — too many requests
    LegalHoldError,        # 403 — GDPR legal hold blocks mutation
)
```

## Testing

```bash
cd sdk/python
pip install -e ".[dev]"
python -m pytest tests/ -v  # 367 tests, all using MockTransport
```

## Requirements

- Python 3.10+
- httpx >= 0.27.0
- pydantic >= 2.0
