Metadata-Version: 2.4
Name: velmhq
Version: 0.1.0
Summary: Python SDK for the Velm API.
Project-URL: Homepage, https://velm.run
Project-URL: Documentation, https://velm.run/docs
Project-URL: Repository, https://github.com/velmhq/sdk-python
Project-URL: Issues, https://github.com/velmhq/community/issues
Author: Velm
License: MIT
License-File: LICENSE
Keywords: agents,ai,feedback,improvements,sdk,velm
Classifier: Development Status :: 3 - Alpha
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: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.9.0
Provides-Extra: dev
Requires-Dist: mypy>=1.13.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: respx>=0.21.0; extra == 'dev'
Requires-Dist: ruff>=0.7.0; extra == 'dev'
Description-Content-Type: text/markdown

# velmhq

Python SDK for the [Velm](https://velm.run) API.

> **Status: pre-release.** The public surface is stable in shape but
> the underlying API is still evolving. Pin a version until the
> 1.0.0 release.

## Install

```bash
pip install velmhq
# or
uv add velmhq
```

The PyPI distribution name is `velmhq` because the bare `velm` is
already published by an unrelated project.

## Usage

```python
from velmhq import Velm

velm = Velm(api_key="vk_test_...")

# Invoke an agent and wait for the result.
run = velm.run("support-bot", {"question": "How do I reset my password?"})
print(run.text)

# Capture a thumbs-down to feed the improvement loop.
velm.feedback.capture(
    run_id=run.id,
    feedback_key=run.id,
    event_type="thumbs_down",
    conversation_text=transcript,
    original_response=bad_response,
    metadata={"surface": "sdk"},
)
```

The async client mirrors the sync surface:

```python
import asyncio
from velmhq import AsyncVelm

async def main() -> None:
    async with AsyncVelm(api_key="vk_test_...") as velm:
        run = await velm.run("support-bot", {"question": "..."})
        print(run.text)

asyncio.run(main())
```

## Multi-turn conversations

Pass the same `conversation_id` across runs and the agent replays the
prior turns, so it has the full context. The id is caller-minted -
any stable string. Omit it for a one-shot run.

```python
import uuid

conversation_id = str(uuid.uuid4())

turn1 = velm.runs.create("support-bot",
    input={"message": "I was double-charged last month."},
    conversation_id=conversation_id)

turn2 = velm.runs.create("support-bot",
    input={"message": "and what about this month?"},
    conversation_id=conversation_id)

# Inspect every run in the conversation.
for run in velm.runs.list(conversation_id=conversation_id):
    print(run.id, run.status, run.created_at)
```

## Errors

The SDK raises typed exceptions on non-2xx responses. Branch on the
class, not the message string.

```python
from velmhq import (
    AuthenticationError,
    BillingError,
    RateLimitError,
    VelmError,
)

try:
    velm.feedback.capture(...)
except RateLimitError as err:
    print(f"rate limited; retry after {err.retry_after_ms}ms")
except BillingError as err:
    print(err.message)  # points at the billing settings page
except AuthenticationError:
    print("invalid API key")
except VelmError as err:
    print(f"{err.code}: {err.message}")
```

## Testing

`velmhq.testing.MockVelm` is a scriptable fake for unit tests in
your own code. It runs the real SDK code path under a fake transport,
so retries, idempotency keys, and error mapping all behave as in
production.

```python
from velmhq.testing import MockVelm

def test_my_handler() -> None:
    velm = MockVelm()
    velm.respond_next({"feedbackId": "fb_1"})

    my_handler(velm)

    assert len(velm.calls) == 1
    assert velm.calls[0].url.endswith("/feedback")
```

## Runtime support

Works on CPython 3.10 through 3.13. Uses `httpx` for HTTP and
`pydantic` v2 for typed models. Both sync (`Velm`) and async
(`AsyncVelm`) clients are provided; pick whichever fits your
application's runtime.

## Documentation

Full reference at [velm.run/docs](https://velm.run/docs).

## License

MIT. See [LICENSE](./LICENSE).
