voice-vibecoder 2.9.3__tar.gz → 2.9.5__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.
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/CHANGELOG.md +16 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/PKG-INFO +1 -1
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/pyproject.toml +1 -1
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/__init__.py +1 -1
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/openclaw.py +31 -21
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/.github/workflows/ci.yml +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/.github/workflows/release.yml +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/.gitignore +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/LICENSE +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/README.md +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/app.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/index.html +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/app_config.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/audio.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/cli_serve.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/__init__.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/claude.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/cursor.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/registry.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/config.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/instances.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/server.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/session.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/tools/__init__.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/tools/agent_task.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/tools/definitions.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/tools/dispatch.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/tools/file_tree.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/tools/handlers.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/__init__.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/callbacks.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/diff_view.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/help_modal.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/panels.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/screen.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/setup.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/state.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/styles.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/update_modal.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/ui/wizard.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/voice_providers/__init__.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/voice_providers/openai.py +0 -0
- {voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/worktrees.py +0 -0
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v2.9.5 (2026-02-21)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- Use chat.send method for gateway streaming
|
|
10
|
+
([`a955747`](https://github.com/snokam/voice-vibecoder/commit/a955747a793514463f932376f0866cb140e364c6))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## v2.9.4 (2026-02-21)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
- Add operator.admin scope for agent.run
|
|
18
|
+
([`f0e658b`](https://github.com/snokam/voice-vibecoder/commit/f0e658b6b8834a876372a3c69d35ff4b184e6bcc))
|
|
19
|
+
|
|
20
|
+
|
|
5
21
|
## v2.9.3 (2026-02-21)
|
|
6
22
|
|
|
7
23
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voice-vibecoder
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.5
|
|
4
4
|
Summary: Olaf The Vibecoder — a voice-controlled coding assistant using OpenAI Realtime API + Claude Code
|
|
5
5
|
Project-URL: Homepage, https://github.com/snokam/voice-vibecoder
|
|
6
6
|
Project-URL: Repository, https://github.com/snokam/voice-vibecoder
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "voice-vibecoder"
|
|
7
|
-
version = "2.9.
|
|
7
|
+
version = "2.9.5"
|
|
8
8
|
description = "Olaf The Vibecoder — a voice-controlled coding assistant using OpenAI Realtime API + Claude Code"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
{voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/openclaw.py
RENAMED
|
@@ -68,11 +68,7 @@ def _build_auth_payload(
|
|
|
68
68
|
token: str | None,
|
|
69
69
|
nonce: str | None,
|
|
70
70
|
) -> str:
|
|
71
|
-
"""Build the payload to sign for device auth.
|
|
72
|
-
|
|
73
|
-
Format (v2 with nonce):
|
|
74
|
-
v2|deviceId|clientId|clientMode|role|scopes|signedAtMs|token|nonce
|
|
75
|
-
"""
|
|
71
|
+
"""Build the payload to sign for device auth."""
|
|
76
72
|
scopes_str = ",".join(scopes)
|
|
77
73
|
token_str = token or ""
|
|
78
74
|
|
|
@@ -152,7 +148,7 @@ class OpenClawRunner:
|
|
|
152
148
|
client_id = "cli"
|
|
153
149
|
client_mode = "cli"
|
|
154
150
|
role = "operator"
|
|
155
|
-
scopes = ["operator.read", "operator.write"]
|
|
151
|
+
scopes = ["operator.read", "operator.write", "operator.admin"]
|
|
156
152
|
|
|
157
153
|
payload = _build_auth_payload(
|
|
158
154
|
device_id=self._device_id,
|
|
@@ -235,19 +231,21 @@ class OpenClawRunner:
|
|
|
235
231
|
"""Run agent via WebSocket for streaming output."""
|
|
236
232
|
try:
|
|
237
233
|
req_id = str(uuid.uuid4())
|
|
238
|
-
|
|
234
|
+
idempotency_key = f"voice-{uuid.uuid4().hex[:16]}"
|
|
235
|
+
|
|
236
|
+
# Use chat.send method
|
|
237
|
+
chat_req = {
|
|
239
238
|
"type": "req",
|
|
240
239
|
"id": req_id,
|
|
241
|
-
"method": "
|
|
240
|
+
"method": "chat.send",
|
|
242
241
|
"params": {
|
|
243
|
-
"
|
|
242
|
+
"sessionKey": session_id,
|
|
244
243
|
"message": message,
|
|
245
|
-
"
|
|
246
|
-
"local": True
|
|
244
|
+
"idempotencyKey": idempotency_key,
|
|
247
245
|
}
|
|
248
246
|
}
|
|
249
247
|
|
|
250
|
-
await ws.send(json.dumps(
|
|
248
|
+
await ws.send(json.dumps(chat_req))
|
|
251
249
|
|
|
252
250
|
result_text = ""
|
|
253
251
|
|
|
@@ -255,31 +253,41 @@ class OpenClawRunner:
|
|
|
255
253
|
msg = await asyncio.wait_for(ws.recv(), timeout=300.0)
|
|
256
254
|
data = json.loads(msg)
|
|
257
255
|
|
|
256
|
+
# Handle events (streaming output)
|
|
258
257
|
if data.get("type") == "event":
|
|
259
258
|
event = data.get("event", "")
|
|
260
259
|
payload = data.get("payload", {})
|
|
261
260
|
|
|
262
|
-
if event == "
|
|
261
|
+
if event == "chat.chunk":
|
|
263
262
|
text = payload.get("text", "")
|
|
264
263
|
if text and on_output:
|
|
265
264
|
on_output(AgentOutput(category="text", content=text))
|
|
266
|
-
|
|
267
|
-
|
|
265
|
+
result_text += text
|
|
266
|
+
elif event == "chat.tool":
|
|
267
|
+
tool = payload.get("name", payload.get("tool", ""))
|
|
268
268
|
if on_output:
|
|
269
269
|
on_output(AgentOutput(category="tool_call", content=f"[{tool}]"))
|
|
270
|
+
elif event == "chat.done":
|
|
271
|
+
# Final result
|
|
272
|
+
final_text = payload.get("text", "")
|
|
273
|
+
if final_text:
|
|
274
|
+
result_text = final_text
|
|
275
|
+
break
|
|
276
|
+
elif event == "chat.error":
|
|
277
|
+
error = payload.get("message", "Unknown error")
|
|
278
|
+
raise RuntimeError(f"Chat error: {error}")
|
|
270
279
|
|
|
280
|
+
# Handle response (initial ack)
|
|
271
281
|
elif data.get("type") == "res" and data.get("id") == req_id:
|
|
272
|
-
if data.get("ok"):
|
|
273
|
-
result_text = data.get("payload", {}).get("result", "")
|
|
274
|
-
else:
|
|
282
|
+
if not data.get("ok"):
|
|
275
283
|
error = data.get("error", {}).get("message", "Unknown error")
|
|
276
|
-
raise RuntimeError(f"
|
|
277
|
-
|
|
284
|
+
raise RuntimeError(f"Chat send error: {error}")
|
|
285
|
+
# Continue listening for events
|
|
278
286
|
|
|
279
287
|
return AgentResult(text=result_text.strip(), session_id=session_id)
|
|
280
288
|
|
|
281
289
|
except Exception as e:
|
|
282
|
-
logger.warning("WebSocket
|
|
290
|
+
logger.warning("WebSocket chat failed: %s", e)
|
|
283
291
|
return None
|
|
284
292
|
|
|
285
293
|
async def _run_via_cli(
|
|
@@ -342,6 +350,8 @@ class OpenClawRunner:
|
|
|
342
350
|
ws = await self._connect_websocket()
|
|
343
351
|
if ws:
|
|
344
352
|
try:
|
|
353
|
+
if on_output:
|
|
354
|
+
on_output(AgentOutput(category="text", content="🦞 Connected! Streaming..."))
|
|
345
355
|
result = await self._run_via_websocket(ws, message, cwd, effective_session, on_output)
|
|
346
356
|
if result:
|
|
347
357
|
return result
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/__init__.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/claude.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/cursor.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/code_providers/registry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/voice_providers/__init__.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.9.3 → voice_vibecoder-2.9.5}/src/voice_vibecoder/voice_providers/openai.py
RENAMED
|
File without changes
|
|
File without changes
|