Metadata-Version: 2.5
Name: syntarus
Version: 0.3.0
Summary: Project-scoped memory client for Syntarus
Project-URL: Documentation, https://www.syntarus.com/pages/developers
Project-URL: Homepage, https://www.syntarus.com
Project-URL: API Reference, https://www.syntarus.com/pages/api-reference
Project-URL: Security, https://www.syntarus.com/pages/security
Project-URL: Source, https://github.com/sujalkherawat25-stack/memoryos/tree/main/sdk
Project-URL: Issues, https://github.com/sujalkherawat25-stack/memoryos/issues
Author: Syntarus
License: MIT License
        
        Copyright (c) 2026 Syntarus
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: agents,ai,llm,memory
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: httpx<1,>=0.27
Provides-Extra: test
Requires-Dist: build<2,>=1.2; extra == 'test'
Requires-Dist: pytest-asyncio<1,>=0.24; extra == 'test'
Requires-Dist: pytest<9,>=8; extra == 'test'
Requires-Dist: twine<8,>=7; extra == 'test'
Description-Content-Type: text/markdown

# Syntarus Python SDK

The official Python client for the project-scoped Syntarus memory API.

## Install

```bash
pip install syntarus
```

## Continuum CLI

The package also installs the `syntarus` command for local development,
automation, and coding agents. It reads a project key only from
`SYNTARUS_API_KEY` (or a one-off `--api-key` flag); it never saves secrets to
the local profile.

```bash
export SYNTARUS_API_KEY="sk_mem_..."

syntarus doctor
syntarus memory add "The customer prefers vegetarian food." --user customer_123 --wait
syntarus memory search "food preference" --user customer_123
syntarus graph show --user customer_123 --json
syntarus event get evt_... --json
```

Use `syntarus config set-endpoint https://...` only for a self-hosted or test
endpoint. `syntarus --help` lists every command. Add `--json` to receive a
stable `{ "ok", "data" }` response suitable for agents and CI.

Python 3.10 or newer is required. Keep project API keys in a server-side
secret manager; never ship them in browser or mobile applications.

## Add and search memory

```python
from syntarus import MemoryClient

with MemoryClient(api_key="sk_mem_...") as memory:
    accepted = memory.add(
        user_id="customer_123",
        agent_id="support_agent",
        run_id="ticket_456",
        # Anchor relative dates such as "next Friday" to the source event.
        event_time="2023-05-07T12:00:00Z",
        messages=[
            {"role": "user", "content": "I prefer vegetarian food."},
            {"role": "assistant", "content": "I will remember that."},
        ],
        metadata={"channel": "voice"},
        idempotency_key="call-456-final",
    )
    memory.wait_for_event(accepted["event_id"])
    result = memory.search(
        "What food does the customer prefer?",
        user_id="customer_123",
        agent_id="support_agent",
    )
    print(result["context"])
```

`agent_id` creates an isolated memory namespace. Omit it for a user profile
shared by every agent in the project. `run_id` groups the conversation history
used during ingestion. `metadata` is event metadata and is returned by event
status and webhook payloads; it is not currently a memory-search filter.
`event_time` is optional, but use it for replayed or delayed conversations so
relative dates are resolved against when the interaction occurred rather than
when Syntarus processes it. It accepts an ISO-8601 string or a Python
`datetime`.

## Bounded bulk import

Bulk imports are source-identified and run on a lower-priority queue. Estimate
first, then explicitly start the manifest; the same `(source_id,
source_version)` cannot be accepted twice in a project.

```python
records = [{
    "source_id": "ticket-123",
    "source_version": "2026-09-09",
    "user_id": "customer_123",
    "messages": [{"role": "user", "content": "I prefer email."}],
}]
estimate = memory.bulk_estimate(records)
manifest = memory.bulk_start(records)
memory.bulk_pause(manifest["manifest"]["id"])
memory.bulk_resume(manifest["manifest"]["id"])
status = memory.bulk_status(manifest["manifest"]["id"])
errors = memory.bulk_errors(manifest["manifest"]["id"])
```

Each record keeps its original turn order and event timestamp. Failed records
are exported separately; cancelling a manifest does not erase its audit-safe
status.

## Async client

```python
from syntarus import AsyncMemoryClient

async with AsyncMemoryClient(api_key="sk_mem_...") as memory:
    accepted = await memory.add(
        user_id="customer_123",
        messages=[{"role": "user", "content": "Call me after 5 PM."}],
    )
    await memory.wait_for_event(accepted["event_id"])
```

