Metadata-Version: 2.4
Name: mirasoth-agentspace
Version: 0.1.0
Summary: Python SDK and CLI for the Mirasoth AgentSpace API - isolated cloud workspaces for agent execution
Author: Mirasoth Inc.
License: Dual-licensed: AGPL-3.0-or-later or Mirasoth Commercial License
Project-URL: Homepage, https://github.com/mirasoth/agentspace
Keywords: agentspace,mirasoth,agent,workspace,sdk,cli
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"

# mirasoth-agentspace (Python)

Python SDK and CLI for the [Mirasoth AgentSpace](../README.md) API —
isolated cloud workspaces for agent execution.

- **Package**: `mirasoth-agentspace` (pip name) · imported as `agentspace`
- **CLI**: installs an `agentspace` console script, command-compatible with
  the Go CLI (`cmd/agentspace`)
- **Zero runtime dependencies** — pure stdlib (`urllib`), Python 3.9+

## Install

```sh
pip install -e python/          # from the repo

# or, once published
pip install mirasoth-agentspace
```

## SDK quickstart

```python
from agentspace import AgentSpace, ImageAttachment, TurnHints

api = AgentSpace("http://127.0.0.1:8620", "asp_...")

# workspace + files
ws = api.create_workspace("demo")
api.upload_file(ws.id, "docs/brief.md", b"# project brief")
entries = api.list_files(ws.id, recursive=True).entries

# streaming agent turn (SSE)
ses = api.create_session(ws.id, "main")
reply = api.run_turn(
    ws.id, ses.id,
    "Read docs/brief.md and write output/summary.md with a summary.",
    on_event=lambda ev: print(ev.data, end="") if ev.type == "delta" else None,
)

# one-shot background task (fresh agent session)
task = api.run_task(ws.id, "Append an 'Appendix' section to output/summary.md.")
print(task.status, task.result)

# scoped handles: api.workspace(ws.id).list_files(...)
ws_handle = api.workspace(ws.id)
result = ws_handle.search_memory("project goals")
```

### Error handling

```python
from agentspace import (
    AgentSpaceError, APIError, NotFoundError, ConflictError,
    RateLimitError, TurnError, TransportError,
)

try:
    api.run_turn(ws.id, ses.id, "...")
except TurnError as e:        # terminal SSE `error` event
    print(e.user_message, e.error_code)
except ConflictError:         # a turn is already in flight (409)
    ...
except RateLimitError:        # service-wide concurrent turn limit (429)
    ...
```

HTTP errors map to typed subclasses (`BadRequestError`, `NotFoundError`,
`ConflictError`, `RateLimitError`, `ServerError`, ...); every
`APIError` carries `.status`, `.message` and the decoded `.payload`
(`{code, message}`). `TransportError` covers connection failures.

### Streaming events

`iter_session_events` / `iter_task_events` yield `StreamEvent(type, data)`
tuples — `status`, `delta`, `thinking_step`, then a terminal
`complete` / `error` (plus raw agent protocol `event` frames on task
streams). The server replays the last completed reply to the first late
subscriber, so prompt-then-attach never misses the answer.

### Custom transport / testing

```python
from agentspace import AgentSpace, UrllibTransport, HTTPResponse

class MyTransport(UrllibTransport):
    def request(self, method, url, headers, body, timeout):
        ...  # proxy, logging, retry policy...
        return HTTPResponse(200, {}, b"{}")

api = AgentSpace(base_url, api_key, transport=MyTransport())
```

## CLI

Command-compatible with the Go CLI — same output formats, same config
file (`~/.agentspace/config.json`), same env vars (`AGENTSPACE_URL`,
`AGENTSPACE_API_KEY`). Credentials resolve as: **flags > env > config**.

```sh
agentspace config set http://127.0.0.1:8620 asp_...
agentspace whoami

agentspace workspaces create demo        # alias: ws
agentspace ws ls --json                   # machine-readable output
agentspace ws rename <id> new-name
agentspace ws rm <id>                     # asks for confirmation (--yes to skip)

agentspace files ls -w <ws> [path]        # alias: f
agentspace files find -w <ws> [path]     # recursive
agentspace files upload local.txt docs/notes.txt -w <ws>
agentspace files download docs/notes.txt ./out -w <ws>
agentspace files mv docs/a.txt docs/b.txt -w <ws>
agentspace files mkdir newdir -w <ws>
agentspace files rm -r olddir -w <ws>     # -r asks for confirmation

agentspace sessions create main -w <ws>   # alias: ses
agentspace sessions ls -w <ws>
agentspace sessions log <ses> -w <ws>     # persisted transcript
agentspace sessions reset <ses> -w <ws>   # fresh agent context, files kept
agentspace sessions cancel <ses> -w <ws>

agentspace send "summarize docs/notes.txt" -w <ws> -s <ses>   # prompt + stream
agentspace attach -w <ws> -s <ses>                            # live stream only

agentspace tasks create "clean up temp files" -w <ws>  # alias: task/t
agentspace tasks get <task> -w <ws>                    # status + result
agentspace tasks attach <task> -w <ws>                # live task events

agentspace memory search "deploy notes" -w <ws> -n 5  # pgvector semantic search
agentspace apikeys create ci                          # alias: keys
agentspace apikeys ls
agentspace apikeys rm <key-id>
```

Global flags (usable anywhere): `--url`, `--api-key`, `--timeout`,
`--json`, `-v/--verbose` (status + raw agent events on stderr),
`-y/--yes` (skip destructive confirmations). In non-interactive shells,
destructive commands (`ws rm`, `files rm -r`) refuse to run unless
`--yes` is passed.

Exit codes: `0` success · `1` API/stream error · `2` usage / missing
credentials / declined action.

## Layout & development

```
python/
  agentspace/     # the SDK package (import name: agentspace)
    client.py     # AgentSpace client: REST + SSE + handles
    models.py     # typed dataclass wire models
    errors.py     # exception hierarchy
    sse.py        # SSE parsing (server Go-quotes data fields)
    cli.py        # the `agentspace` CLI
    _config.py    # CLI credentials (shared with the Go CLI)
  tests/          # pytest suite; no network needed (scripted fake transport)
```

```sh
cd python
python -m pytest            # 76 tests
pip install -e .[dev]       # editable install with dev extras
```

End-to-end example against a live stack: `examples/python/walkthrough.py`
in the repo root (drives this SDK; also doubles as a smoke test).
