Python SDK for the Velm 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.
pip install velmhq
# or
uv add velmhqThe PyPI distribution name is velmhq because the bare velm is
already published by an unrelated project.
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:
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())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.
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)The SDK raises typed exceptions on non-2xx responses. Branch on the class, not the message string.
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}")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.
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")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.
Full reference at velm.run/docs.
MIT. See LICENSE.