## Production transport behavior

Clients reuse an HTTP connection pool, send a correlation header on every
request, and retry up to two times by default for temporary network errors and
retryable HTTP responses. Reads are safe to replay. Memory writes and deletion
jobs are also safe to retry because the SDK always sends an idempotency key.
Other state-changing calls are deliberately not retried automatically.

Tune this per client, or make a short-lived override for a special operation:

```python
from syntarus import MemoryClient, APIStatusError, RateLimitError

with MemoryClient("sk_mem_...", timeout=30.0, max_retries=3) as memory:
    try:
        result = memory.search("current preference", user_id="customer_123")
    except RateLimitError as error:
        # Respect an API-supplied delay when present.
        print(error.retry_after, error.request_id)
    except APIStatusError as error:
        print(error.status_code, error.request_id)
    # The new client must be closed if it is used.
    with memory.with_options(timeout=5.0, max_retries=0) as fast_fail:
        fast_fail.search("health probe", user_id="customer_123")
```

`APIStatusError` exposes `status_code`, `request_id`, and a parsed response
body. It never contains your API key. The SDK does not retry non-idempotent
state transitions such as webhook creation or bulk pause/resume/cancel.

For a large import, wait on the manifest rather than writing a polling loop:

```python
manifest = memory.bulk_start(records)
result = memory.wait_for_manifest(manifest["manifest"]["id"], timeout=3600)
```

## Lifecycle operations

```python
memory.export(user_id="customer_123", agent_id="support_agent")
memory.delete("memory-uuid")
memory.delete_user(user_id="customer_123", agent_id="support_agent")
```

Deleting a user without `agent_id` deletes only the shared user namespace.
Delete each agent namespace separately when an application uses agent-scoped
memory.

## Enterprise isolation and governance

Use a project key with `tokens:write` to mint a short-lived credential for one
end user and, optionally, one agent. Subject tokens can only read or write
their bound namespace; they cannot export, delete, manage keys, or read audit
logs.

```python
issued = memory.create_subject_token(
    user_id="customer_123",
    agent_id="support_agent",
    scopes=["memories:read", "memories:write"],
    ttl_seconds=900,
)

with MemoryClient(api_key=issued["token"]) as delegated:
    delegated.search("What does this customer prefer?", user_id="customer_123")
```

Verified deletion is a durable cross-store job. Poll it with the normal event
method to receive the per-store completion receipt:

```python
deletion = memory.request_user_deletion(
    user_id="customer_123",
    agent_id="support_agent",
    idempotency_key="erase-customer-123-support",
)
receipt = memory.wait_for_event(deletion["event_id"])
print(receipt["result"]["stores"])

audit = memory.audit_events(user_id="customer_123", limit=50)
```

The project owner must enable delegated tokens in the developer console first.
Audit records intentionally exclude memory text and secret values.

## Webhooks

```python
created = memory.create_webhook("https://example.com/syntarus/events")
signing_secret = created["signing_secret"]  # returned once
memory.list_webhooks()
memory.webhook_deliveries(webhook_id=created["webhook"]["id"])
memory.delete_webhook(created["webhook"]["id"])
```

Deliveries include `X-Syntarus-Timestamp`, `X-Syntarus-Delivery`, and
`X-Syntarus-Signature-256`. Verify the signature as HMAC-SHA256 over
`<timestamp>.<raw_request_body>` and reject timestamps outside a five-minute
window. A non-2xx response is retried durably and eventually becomes a
dead-letter delivery visible through `webhook_deliveries`.

## Errors

The SDK raises typed exceptions derived from `SyntarusError`:

- `AuthenticationError`
- `PermissionDenied`
- `RateLimitError` (`retry_after` is available when the API sends it)
- `APIConnectionError`
- `APITimeoutError`
- `EventFailedError` (`event` contains the terminal event record)

## Syntarus resources

- [Syntarus website](https://www.syntarus.com)
- [Developer portal](https://www.syntarus.com/pages/developers)
- [API reference](https://www.syntarus.com/pages/api-reference)
- [Security and reliability](https://www.syntarus.com/pages/security)
- [Source code](https://github.com/sujalkherawat25-stack/memoryos/tree/main/sdk)
- [Report an issue](https://github.com/sujalkherawat25-stack/memoryos/issues)
