yaver 0.1.0__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.
yaver-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,77 @@
1
+ Metadata-Version: 2.4
2
+ Name: yaver
3
+ Version: 0.1.0
4
+ Summary: Yaver SDK — embed P2P AI agent connectivity into your Python apps
5
+ Author-email: Kivanc Cakmak <kivanc@yaver.io>
6
+ License: MIT
7
+ Project-URL: Homepage, https://yaver.io
8
+ Project-URL: Repository, https://github.com/kivanccakmak/yaver.io
9
+ Project-URL: Documentation, https://github.com/kivanccakmak/yaver.io/tree/main/sdk/python
10
+ Keywords: yaver,ai,agent,p2p,speech-to-text,tts,sdk
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown
23
+
24
+ # Yaver Python SDK
25
+
26
+ Embed Yaver's P2P AI agent connectivity into your Python applications. Zero dependencies (stdlib only).
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ pip install yaver
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```python
37
+ from yaver import YaverClient
38
+
39
+ client = YaverClient("http://localhost:18080", "your-auth-token")
40
+
41
+ # Create a task
42
+ task = client.create_task("Fix the login bug")
43
+ print(f"Task {task['id']} created")
44
+
45
+ # Stream output
46
+ for chunk in client.stream_output(task["id"]):
47
+ print(chunk, end="")
48
+
49
+ # List all tasks
50
+ tasks = client.list_tasks()
51
+ ```
52
+
53
+ ## Features
54
+
55
+ - **Task management**: create, list, get, stop, delete, continue tasks
56
+ - **Output streaming**: poll-based streaming with configurable interval
57
+ - **Auth client**: validate tokens, list devices, manage settings via Convex backend
58
+ - **Verbosity control**: set response detail level 0-10
59
+ - **Native mode**: optional ctypes bindings via C shared library (libyaver.so)
60
+ - **Zero dependencies**: uses only Python stdlib
61
+
62
+ ## Auth Client
63
+
64
+ ```python
65
+ from yaver import YaverAuthClient
66
+
67
+ auth = YaverAuthClient("your-token")
68
+ user = auth.validate_token()
69
+ devices = auth.list_devices()
70
+ settings = auth.get_settings()
71
+ ```
72
+
73
+ ## Links
74
+
75
+ - [Yaver](https://yaver.io) — main site
76
+ - [GitHub](https://github.com/kivanccakmak/yaver.io) — source code
77
+ - [SDK docs](https://github.com/kivanccakmak/yaver.io/tree/main/sdk) — all SDKs
yaver-0.1.0/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # Yaver Python SDK
2
+
3
+ Embed Yaver's P2P AI agent connectivity into your Python applications. Zero dependencies (stdlib only).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install yaver
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ from yaver import YaverClient
15
+
16
+ client = YaverClient("http://localhost:18080", "your-auth-token")
17
+
18
+ # Create a task
19
+ task = client.create_task("Fix the login bug")
20
+ print(f"Task {task['id']} created")
21
+
22
+ # Stream output
23
+ for chunk in client.stream_output(task["id"]):
24
+ print(chunk, end="")
25
+
26
+ # List all tasks
27
+ tasks = client.list_tasks()
28
+ ```
29
+
30
+ ## Features
31
+
32
+ - **Task management**: create, list, get, stop, delete, continue tasks
33
+ - **Output streaming**: poll-based streaming with configurable interval
34
+ - **Auth client**: validate tokens, list devices, manage settings via Convex backend
35
+ - **Verbosity control**: set response detail level 0-10
36
+ - **Native mode**: optional ctypes bindings via C shared library (libyaver.so)
37
+ - **Zero dependencies**: uses only Python stdlib
38
+
39
+ ## Auth Client
40
+
41
+ ```python
42
+ from yaver import YaverAuthClient
43
+
44
+ auth = YaverAuthClient("your-token")
45
+ user = auth.validate_token()
46
+ devices = auth.list_devices()
47
+ settings = auth.get_settings()
48
+ ```
49
+
50
+ ## Links
51
+
52
+ - [Yaver](https://yaver.io) — main site
53
+ - [GitHub](https://github.com/kivanccakmak/yaver.io) — source code
54
+ - [SDK docs](https://github.com/kivanccakmak/yaver.io/tree/main/sdk) — all SDKs
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "yaver"
7
+ version = "0.1.0"
8
+ description = "Yaver SDK — embed P2P AI agent connectivity into your Python apps"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.8"
12
+ authors = [
13
+ {name = "Kivanc Cakmak", email = "kivanc@yaver.io"},
14
+ ]
15
+ keywords = ["yaver", "ai", "agent", "p2p", "speech-to-text", "tts", "sdk"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.8",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Topic :: Software Development :: Libraries",
27
+ ]
28
+
29
+ [project.urls]
30
+ Homepage = "https://yaver.io"
31
+ Repository = "https://github.com/kivanccakmak/yaver.io"
32
+ Documentation = "https://github.com/kivanccakmak/yaver.io/tree/main/sdk/python"
33
+
34
+ [tool.setuptools]
35
+ py-modules = ["yaver"]
yaver-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,77 @@
1
+ Metadata-Version: 2.4
2
+ Name: yaver
3
+ Version: 0.1.0
4
+ Summary: Yaver SDK — embed P2P AI agent connectivity into your Python apps
5
+ Author-email: Kivanc Cakmak <kivanc@yaver.io>
6
+ License: MIT
7
+ Project-URL: Homepage, https://yaver.io
8
+ Project-URL: Repository, https://github.com/kivanccakmak/yaver.io
9
+ Project-URL: Documentation, https://github.com/kivanccakmak/yaver.io/tree/main/sdk/python
10
+ Keywords: yaver,ai,agent,p2p,speech-to-text,tts,sdk
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown
23
+
24
+ # Yaver Python SDK
25
+
26
+ Embed Yaver's P2P AI agent connectivity into your Python applications. Zero dependencies (stdlib only).
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ pip install yaver
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```python
37
+ from yaver import YaverClient
38
+
39
+ client = YaverClient("http://localhost:18080", "your-auth-token")
40
+
41
+ # Create a task
42
+ task = client.create_task("Fix the login bug")
43
+ print(f"Task {task['id']} created")
44
+
45
+ # Stream output
46
+ for chunk in client.stream_output(task["id"]):
47
+ print(chunk, end="")
48
+
49
+ # List all tasks
50
+ tasks = client.list_tasks()
51
+ ```
52
+
53
+ ## Features
54
+
55
+ - **Task management**: create, list, get, stop, delete, continue tasks
56
+ - **Output streaming**: poll-based streaming with configurable interval
57
+ - **Auth client**: validate tokens, list devices, manage settings via Convex backend
58
+ - **Verbosity control**: set response detail level 0-10
59
+ - **Native mode**: optional ctypes bindings via C shared library (libyaver.so)
60
+ - **Zero dependencies**: uses only Python stdlib
61
+
62
+ ## Auth Client
63
+
64
+ ```python
65
+ from yaver import YaverAuthClient
66
+
67
+ auth = YaverAuthClient("your-token")
68
+ user = auth.validate_token()
69
+ devices = auth.list_devices()
70
+ settings = auth.get_settings()
71
+ ```
72
+
73
+ ## Links
74
+
75
+ - [Yaver](https://yaver.io) — main site
76
+ - [GitHub](https://github.com/kivanccakmak/yaver.io) — source code
77
+ - [SDK docs](https://github.com/kivanccakmak/yaver.io/tree/main/sdk) — all SDKs
@@ -0,0 +1,7 @@
1
+ README.md
2
+ pyproject.toml
3
+ yaver.py
4
+ yaver.egg-info/PKG-INFO
5
+ yaver.egg-info/SOURCES.txt
6
+ yaver.egg-info/dependency_links.txt
7
+ yaver.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ yaver
yaver-0.1.0/yaver.py ADDED
@@ -0,0 +1,273 @@
1
+ """
2
+ Yaver Python SDK — embed Yaver's P2P connectivity into your Python applications.
3
+
4
+ Supports two backends:
5
+ 1. Native (ctypes) — loads the C shared library built from Go SDK
6
+ 2. HTTP — direct HTTP calls to a Yaver agent (no shared library needed)
7
+
8
+ Quick start (HTTP mode — no build step):
9
+
10
+ from yaver import YaverClient
11
+
12
+ client = YaverClient("http://localhost:18080", "your-auth-token")
13
+ task = client.create_task("Fix the login bug")
14
+ for line in client.stream_output(task["id"]):
15
+ print(line, end="")
16
+
17
+ Quick start (native mode — requires libyaver.so):
18
+
19
+ from yaver import YaverNativeClient
20
+
21
+ client = YaverNativeClient("http://localhost:18080", "your-auth-token")
22
+ task = client.create_task("Fix the login bug")
23
+ """
24
+
25
+ import json
26
+ import time
27
+ from typing import Optional, Iterator, Any
28
+ from urllib.request import Request, urlopen
29
+ from urllib.error import HTTPError
30
+
31
+
32
+ class YaverClient:
33
+ """HTTP-based Yaver client. No shared library needed."""
34
+
35
+ def __init__(self, base_url: str, auth_token: str, timeout: float = 30.0):
36
+ self.base_url = base_url.rstrip("/")
37
+ self.auth_token = auth_token
38
+ self.timeout = timeout
39
+
40
+ def _request(self, method: str, path: str, body: Any = None) -> dict:
41
+ url = f"{self.base_url}{path}"
42
+ data = json.dumps(body).encode() if body else None
43
+ req = Request(url, data=data, method=method)
44
+ req.add_header("Authorization", f"Bearer {self.auth_token}")
45
+ if data:
46
+ req.add_header("Content-Type", "application/json")
47
+ try:
48
+ with urlopen(req, timeout=self.timeout) as resp:
49
+ return json.loads(resp.read())
50
+ except HTTPError as e:
51
+ error_body = e.read().decode() if e.fp else str(e)
52
+ raise RuntimeError(f"HTTP {e.code}: {error_body}")
53
+
54
+ def health(self) -> dict:
55
+ """Check if the agent is reachable."""
56
+ return self._request("GET", "/health")
57
+
58
+ def ping(self) -> float:
59
+ """Measure round-trip time in milliseconds."""
60
+ start = time.monotonic()
61
+ self.health()
62
+ return (time.monotonic() - start) * 1000
63
+
64
+ def info(self) -> dict:
65
+ """Get agent status information."""
66
+ return self._request("GET", "/info")
67
+
68
+ def create_task(
69
+ self,
70
+ prompt: str,
71
+ model: Optional[str] = None,
72
+ runner: Optional[str] = None,
73
+ custom_command: Optional[str] = None,
74
+ verbosity: Optional[int] = None,
75
+ ) -> dict:
76
+ """Create a new task on the remote agent."""
77
+ body: dict = {"title": prompt}
78
+ if model:
79
+ body["model"] = model
80
+ if runner:
81
+ body["runner"] = runner
82
+ if custom_command:
83
+ body["customCommand"] = custom_command
84
+ if verbosity is not None:
85
+ body["speechContext"] = {"verbosity": verbosity}
86
+ result = self._request("POST", "/tasks", body)
87
+ if not result.get("ok"):
88
+ raise RuntimeError(result.get("error", "Unknown error"))
89
+ return {
90
+ "id": result["taskId"],
91
+ "status": result["status"],
92
+ "runner_id": result.get("runnerId", ""),
93
+ }
94
+
95
+ def get_task(self, task_id: str) -> dict:
96
+ """Get task details by ID."""
97
+ result = self._request("GET", f"/tasks/{task_id}")
98
+ return result.get("task", result)
99
+
100
+ def list_tasks(self) -> list:
101
+ """List all tasks."""
102
+ result = self._request("GET", "/tasks")
103
+ return result.get("tasks", [])
104
+
105
+ def stop_task(self, task_id: str) -> None:
106
+ """Stop a running task."""
107
+ result = self._request("POST", f"/tasks/{task_id}/stop")
108
+ if not result.get("ok"):
109
+ raise RuntimeError(result.get("error", "Failed to stop task"))
110
+
111
+ def delete_task(self, task_id: str) -> None:
112
+ """Delete a task."""
113
+ self._request("DELETE", f"/tasks/{task_id}")
114
+
115
+ def continue_task(self, task_id: str, message: str) -> None:
116
+ """Send a follow-up message to a running task."""
117
+ result = self._request("POST", f"/tasks/{task_id}/continue", {"message": message})
118
+ if not result.get("ok"):
119
+ raise RuntimeError(result.get("error", "Failed to continue task"))
120
+
121
+ def stream_output(self, task_id: str, poll_interval: float = 0.5) -> Iterator[str]:
122
+ """Stream task output. Yields new output as it arrives."""
123
+ last_len = 0
124
+ while True:
125
+ task = self.get_task(task_id)
126
+ output = task.get("output", "")
127
+ if len(output) > last_len:
128
+ yield output[last_len:]
129
+ last_len = len(output)
130
+ status = task.get("status", "")
131
+ if status in ("completed", "failed", "stopped"):
132
+ return
133
+ time.sleep(poll_interval)
134
+
135
+
136
+ class YaverAuthClient:
137
+ """Auth client for the Convex backend."""
138
+
139
+ DEFAULT_CONVEX_URL = "https://perceptive-minnow-557.eu-west-1.convex.site"
140
+
141
+ def __init__(self, auth_token: str, convex_url: Optional[str] = None, timeout: float = 10.0):
142
+ self.convex_url = (convex_url or self.DEFAULT_CONVEX_URL).rstrip("/")
143
+ self.auth_token = auth_token
144
+ self.timeout = timeout
145
+
146
+ def _request(self, method: str, path: str, body: Any = None) -> dict:
147
+ url = f"{self.convex_url}{path}"
148
+ data = json.dumps(body).encode() if body else None
149
+ req = Request(url, data=data, method=method)
150
+ req.add_header("Authorization", f"Bearer {self.auth_token}")
151
+ if data:
152
+ req.add_header("Content-Type", "application/json")
153
+ with urlopen(req, timeout=self.timeout) as resp:
154
+ return json.loads(resp.read())
155
+
156
+ def validate_token(self) -> dict:
157
+ """Validate the auth token and return user info."""
158
+ return self._request("GET", "/auth/validate")
159
+
160
+ def list_devices(self) -> list:
161
+ """List registered devices."""
162
+ result = self._request("GET", "/devices")
163
+ return result.get("devices", [])
164
+
165
+ def get_settings(self) -> dict:
166
+ """Get user settings."""
167
+ result = self._request("GET", "/settings")
168
+ return result.get("settings", {})
169
+
170
+ def save_settings(self, settings: dict) -> None:
171
+ """Save user settings."""
172
+ self._request("POST", "/settings", settings)
173
+
174
+
175
+ # ── Native (ctypes) client ────────────────────────────────────────────
176
+
177
+ try:
178
+ import ctypes
179
+ import ctypes.util
180
+ import os
181
+ import platform
182
+
183
+ def _find_lib():
184
+ """Find the libyaver shared library."""
185
+ # Check common locations
186
+ for name in ["libyaver.so", "libyaver.dylib", "libyaver.dll"]:
187
+ # Same directory as this file
188
+ here = os.path.join(os.path.dirname(__file__), name)
189
+ if os.path.exists(here):
190
+ return here
191
+ # SDK build directory
192
+ sdk_path = os.path.join(os.path.dirname(__file__), "..", "go", "clib", name)
193
+ if os.path.exists(sdk_path):
194
+ return sdk_path
195
+ # System library path
196
+ path = ctypes.util.find_library("yaver")
197
+ if path:
198
+ return path
199
+ return None
200
+
201
+ class YaverNativeClient:
202
+ """Native Yaver client using the C shared library (libyaver.so/dylib/dll)."""
203
+
204
+ def __init__(self, base_url: str, auth_token: str, lib_path: Optional[str] = None):
205
+ path = lib_path or _find_lib()
206
+ if not path:
207
+ raise FileNotFoundError(
208
+ "libyaver shared library not found. "
209
+ "Build it: cd sdk/go/clib && go build -buildmode=c-shared -o libyaver.so ."
210
+ )
211
+ self._lib = ctypes.CDLL(path)
212
+
213
+ # Set up function signatures
214
+ self._lib.YaverNewClient.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
215
+ self._lib.YaverNewClient.restype = ctypes.c_int
216
+ self._lib.YaverFreeClient.argtypes = [ctypes.c_int]
217
+ self._lib.YaverHealth.argtypes = [ctypes.c_int]
218
+ self._lib.YaverHealth.restype = ctypes.c_char_p
219
+ self._lib.YaverPing.argtypes = [ctypes.c_int]
220
+ self._lib.YaverPing.restype = ctypes.c_char_p
221
+ self._lib.YaverCreateTask.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_char_p]
222
+ self._lib.YaverCreateTask.restype = ctypes.c_char_p
223
+ self._lib.YaverGetTask.argtypes = [ctypes.c_int, ctypes.c_char_p]
224
+ self._lib.YaverGetTask.restype = ctypes.c_char_p
225
+ self._lib.YaverListTasks.argtypes = [ctypes.c_int]
226
+ self._lib.YaverListTasks.restype = ctypes.c_char_p
227
+ self._lib.YaverStopTask.argtypes = [ctypes.c_int, ctypes.c_char_p]
228
+ self._lib.YaverStopTask.restype = ctypes.c_char_p
229
+ self._lib.YaverTranscribe.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p]
230
+ self._lib.YaverTranscribe.restype = ctypes.c_char_p
231
+ self._lib.YaverSpeak.argtypes = [ctypes.c_char_p]
232
+ self._lib.YaverSpeak.restype = ctypes.c_char_p
233
+
234
+ self._id = self._lib.YaverNewClient(
235
+ base_url.encode(), auth_token.encode()
236
+ )
237
+
238
+ def __del__(self):
239
+ if hasattr(self, "_lib") and hasattr(self, "_id"):
240
+ self._lib.YaverFreeClient(self._id)
241
+
242
+ def _call(self, result_bytes: bytes) -> dict:
243
+ return json.loads(result_bytes.decode())
244
+
245
+ def health(self) -> dict:
246
+ return self._call(self._lib.YaverHealth(self._id))
247
+
248
+ def ping(self) -> dict:
249
+ return self._call(self._lib.YaverPing(self._id))
250
+
251
+ def create_task(self, prompt: str, opts: Optional[dict] = None) -> dict:
252
+ opts_json = json.dumps(opts).encode() if opts else None
253
+ return self._call(self._lib.YaverCreateTask(self._id, prompt.encode(), opts_json))
254
+
255
+ def get_task(self, task_id: str) -> dict:
256
+ return self._call(self._lib.YaverGetTask(self._id, task_id.encode()))
257
+
258
+ def list_tasks(self) -> list:
259
+ return self._call(self._lib.YaverListTasks(self._id))
260
+
261
+ def stop_task(self, task_id: str) -> dict:
262
+ return self._call(self._lib.YaverStopTask(self._id, task_id.encode()))
263
+
264
+ def transcribe(self, audio_path: str, provider: str = "whisper", api_key: str = "") -> dict:
265
+ return self._call(self._lib.YaverTranscribe(
266
+ audio_path.encode(), provider.encode(), api_key.encode()
267
+ ))
268
+
269
+ def speak(self, text: str) -> dict:
270
+ return self._call(self._lib.YaverSpeak(text.encode()))
271
+
272
+ except ImportError:
273
+ pass # ctypes not available — native client disabled