Metadata-Version: 2.4
Name: axisdream
Version: 0.6.3
Summary: Official Axisdream SDK — add a knowledge layer to any AI agent
Project-URL: Homepage, https://axisdream.ai
Project-URL: Documentation, https://docs.axisdream.ai
Project-URL: Repository, https://github.com/Jack-Pision/axisdream
Project-URL: Issues, https://github.com/Jack-Pision/axisdream/issues
Author-email: Axisdream <sdk@axisdream.ai>
License: MIT
Keywords: agents,ai,knowledge,memory,rag,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT 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 :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# axisdream

Official Python SDK for [Axisdream](https://axisdream.ai) — thin client for the Axisdream knowledge platform.

Published on PyPI as **`axisdream`**.

## Install

```bash
pip install axisdream
```

## Quickstart

```python
import asyncio
import os
from axisdream import AsyncAxisdream

# Set these once in your environment, or pass them to AsyncAxisdream directly.
os.environ["AXISDREAM_API_KEY"] = "cs-YOUR_KEY"
os.environ["AXISDREAM_BASE_URL"] = "https://your-axisdream-api.example"

async def main():
    cog = AsyncAxisdream()
    space = await cog.space("my-agent")

    # See what exists
    files = await space.list("expertise")
    print(f"Files: {files.file_count}")

    # Add knowledge
    await space.add(
        path="expertise/retry.md",
        content="# Retry Patterns\nUse exponential backoff with jitter.",
        bucket="expertise",
        topic="retry-patterns",
        confidence=0.95,
    )

    # Search (vectors + BM25 + knowledge graph, per-source limits)
    results = await space.retrieve(
        "retry logic",
        vector_limit=10,  # max vector results
        bm25_limit=10,    # max keyword results
        kg_limit=5,       # max graph neighbors per result
    )
    for item in results.results:
        print(f"{item.file_path}: {item.score:.2f} ({item.source})")

    # Retrieve a file
    file = await space.fetch("expertise/retry.md")
    print(file.content)

    # Delete
    await space.forget("expertise/retry.md")

    await cog.aclose()

asyncio.run(main())
```

## Sync client

```python
from axisdream import Axisdream

with Axisdream() as cog:
    space = cog.space("my-agent")
    files = space.list("expertise")
    results = space.retrieve("retry logic", vector_limit=10, bm25_limit=10)
    space.add(
        path="expertise/retry.md",
        content="# Retry Patterns\n...",
        bucket="expertise",
        topic="retry-patterns",
    )
    space.forget("expertise/retry.md")
```

## API Reference

### `Axisdream(api_key, base_url, timeout, max_retries)`

Reads `AXISDREAM_API_KEY` from environment if `api_key` is not provided.
Reads `AXISDREAM_BASE_URL` if `base_url` is not provided, then falls back to
`http://localhost:8000` for local development.

| Method | Description |
|---|---|
| `cog.space(name_or_id)` | Get a space client by name or ID |
| `cog.list_spaces()` | List all your spaces |

### `SpaceClient`

| Method | Args | Description |
|---|---|---|
| `space.list(folder)` | `folder=""` | List files in folder |
| `space.fetch(path)` | `path` | Get one file with content + metadata |
| `space.retrieve(query, ...)` | see below | Unified search: vectors + BM25 + KG |
| `space.add(path, content, bucket, topic, confidence, file_type, status, related, relates_to)` | see below | Add/update knowledge |
| `space.forget(path)` | `path` | Delete from all layers |
| `space.get_tools()` | — | Fetch the Platform's live MCP-compatible tool schemas |

#### `add()` parameters

| Param | Type | Required | Description |
|---|---|---|---|
| `path` | str | yes | File path (e.g. "expertise/retry.md") |
| `content` | str | yes | Markdown content |
| `bucket` | str | yes | "expertise", "memory", "skills", or "root" |
| `topic` | str | yes | Category/topic |
| `confidence` | float | no | 0.0-1.0, default 0.9 |
| `file_type` | str | no | Explicit file type override |
| `status` | str | no | Metadata status, default `active` |
| `related` | list[str] | no | Canonical related file paths |
| `relates_to` | list[str] | no | Backward-compatible alias for `related` |

## Buckets

| Bucket | Use for |
|---|---|
| `expertise` | Knowledge, patterns, guides, reference material |
| `memory` | Agent memory, user preferences, session notes |
| `skills` | Reusable procedures, workflows, and operator playbooks |
| `root` | Shared top-level files such as `root/purpose.md` and `root/memory.md` |

## Search limits

`retrieve()` parameters (enforced at backend):

| Param | Type | Default | Range | Description |
|---|---|---|---|---|
| `vector_limit` | int | 100 | 0–100 | Max vector results. 0 = skip vectors. |
| `bm25_limit` | int | 100 | 0–100 | Max BM25 keyword results. 0 = skip BM25. |
| `kg_limit` | int | 100 | 0–100 | Max graph neighbors per result. 0 = skip KG. |
| `bucket` | str | None | "expertise"/"memory"/"skills"/"root" | Filter by bucket. |
| `folder_path` | str | None | — | Restrict to folder. |

**Examples:**
```python
# Pure vector search (skip BM25)
results = await space.retrieve("query", bm25_limit=0)

# Pure keyword search (skip vectors)
results = await space.retrieve("query", vector_limit=0)

# Skip graph enrichment
results = await space.retrieve("query", kg_limit=0)

# Fine-grained control
results = await space.retrieve("query", vector_limit=5, bm25_limit=3, kg_limit=1)
```

## Errors

```python
from axisdream.exceptions import AuthError, NotFoundError, RateLimitError

try:
    results = await space.retrieve("query")
except AuthError:
    print("Invalid API key")
except NotFoundError:
    print("Space not found")
except RateLimitError:
    print("Rate limited, retry later")
```

## Local-first note

The Python SDK uses the configured hosted URL when available:

- Base URL precedence: `base_url`, then `AXISDREAM_BASE_URL`, then `http://localhost:8000`
- Space lookup accepts either a space name or a space ID
