voice-vibecoder 2.10.0__tar.gz → 2.10.2__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.
Files changed (43) hide show
  1. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/CHANGELOG.md +16 -0
  2. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/PKG-INFO +1 -1
  3. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/pyproject.toml +1 -1
  4. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/__init__.py +1 -1
  5. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/code_providers/openclaw.py +25 -3
  6. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/.github/workflows/ci.yml +0 -0
  7. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/.github/workflows/release.yml +0 -0
  8. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/.gitignore +0 -0
  9. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/LICENSE +0 -0
  10. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/README.md +0 -0
  11. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/app.py +0 -0
  12. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/index.html +0 -0
  13. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/app_config.py +0 -0
  14. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/audio.py +0 -0
  15. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/cli_serve.py +0 -0
  16. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/code_providers/__init__.py +0 -0
  17. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/code_providers/claude.py +0 -0
  18. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/code_providers/cursor.py +0 -0
  19. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/code_providers/registry.py +0 -0
  20. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/config.py +0 -0
  21. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/instances.py +0 -0
  22. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/server.py +0 -0
  23. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/session.py +0 -0
  24. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/tools/__init__.py +0 -0
  25. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/tools/agent_task.py +0 -0
  26. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/tools/definitions.py +0 -0
  27. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/tools/dispatch.py +0 -0
  28. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/tools/file_tree.py +0 -0
  29. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/tools/handlers.py +0 -0
  30. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/__init__.py +0 -0
  31. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/callbacks.py +0 -0
  32. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/diff_view.py +0 -0
  33. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/help_modal.py +0 -0
  34. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/panels.py +0 -0
  35. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/screen.py +0 -0
  36. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/setup.py +0 -0
  37. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/state.py +0 -0
  38. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/styles.py +0 -0
  39. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/update_modal.py +0 -0
  40. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/ui/wizard.py +0 -0
  41. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/voice_providers/__init__.py +0 -0
  42. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/voice_providers/openai.py +0 -0
  43. {voice_vibecoder-2.10.0 → voice_vibecoder-2.10.2}/src/voice_vibecoder/worktrees.py +0 -0
@@ -2,6 +2,22 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v2.10.2 (2026-02-21)
6
+
7
+ ### Bug Fixes
8
+
9
+ - Improve text buffering - flush on newlines not punctuation
10
+ ([`b1f13bf`](https://github.com/snokam/voice-vibecoder/commit/b1f13bf68ccfa60b591f4e9e21d74c777c4f6957))
11
+
12
+
13
+ ## v2.10.1 (2026-02-21)
14
+
15
+ ### Bug Fixes
16
+
17
+ - Buffer streaming text to avoid fragmented output
18
+ ([`f46e2c1`](https://github.com/snokam/voice-vibecoder/commit/f46e2c13f9eca5a42df4fa8d46ebb56e479d4bea))
19
+
20
+
5
21
  ## v2.10.0 (2026-02-21)
6
22
 
7
23
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voice-vibecoder
3
- Version: 2.10.0
3
+ Version: 2.10.2
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.10.0"
7
+ version = "2.10.2"
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"
@@ -3,7 +3,7 @@
3
3
  A voice-controlled coding assistant using OpenAI Realtime API + Claude Code.
4
4
  """
5
5
 
6
- __version__ = "2.10.0"
6
+ __version__ = "2.10.2"
7
7
 
8
8
  from voice_vibecoder.app_config import VoiceConfig
9
9
  from voice_vibecoder.ui.screen import VoiceCodingScreen
@@ -243,6 +243,14 @@ class OpenClawRunner:
243
243
 
244
244
  result_text = ""
245
245
  last_text = ""
246
+ text_buffer = ""
247
+ last_flush_time = time.time()
248
+
249
+ async def flush_buffer():
250
+ nonlocal text_buffer
251
+ if text_buffer and on_output:
252
+ on_output(AgentOutput(category="text", content=text_buffer))
253
+ text_buffer = ""
246
254
 
247
255
  while True:
248
256
  msg = await asyncio.wait_for(ws.recv(), timeout=300.0)
@@ -257,13 +265,26 @@ class OpenClawRunner:
257
265
 
258
266
  if stream == "assistant" and "text" in agent_data:
259
267
  text = agent_data["text"]
260
- # Send delta (new text since last)
268
+ # Buffer delta and flush on sentence boundaries or timeout
261
269
  if text and len(text) > len(last_text):
262
270
  delta = text[len(last_text):]
263
- if on_output and delta:
264
- on_output(AgentOutput(category="text", content=delta))
271
+ text_buffer += delta
265
272
  last_text = text
266
273
  result_text = text
274
+
275
+ # Flush on newlines or when buffer is large enough
276
+ now = time.time()
277
+ # Only flush on actual line breaks or large buffers
278
+ # Avoid flushing on . ! ? as they appear mid-text
279
+ should_flush = (
280
+ "\n" in delta
281
+ or delta.endswith("|") # Table row end
282
+ or len(text_buffer) > 120
283
+ or (now - last_flush_time) > 1.0
284
+ )
285
+ if should_flush:
286
+ await flush_buffer()
287
+ last_flush_time = now
267
288
 
268
289
  elif stream == "tool":
269
290
  # Tool execution
@@ -288,6 +309,7 @@ class OpenClawRunner:
288
309
  elif event == "chat":
289
310
  state = payload.get("state")
290
311
  if state == "final":
312
+ await flush_buffer() # Flush remaining text
291
313
  # Get final message
292
314
  msg_content = payload.get("message", {})
293
315
  if isinstance(msg_content, dict) and "content" in msg_content: