avartha-python-sdk 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- avartha_python_sdk-0.0.1/.github/CODEOWNERS +5 -0
- avartha_python_sdk-0.0.1/.github/workflows/ci.yml +37 -0
- avartha_python_sdk-0.0.1/.github/workflows/publish.yml +66 -0
- avartha_python_sdk-0.0.1/.gitignore +11 -0
- avartha_python_sdk-0.0.1/AGENTS.md +16 -0
- avartha_python_sdk-0.0.1/CONTRIBUTING.md +14 -0
- avartha_python_sdk-0.0.1/LICENSE +23 -0
- avartha_python_sdk-0.0.1/MANIFEST.in +8 -0
- avartha_python_sdk-0.0.1/Makefile +17 -0
- avartha_python_sdk-0.0.1/PKG-INFO +417 -0
- avartha_python_sdk-0.0.1/README.md +382 -0
- avartha_python_sdk-0.0.1/docs/audit/category-c-validation.md +71 -0
- avartha_python_sdk-0.0.1/docs/audit/findings.csv +59 -0
- avartha_python_sdk-0.0.1/docs/audit/findings.json +1246 -0
- avartha_python_sdk-0.0.1/docs/audit/fuzz-coverage.csv +6751 -0
- avartha_python_sdk-0.0.1/docs/audit/http-coverage.csv +22 -0
- avartha_python_sdk-0.0.1/docs/audit/http-results.json +350 -0
- avartha_python_sdk-0.0.1/docs/audit/invariants.json +322 -0
- avartha_python_sdk-0.0.1/docs/audit/inventory.csv +350 -0
- avartha_python_sdk-0.0.1/docs/audit/inventory.json +3152 -0
- avartha_python_sdk-0.0.1/docs/audit/live-coverage.csv +220 -0
- avartha_python_sdk-0.0.1/docs/audit/live-results.json +36886 -0
- avartha_python_sdk-0.0.1/docs/audit/report.md +310 -0
- avartha_python_sdk-0.0.1/docs/audit/source-fuzz-results.json +6917 -0
- avartha_python_sdk-0.0.1/docs/audit/source-manifest.json +387 -0
- avartha_python_sdk-0.0.1/docs/audit/state-fuzz-results.json +80072 -0
- avartha_python_sdk-0.0.1/docs/audit/summary.json +19 -0
- avartha_python_sdk-0.0.1/docs/audit/surface-matrix.csv +38 -0
- avartha_python_sdk-0.0.1/docs/audit/wire-schema-results.json +56 -0
- avartha_python_sdk-0.0.1/docs/compatibility.md +112 -0
- avartha_python_sdk-0.0.1/docs/github-policies.md +26 -0
- avartha_python_sdk-0.0.1/docs/migration.md +192 -0
- avartha_python_sdk-0.0.1/docs/platform.md +78 -0
- avartha_python_sdk-0.0.1/docs/preview-results.json +123 -0
- avartha_python_sdk-0.0.1/docs/preview-testing.md +177 -0
- avartha_python_sdk-0.0.1/examples/agents.py +66 -0
- avartha_python_sdk-0.0.1/examples/chat.py +28 -0
- avartha_python_sdk-0.0.1/examples/conversation.py +51 -0
- avartha_python_sdk-0.0.1/examples/endpoints.py +39 -0
- avartha_python_sdk-0.0.1/examples/realtime.py +36 -0
- avartha_python_sdk-0.0.1/examples/realtime_asr.py +61 -0
- avartha_python_sdk-0.0.1/examples/tts.py +39 -0
- avartha_python_sdk-0.0.1/pyproject.toml +73 -0
- avartha_python_sdk-0.0.1/scripts/audit/catalog.py +227 -0
- avartha_python_sdk-0.0.1/scripts/audit/fetch_sources.py +47 -0
- avartha_python_sdk-0.0.1/scripts/audit/http_probe.py +102 -0
- avartha_python_sdk-0.0.1/scripts/audit/invariants.py +121 -0
- avartha_python_sdk-0.0.1/scripts/audit/probe.py +1667 -0
- avartha_python_sdk-0.0.1/scripts/audit/report.py +312 -0
- avartha_python_sdk-0.0.1/scripts/audit/source_fuzz.py +391 -0
- avartha_python_sdk-0.0.1/scripts/audit/state_fuzz.py +39 -0
- avartha_python_sdk-0.0.1/scripts/audit/state_model.py +266 -0
- avartha_python_sdk-0.0.1/scripts/preview_smoke.py +372 -0
- avartha_python_sdk-0.0.1/setup.cfg +4 -0
- avartha_python_sdk-0.0.1/setup.py +33 -0
- avartha_python_sdk-0.0.1/src/avartha/__init__.py +42 -0
- avartha_python_sdk-0.0.1/src/avartha/_config.py +140 -0
- avartha_python_sdk-0.0.1/src/avartha/_realtime_tts.py +138 -0
- avartha_python_sdk-0.0.1/src/avartha/_version.py +24 -0
- avartha_python_sdk-0.0.1/src/avartha/client.py +159 -0
- avartha_python_sdk-0.0.1/src/avartha/control.py +441 -0
- avartha_python_sdk-0.0.1/src/avartha/conversational_ai/__init__.py +19 -0
- avartha_python_sdk-0.0.1/src/avartha/conversational_ai/conversation.py +19 -0
- avartha_python_sdk-0.0.1/src/avartha/conversational_ai/default_audio_interface.py +5 -0
- avartha_python_sdk-0.0.1/src/avartha/elevenlabs.py +120 -0
- avartha_python_sdk-0.0.1/src/avartha/errors.py +35 -0
- avartha_python_sdk-0.0.1/src/avartha/openai.py +106 -0
- avartha_python_sdk-0.0.1/src/avartha/py.typed +0 -0
- avartha_python_sdk-0.0.1/src/avartha_python_sdk.egg-info/PKG-INFO +417 -0
- avartha_python_sdk-0.0.1/src/avartha_python_sdk.egg-info/SOURCES.txt +78 -0
- avartha_python_sdk-0.0.1/src/avartha_python_sdk.egg-info/dependency_links.txt +1 -0
- avartha_python_sdk-0.0.1/src/avartha_python_sdk.egg-info/requires.txt +16 -0
- avartha_python_sdk-0.0.1/src/avartha_python_sdk.egg-info/top_level.txt +1 -0
- avartha_python_sdk-0.0.1/tests/conftest.py +10 -0
- avartha_python_sdk-0.0.1/tests/test_clients.py +325 -0
- avartha_python_sdk-0.0.1/tests/test_control.py +243 -0
- avartha_python_sdk-0.0.1/tests/test_fence.py +118 -0
- avartha_python_sdk-0.0.1/tests/test_platform_e2e.py +155 -0
- avartha_python_sdk-0.0.1/tests/test_websocket_urls.py +152 -0
- avartha_python_sdk-0.0.1/tests/test_websockets.py +364 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
merge_group:
|
|
8
|
+
types: [checks_requested]
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ci-${{ github.ref }}
|
|
15
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
check:
|
|
19
|
+
name: Python ${{ matrix.python }}
|
|
20
|
+
runs-on: ubuntu-24.04
|
|
21
|
+
timeout-minutes: 20
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
python: ['3.12', '3.13', '3.14']
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
28
|
+
with:
|
|
29
|
+
fetch-depth: 0 # setuptools_scm derives the version from git tags
|
|
30
|
+
fetch-tags: true
|
|
31
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: ${{ matrix.python }}
|
|
34
|
+
cache: pip
|
|
35
|
+
cache-dependency-path: pyproject.toml
|
|
36
|
+
- run: python -m pip install -e '.[dev]'
|
|
37
|
+
- run: make check
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Publish Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
IS_NIGHTLY_BUILD: "false"
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
name: Build distribution
|
|
17
|
+
runs-on: ubuntu-24.04
|
|
18
|
+
timeout-minutes: 20
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
21
|
+
with:
|
|
22
|
+
# setuptools_scm needs the full history and the tags to derive a version.
|
|
23
|
+
fetch-depth: 0
|
|
24
|
+
fetch-tags: true
|
|
25
|
+
ref: ${{ github.event.release.tag_name || github.ref }}
|
|
26
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
27
|
+
with:
|
|
28
|
+
python-version: '3.12'
|
|
29
|
+
cache: pip
|
|
30
|
+
cache-dependency-path: pyproject.toml
|
|
31
|
+
- run: python -m pip install --upgrade pip build twine
|
|
32
|
+
- name: Verify version from tag
|
|
33
|
+
# Refuse to build off an untagged commit: setuptools_scm would guess the
|
|
34
|
+
# next version and we would publish a release nobody tagged.
|
|
35
|
+
run: |
|
|
36
|
+
git describe --exact-match --tags HEAD
|
|
37
|
+
python -c "from setuptools_scm import get_version; print('scm version:', get_version())"
|
|
38
|
+
- run: python -m build
|
|
39
|
+
- name: Check distribution
|
|
40
|
+
run: |
|
|
41
|
+
twine check dist/*
|
|
42
|
+
ls -la dist/
|
|
43
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
44
|
+
with:
|
|
45
|
+
name: python-package-distributions
|
|
46
|
+
path: dist/
|
|
47
|
+
|
|
48
|
+
publish:
|
|
49
|
+
name: Publish to PyPI
|
|
50
|
+
needs: build
|
|
51
|
+
runs-on: ubuntu-24.04
|
|
52
|
+
timeout-minutes: 20
|
|
53
|
+
environment:
|
|
54
|
+
name: pypi
|
|
55
|
+
url: https://pypi.org/p/avartha-python-sdk
|
|
56
|
+
permissions:
|
|
57
|
+
# Required for Trusted Publishing; no API token is stored in this repo.
|
|
58
|
+
id-token: write
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
61
|
+
with:
|
|
62
|
+
name: python-package-distributions
|
|
63
|
+
path: dist/
|
|
64
|
+
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
65
|
+
with:
|
|
66
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Avartha Python SDK
|
|
2
|
+
|
|
3
|
+
Use Python 3.12+, a src layout, typed public APIs, and the Makefile targets.
|
|
4
|
+
Preserve the Avartha proprietary LICENSE notice inherited from Vidhi.
|
|
5
|
+
Run `git status --short` before edits. Keep changes scoped.
|
|
6
|
+
|
|
7
|
+
Preserve upstream OpenAI and ElevenLabs method signatures, event types, wire
|
|
8
|
+
payloads, and exception classes. Prefer the official dependencies to recreating
|
|
9
|
+
vendor protocols. Cover adapters with HTTP contract tests and real local
|
|
10
|
+
WebSocket tests. Never silently route an Avartha key to a vendor hostname.
|
|
11
|
+
|
|
12
|
+
Only expose platform endpoints verified against avartha/platform. Document
|
|
13
|
+
server prerequisites separately from SDK support. Keep private SDK attribute
|
|
14
|
+
access isolated and pin the dependency range it was tested against.
|
|
15
|
+
|
|
16
|
+
Run `make check` before finishing. Do not add bot attribution to commits or docs.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Use Python 3.12+ and run `make install-dev` in a virtual environment.
|
|
4
|
+
`make format` applies formatting; `make check` runs lint, type checking, tests,
|
|
5
|
+
and wheel/source builds. Read AGENTS.md for compatibility rules.
|
|
6
|
+
|
|
7
|
+
Protocol behavior should come from the official client dependencies. When an
|
|
8
|
+
adapter needs a private upstream attribute, isolate it, constrain the dependency
|
|
9
|
+
version, and add a local WebSocket regression test. Update the compatibility
|
|
10
|
+
matrix when platform support changes; client availability is not server support.
|
|
11
|
+
|
|
12
|
+
Release steps: update both pyproject.toml and avartha.__version__, run `make check`,
|
|
13
|
+
review the wheel/sdist, tag the reviewed version, then publish through the
|
|
14
|
+
organization's approved package publication process. No publication is automatic.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright (c) 2026 Avartha Inc. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
This software and its associated documentation (the "Software") are the
|
|
4
|
+
proprietary and confidential property of Avartha Inc.
|
|
5
|
+
|
|
6
|
+
No license or other right to use, copy, modify, distribute, sublicense,
|
|
7
|
+
publish, display, perform, transmit, or create derivative works of the
|
|
8
|
+
Software is granted except under a separate written agreement with
|
|
9
|
+
Avartha Inc. Any use of the Software without such authorization is strictly
|
|
10
|
+
prohibited.
|
|
11
|
+
|
|
12
|
+
THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
13
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
14
|
+
FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
15
|
+
AVARTHA INC. BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING
|
|
16
|
+
FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR ITS USE.
|
|
17
|
+
|
|
18
|
+
Third-Party Software
|
|
19
|
+
|
|
20
|
+
The Software may include or interact with third-party components. Those
|
|
21
|
+
components remain subject to their respective license terms and notices.
|
|
22
|
+
Nothing in this license limits or supersedes rights granted by third-party
|
|
23
|
+
licenses or claims ownership of third-party copyrights.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
include LICENSE README.md CONTRIBUTING.md Makefile AGENTS.md
|
|
2
|
+
recursive-include docs *.md *.json *.csv
|
|
3
|
+
recursive-include examples *.py
|
|
4
|
+
recursive-include tests *.py
|
|
5
|
+
include .github/workflows/ci.yml
|
|
6
|
+
include .github/workflows/publish.yml
|
|
7
|
+
include setup.py
|
|
8
|
+
recursive-include scripts *.py
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
PYTHON ?= python
|
|
2
|
+
BUILD_FLAGS ?=
|
|
3
|
+
.PHONY: install-dev lint format test build check
|
|
4
|
+
install-dev:
|
|
5
|
+
$(PYTHON) -m pip install -e '.[dev]'
|
|
6
|
+
lint:
|
|
7
|
+
$(PYTHON) -m ruff check .
|
|
8
|
+
$(PYTHON) -m ruff format --check .
|
|
9
|
+
$(PYTHON) -m mypy
|
|
10
|
+
format:
|
|
11
|
+
$(PYTHON) -m ruff check --fix .
|
|
12
|
+
$(PYTHON) -m ruff format .
|
|
13
|
+
test:
|
|
14
|
+
$(PYTHON) -m pytest
|
|
15
|
+
build:
|
|
16
|
+
$(PYTHON) -m build $(BUILD_FLAGS)
|
|
17
|
+
check: lint test build
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: avartha-python-sdk
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Python clients for Avartha inference, voice agents, and platform management
|
|
5
|
+
Author-email: "Avartha Inc." <team@avartha.ai>
|
|
6
|
+
License-Expression: LicenseRef-Avartha-Proprietary
|
|
7
|
+
Project-URL: Repository, https://github.com/avartha/avartha-python-sdk
|
|
8
|
+
Project-URL: Issues, https://github.com/avartha/avartha-python-sdk/issues
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Typing :: Typed
|
|
17
|
+
Requires-Python: >=3.12
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: openai[realtime]<4,>=3.13.0
|
|
21
|
+
Requires-Dist: elevenlabs<2.69,>=2.68.0
|
|
22
|
+
Requires-Dist: httpx<0.29,>=0.28.1
|
|
23
|
+
Requires-Dist: websockets<16,>=15.0.1
|
|
24
|
+
Requires-Dist: pydantic<3,>=2.11
|
|
25
|
+
Provides-Extra: audio
|
|
26
|
+
Requires-Dist: elevenlabs[pyaudio]<2.69,>=2.68.0; extra == "audio"
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest<10,>=8; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-asyncio<2,>=1; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff<0.17,>=0.16; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy<3,>=2.3; extra == "dev"
|
|
32
|
+
Requires-Dist: build<2,>=1; extra == "dev"
|
|
33
|
+
Requires-Dist: setuptools-scm<9,>=8; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# Avartha Python SDK
|
|
37
|
+
|
|
38
|
+
Synchronous and asynchronous Python clients for Avartha Realtime LLMs,
|
|
39
|
+
streaming speech, and platform management. Requires Python 3.12+.
|
|
40
|
+
|
|
41
|
+
**Drop-in Python interfaces for OpenAI Realtime and ElevenLabs speech.** Change
|
|
42
|
+
the client import and configure Avartha credentials, URLs, and model IDs. Keep
|
|
43
|
+
the upstream resource methods, request types, response objects, and event loops:
|
|
44
|
+
|
|
45
|
+
```diff
|
|
46
|
+
-from openai import OpenAI, AsyncOpenAI
|
|
47
|
+
+from avartha import OpenAI, AsyncOpenAI
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```diff
|
|
51
|
+
-from elevenlabs.client import ElevenLabs, AsyncElevenLabs
|
|
52
|
+
+from avartha import ElevenLabs, AsyncElevenLabs
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
These classes extend the official SDKs. Compatibility depends on the server's
|
|
56
|
+
supported endpoints. Avartha managed inference is **WebSocket-only**; legacy
|
|
57
|
+
Chat Completions, Responses, and HTTP speech calls are retired. Preview testing
|
|
58
|
+
also found ASR and TTS mismatches with the official ElevenLabs client defaults.
|
|
59
|
+
[Migration details](docs/migration.md) · [Protocol audit and triage](docs/audit/report.md) · [Initial live test results](docs/preview-testing.md)
|
|
60
|
+
|
|
61
|
+
## Documentation
|
|
62
|
+
|
|
63
|
+
- [Drop-in migration from OpenAI and ElevenLabs](docs/migration.md)
|
|
64
|
+
- [Compatibility and endpoint coverage](docs/compatibility.md)
|
|
65
|
+
- [Protocol audit: defaults, message sequences, errors, and triage](docs/audit/report.md)
|
|
66
|
+
- [Platform management](docs/platform.md)
|
|
67
|
+
- [Runnable examples](examples)
|
|
68
|
+
- [Contributing](CONTRIBUTING.md)
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
The repository is private and the package has not been published to PyPI.
|
|
73
|
+
With GitHub access configured, install from source:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
git clone https://github.com/avartha/avartha-python-sdk.git
|
|
77
|
+
python -m pip install ./avartha-python-sdk
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Set your Avartha API key and platform root:
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
export AVARTHA_API_KEY='avk_...'
|
|
84
|
+
export AVARTHA_BASE_URL='https://platform.avartha.ai'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
For preview, set `AVARTHA_BASE_URL=https://platform.preview.avartha.ai`.
|
|
88
|
+
Both protocol clients derive their service URLs from this root. Use model and
|
|
89
|
+
voice IDs from the selected environment; vendor IDs are not mapped automatically.
|
|
90
|
+
|
|
91
|
+
## Usage
|
|
92
|
+
|
|
93
|
+
Use the OpenAI Realtime interface for LLM inference. The client reads
|
|
94
|
+
`AVARTHA_API_KEY` from the environment; `api_key` can also be passed explicitly.
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from avartha import OpenAI
|
|
98
|
+
|
|
99
|
+
with OpenAI() as client:
|
|
100
|
+
with client.realtime.connect(model="google/gemma-4-26b-a4b-it") as connection:
|
|
101
|
+
connection.session.update(session={"type": "realtime", "output_modalities": ["text"]})
|
|
102
|
+
connection.conversation.item.create(
|
|
103
|
+
item={
|
|
104
|
+
"type": "message",
|
|
105
|
+
"role": "user",
|
|
106
|
+
"content": [{"type": "input_text", "text": "Explain Python dictionaries."}],
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
connection.response.create()
|
|
110
|
+
for event in connection:
|
|
111
|
+
if event.type == "response.output_text.delta":
|
|
112
|
+
print(event.delta, end="", flush=True)
|
|
113
|
+
elif event.type == "response.done":
|
|
114
|
+
break
|
|
115
|
+
elif event.type == "error":
|
|
116
|
+
raise RuntimeError(event.error.message)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Keep the connection open for additional turns. Create another conversation item
|
|
120
|
+
and response on the same connection to preserve conversation state.
|
|
121
|
+
|
|
122
|
+
To discover available models and their enabled protocols:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from avartha import OpenAI
|
|
126
|
+
|
|
127
|
+
with OpenAI() as client:
|
|
128
|
+
for model in client.models.list():
|
|
129
|
+
print(model.id, model.to_dict().get("protocols", []))
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The preview catalog currently includes Gemma for `openai_realtime`, Qwen for
|
|
133
|
+
`elevenlabs_tts`, and Voxtral for `elevenlabs_asr`. Availability is workspace-
|
|
134
|
+
and tier-specific; discovery is authoritative for your key.
|
|
135
|
+
|
|
136
|
+
## Async usage
|
|
137
|
+
|
|
138
|
+
Use `AsyncOpenAI`, await operations, and iterate with `async for`. Request
|
|
139
|
+
parameters and event types remain the upstream SDK's own.
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
import asyncio
|
|
143
|
+
from avartha import AsyncOpenAI
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
async def main():
|
|
147
|
+
async with AsyncOpenAI() as client:
|
|
148
|
+
async with client.realtime.connect(model="google/gemma-4-26b-a4b-it") as connection:
|
|
149
|
+
await connection.session.update(
|
|
150
|
+
session={"type": "realtime", "output_modalities": ["text"]}
|
|
151
|
+
)
|
|
152
|
+
await connection.conversation.item.create(
|
|
153
|
+
item={
|
|
154
|
+
"type": "message",
|
|
155
|
+
"role": "user",
|
|
156
|
+
"content": [{"type": "input_text", "text": "Explain Python dictionaries."}],
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
await connection.response.create()
|
|
160
|
+
async for event in connection:
|
|
161
|
+
if event.type == "response.output_text.delta":
|
|
162
|
+
print(event.delta, end="", flush=True)
|
|
163
|
+
elif event.type == "response.done":
|
|
164
|
+
break
|
|
165
|
+
elif event.type == "error":
|
|
166
|
+
raise RuntimeError(event.error.message)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
asyncio.run(main())
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
[Complete Realtime example](examples/realtime.py).
|
|
173
|
+
|
|
174
|
+
## Streaming speech
|
|
175
|
+
|
|
176
|
+
`ElevenLabs()` defaults to the same Avartha platform root and serverless tier.
|
|
177
|
+
Its method names and wire messages come from the official ElevenLabs package.
|
|
178
|
+
|
|
179
|
+
### Text to speech
|
|
180
|
+
|
|
181
|
+
Discover voices for the selected TTS model using the upstream request options:
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from avartha import ElevenLabs
|
|
185
|
+
|
|
186
|
+
with ElevenLabs() as client:
|
|
187
|
+
voices = client.voices.get_all(
|
|
188
|
+
request_options={
|
|
189
|
+
"additional_query_parameters": {"model_id": "qwen/qwen3-tts-12hz-1.7b-base"}
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
for voice in voices.voices:
|
|
193
|
+
print(voice.voice_id)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Stream text over a WebSocket with `convert_realtime`. Avartha returns PCM;
|
|
197
|
+
select a sample rate supported by your model and write a WAV header for playback.
|
|
198
|
+
This example uses Qwen's 24 kHz output:
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
import wave
|
|
202
|
+
from avartha import ElevenLabs
|
|
203
|
+
|
|
204
|
+
with ElevenLabs() as client:
|
|
205
|
+
audio = client.text_to_speech.convert_realtime(
|
|
206
|
+
voice_id="carol",
|
|
207
|
+
model_id="qwen/qwen3-tts-12hz-1.7b-base",
|
|
208
|
+
output_format="pcm_24000",
|
|
209
|
+
text=iter(["Welcome. ", "How can I help?"]),
|
|
210
|
+
)
|
|
211
|
+
with wave.open("welcome.wav", "wb") as output:
|
|
212
|
+
output.setnchannels(1)
|
|
213
|
+
output.setsampwidth(2)
|
|
214
|
+
output.setframerate(24000)
|
|
215
|
+
for chunk in audio:
|
|
216
|
+
output.writeframes(chunk)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The official TTS helper currently fails on preview: Vajra requires
|
|
220
|
+
`auto_mode=true` and rejects the helper's hardcoded `try_trigger_generation`
|
|
221
|
+
and `generation_config` fields. Raw single- and multi-context TTS both succeeded
|
|
222
|
+
with native pacing, so this is a client/runtime contract mismatch, not a model
|
|
223
|
+
outage. See [the diagnosis](docs/preview-testing.md#tts-vajra-rejects-official-client-defaults).
|
|
224
|
+
The example above preserves the vendor interface and requires that mismatch to
|
|
225
|
+
be resolved on the service.
|
|
226
|
+
|
|
227
|
+
`convert_realtime` is synchronous, matching upstream. The pinned ElevenLabs SDK
|
|
228
|
+
has no multi-context helper; the platform's `multi-stream-input` WebSocket is a
|
|
229
|
+
separate vendor protocol surface. HTTP `text_to_speech.stream` and `.convert`
|
|
230
|
+
remain inherited methods but are not supported by managed inference.
|
|
231
|
+
[Runnable TTS example](examples/tts.py).
|
|
232
|
+
|
|
233
|
+
### Speech to text
|
|
234
|
+
|
|
235
|
+
Realtime ASR uses `await client.speech_to_text.realtime.connect(...)` on both
|
|
236
|
+
ElevenLabs client variants. Send mono PCM16 audio and await a committed transcript.
|
|
237
|
+
[The complete example](examples/realtime_asr.py) reads a WAV file, registers
|
|
238
|
+
transcript/error callbacks, streams chunks, commits, and closes the connection:
|
|
239
|
+
|
|
240
|
+
```sh
|
|
241
|
+
python examples/realtime_asr.py mistralai/voxtral-mini-4b-realtime-2602 speech-16k.wav
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Preview workaround:** pass `previous_text=""` in each `connection.send` data
|
|
245
|
+
dictionary when you have no context. The official SDK otherwise sends
|
|
246
|
+
`previous_text: null`, which preview currently rejects. Both sync-client and
|
|
247
|
+
async-client ASR sessions passed with the empty-string workaround. This is an
|
|
248
|
+
application option, not a change to the SDK's wire protocol.
|
|
249
|
+
|
|
250
|
+
File-based HTTP `speech_to_text.convert` is retired on managed inference.
|
|
251
|
+
|
|
252
|
+
## Agents
|
|
253
|
+
|
|
254
|
+
The SDK retains the complete ElevenLabs `conversational_ai` namespace, including
|
|
255
|
+
agent creation, tools, knowledge-base documents, and conversations. **Managed
|
|
256
|
+
Avartha agent CRUD does not currently implement the ElevenLabs endpoints.**
|
|
257
|
+
Its native control API uses a different schema. Preview's ElevenLabs-shaped
|
|
258
|
+
conversation-list endpoint did respond successfully.
|
|
259
|
+
|
|
260
|
+
Against a service that implements ElevenLabs agent management, the original
|
|
261
|
+
calls work unchanged:
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
from avartha import ElevenLabs
|
|
265
|
+
|
|
266
|
+
with ElevenLabs(base_url="https://your-compatible-agent-service") as client:
|
|
267
|
+
agent = client.conversational_ai.agents.create(
|
|
268
|
+
name="Support",
|
|
269
|
+
conversation_config={
|
|
270
|
+
"agent": {
|
|
271
|
+
"first_message": "What can I help you with?",
|
|
272
|
+
"prompt": {"prompt": "Help customers find concise, accurate answers."},
|
|
273
|
+
},
|
|
274
|
+
"tts": {"voice_id": "your-voice"},
|
|
275
|
+
},
|
|
276
|
+
)
|
|
277
|
+
print(agent.agent_id)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
`Conversation`, `AsyncConversation`, and `ClientTools` are the upstream classes,
|
|
281
|
+
also available from `avartha.conversational_ai`. `AsyncConversation` takes a
|
|
282
|
+
**sync** ElevenLabs client, matching upstream. Agent session execution has local
|
|
283
|
+
contract coverage; it was not exercised against a published preview agent.
|
|
284
|
+
|
|
285
|
+
- [Agent, tool, and knowledge-base example](examples/agents.py)
|
|
286
|
+
- [Conversation with client tools](examples/conversation.py)
|
|
287
|
+
|
|
288
|
+
## Using types
|
|
289
|
+
|
|
290
|
+
Continue importing types and exceptions from the upstream packages. The adapter
|
|
291
|
+
returns their original objects:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
from avartha import OpenAI
|
|
295
|
+
from openai.types import Model
|
|
296
|
+
|
|
297
|
+
with OpenAI() as client:
|
|
298
|
+
models: list[Model] = client.models.list().data
|
|
299
|
+
print([model.to_dict() for model in models])
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Use `openai.types` and `elevenlabs.types` for their full type catalogs.
|
|
303
|
+
`avartha.types` is not a replacement namespace. Platform management responses
|
|
304
|
+
are JSON dictionaries and lists.
|
|
305
|
+
|
|
306
|
+
## Handling errors
|
|
307
|
+
|
|
308
|
+
Keep existing vendor exception handlers. For HTTP discovery:
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
import openai
|
|
312
|
+
from avartha import OpenAI
|
|
313
|
+
|
|
314
|
+
with OpenAI() as client:
|
|
315
|
+
try:
|
|
316
|
+
client.models.list()
|
|
317
|
+
except openai.APIConnectionError as error:
|
|
318
|
+
print("Connection failed:", error)
|
|
319
|
+
except openai.APIStatusError as error:
|
|
320
|
+
print("Request failed:", error.status_code, error.request_id)
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Realtime server errors are events, so handle `event.type == "error"` in the
|
|
324
|
+
receive loop. Inspect `response.done.response.status` for completion, failure,
|
|
325
|
+
or cancellation; a terminal event alone does not prove successful inference.
|
|
326
|
+
Connection failures can raise WebSocket exceptions.
|
|
327
|
+
|
|
328
|
+
ElevenLabs HTTP/TTS helper errors remain `elevenlabs.core.api_error.ApiError`;
|
|
329
|
+
ASR also emits `RealtimeEvents.ERROR`. The upstream TTS helper can omit a
|
|
330
|
+
server error's details when the gateway closes the socket.
|
|
331
|
+
|
|
332
|
+
Management failures use `avartha.PlatformAPIError`, retaining the HTTP status,
|
|
333
|
+
response body, field errors, request ID, and `Retry-After` header. Management
|
|
334
|
+
network failures are `httpx` exceptions.
|
|
335
|
+
|
|
336
|
+
## Retries and timeouts
|
|
337
|
+
|
|
338
|
+
Upstream constructor options pass through:
|
|
339
|
+
|
|
340
|
+
```python
|
|
341
|
+
from avartha import OpenAI
|
|
342
|
+
|
|
343
|
+
with OpenAI(timeout=30.0, max_retries=0) as client:
|
|
344
|
+
print(client.models.list())
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
HTTP and WebSocket retry settings are separate. The pinned OpenAI client accepts
|
|
348
|
+
`client.realtime.connect(..., max_retries=0)` to disable automatic reconnection,
|
|
349
|
+
and `websocket_connection_options` for transport settings. Use `asyncio.timeout`
|
|
350
|
+
when an async operation needs an overall deadline. Close active sessions when
|
|
351
|
+
cancelling. ElevenLabs `timeout` does not bound every WebSocket receive; the
|
|
352
|
+
live smoke runner isolates its synchronous TTS helper to enforce a deadline.
|
|
353
|
+
Control-plane writes are never retried automatically.
|
|
354
|
+
|
|
355
|
+
## Configuration
|
|
356
|
+
|
|
357
|
+
| Client | Meaning of explicit `base_url` |
|
|
358
|
+
| --- | --- |
|
|
359
|
+
| `OpenAI`, `AsyncOpenAI` | Full inference base: `https://platform.avartha.ai/inference/serverless/openai/v1` |
|
|
360
|
+
| `ElevenLabs`, `AsyncElevenLabs` | Dialect root before `/v1`: `https://platform.avartha.ai/inference/serverless/elevenlabs` |
|
|
361
|
+
| `Avartha`, `AsyncAvartha`, `Control`, `AsyncControl` | Platform root: `https://platform.avartha.ai` |
|
|
362
|
+
|
|
363
|
+
Without an explicit URL, protocol clients derive their URL from
|
|
364
|
+
`AVARTHA_BASE_URL`. Set `tier="dedicated"` for dedicated inference; there is no
|
|
365
|
+
automatic fallback between tiers. An explicit protocol `base_url` takes
|
|
366
|
+
precedence over `tier`. `AVARTHA_ELEVENLABS_BASE_URL` overrides the derived speech
|
|
367
|
+
root, and an explicit ElevenLabs `base_url` overrides that environment variable.
|
|
368
|
+
|
|
369
|
+
Keys are read at construction from `AVARTHA_API_KEY` or `api_key`.
|
|
370
|
+
Vendor default keys and base URL variables are not substituted. Keep custom
|
|
371
|
+
upstream transports and type imports where needed; OpenAI 3 uses HTTPX2.
|
|
372
|
+
[Migration configuration](docs/migration.md#configuration).
|
|
373
|
+
|
|
374
|
+
Always close clients or use context managers. OpenAI retains its upstream
|
|
375
|
+
HTTP-client ownership behavior. ElevenLabs and Control close only clients they
|
|
376
|
+
created. Close active WebSocket sessions separately.
|
|
377
|
+
|
|
378
|
+
## Platform management
|
|
379
|
+
|
|
380
|
+
Use the combined `Avartha` client for inference plus management:
|
|
381
|
+
|
|
382
|
+
```python
|
|
383
|
+
from avartha import Avartha
|
|
384
|
+
|
|
385
|
+
with Avartha() as client:
|
|
386
|
+
print(client.control.catalog.models())
|
|
387
|
+
print(client.control.catalog.skus(provider="modal"))
|
|
388
|
+
print(client.control.organizations.list())
|
|
389
|
+
print(client.control.organizations.limits("your-workspace-id"))
|
|
390
|
+
print(client.control.endpoints.list(workspace_id="your-workspace-id"))
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
`client.openai` and `client.elevenlabs` are the protocol clients;
|
|
394
|
+
`client.realtime` is a shortcut to the OpenAI resource. `AsyncAvartha`, `Control`,
|
|
395
|
+
and `AsyncControl` are available too. Endpoint creation, readiness waiting,
|
|
396
|
+
scaling, routing, stopping, and deletion are described in the
|
|
397
|
+
[management guide](docs/platform.md).
|
|
398
|
+
|
|
399
|
+
## Examples and development
|
|
400
|
+
|
|
401
|
+
For local microphone/speaker support, install the `audio` extra from the
|
|
402
|
+
repository (`python -m pip install '.[audio]'`) and PortAudio.
|
|
403
|
+
|
|
404
|
+
```sh
|
|
405
|
+
python -m venv .venv
|
|
406
|
+
. .venv/bin/activate
|
|
407
|
+
make install-dev
|
|
408
|
+
make check
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
On images without `ensurepip`, install `uv` and use
|
|
412
|
+
`make check BUILD_FLAGS=--installer=uv`. CI runs on Python 3.12–3.14. Default
|
|
413
|
+
tests use mock HTTP transports and local WebSockets without cloud inference.
|
|
414
|
+
`make build` produces wheel and source archives; publication is separate.
|
|
415
|
+
|
|
416
|
+
Live testing is explicit and consumes inference credits. See
|
|
417
|
+
[preview testing](docs/preview-testing.md) for the runner and current results.
|