streamdouble 0.1.0__tar.gz → 0.1.0.dev0__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 (68) hide show
  1. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/PKG-INFO +8 -24
  2. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/PLAN.md +8 -9
  3. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/README.md +7 -23
  4. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/pyproject.toml +1 -1
  5. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/__init__.py +1 -1
  6. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.gitattributes +0 -0
  7. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  8. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  9. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/ISSUE_TEMPLATE/protocol-difference.yml +0 -0
  10. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/workflows/ci.yml +0 -0
  11. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/workflows/release.yml +0 -0
  12. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.gitignore +0 -0
  13. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/CLAUDE.md +0 -0
  14. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/CONTRIBUTING.md +0 -0
  15. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/LICENSE +0 -0
  16. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/docs/demo.svg +0 -0
  17. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/docs/launch-drafts.md +0 -0
  18. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/docs/mulaw-gotchas.md +0 -0
  19. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/examples/echo_agent.py +0 -0
  20. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/alias_bait_44k.wav +0 -0
  21. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/long_8k.wav +0 -0
  22. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/make_fixtures.py +0 -0
  23. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/make_speech.py +0 -0
  24. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/noisy_8k.wav +0 -0
  25. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/partial_frame_8k.wav +0 -0
  26. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/silence_8k.wav +0 -0
  27. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_16k.wav +0 -0
  28. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_44k_stereo.wav +0 -0
  29. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_8k.wav +0 -0
  30. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_8k_24bit.wav +0 -0
  31. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_8k_32bit.wav +0 -0
  32. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_8k_8bit.wav +0 -0
  33. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/tone_440_8k.wav +0 -0
  34. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/scenarios/barge_in.yaml +0 -0
  35. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/scenarios/hangup.yaml +0 -0
  36. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/scenarios/no_input.yaml +0 -0
  37. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/skill/SKILL.md +0 -0
  38. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/audio.py +0 -0
  39. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/chaos.py +0 -0
  40. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/cli.py +0 -0
  41. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/g711.py +0 -0
  42. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/metrics.py +0 -0
  43. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/pacer.py +0 -0
  44. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/protocol.py +0 -0
  45. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/scenario.py +0 -0
  46. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/session.py +0 -0
  47. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/conftest.py +0 -0
  48. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/golden/frames.json +0 -0
  49. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_audio.py +0 -0
  50. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_chaos.py +0 -0
  51. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_cli.py +0 -0
  52. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_documented_commands.py +0 -0
  53. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_g711.py +0 -0
  54. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_golden.py +0 -0
  55. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_integration_echo.py +0 -0
  56. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_measurement_validity.py +0 -0
  57. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_metrics.py +0 -0
  58. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_pacer.py +0 -0
  59. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_protocol.py +0 -0
  60. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_review_gate_1.py +0 -0
  61. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_review_gate_2.py +0 -0
  62. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_review_gate_3.py +0 -0
  63. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_review_gate_4.py +0 -0
  64. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_scenario.py +0 -0
  65. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_scenario_execution.py +0 -0
  66. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_session.py +0 -0
  67. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_signal_integrity.py +0 -0
  68. {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tools/make_demo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: streamdouble
3
- Version: 0.1.0
3
+ Version: 0.1.0.dev0
4
4
  Summary: A framework-agnostic Twilio Media Streams simulator. Test your voice agent's WebSocket endpoint locally, at full protocol fidelity, without placing a real call.
5
5
  Project-URL: Homepage, https://github.com/shaswat28/streamdouble
6
6
  Project-URL: Issues, https://github.com/shaswat28/streamdouble/issues
@@ -40,10 +40,9 @@ WebSocket endpoint locally, at full protocol fidelity, without placing a real ca
40
40
 
41
41
  ![streamdouble placing a simulated Twilio call](docs/demo.svg)
42
42
 
43
- > **Status: early, but it works.** Places real calls, records the reply,
44
- > simulates bad networks, runs scripted scenarios, and gates on latency in CI.
45
- > Validated against a production voice agent, where it found a real bug.
46
- > Expect the API to move before 1.0.
43
+ > **Status: pre-alpha, under active construction.** Phases 1–5 of 6 complete.
44
+ > Places real calls, records the reply, simulates bad networks, runs scripted
45
+ > scenarios, and gates on latency in CI. Not yet published to PyPI.
47
46
 
48
47
  ---
49
48
 
@@ -65,27 +64,12 @@ enough that your agent cannot tell it isn't Twilio.
65
64
  Two terminals. No Twilio account, no tunnel, no phone.
66
65
 
67
66
  ```bash
68
- pip install streamdouble
69
- ```
70
-
71
- Point it at your agent, with any WAV as the caller's voice:
72
-
73
- ```bash
74
- streamdouble call ws://localhost:8000/media-stream --audio hello.wav --out reply.wav
75
- ```
76
-
77
- `reply.wav` is what your agent said back.
78
-
79
- **No voice agent yet?** Clone this repository — it ships one to talk to, plus
80
- the audio fixtures:
81
-
82
- ```bash
83
- git clone https://github.com/shaswat28/streamdouble && cd streamdouble
84
- python examples/echo_agent.py --port 8000 # terminal one
67
+ pip install -e ".[dev]"
68
+ python examples/echo_agent.py --port 8000
85
69
  ```
86
70
 
87
71
  ```bash
88
- streamdouble call ws://localhost:8000/media-stream --audio fixtures/speech_8k.wav --out reply.wav # terminal two
72
+ streamdouble call ws://localhost:8000/media-stream --audio fixtures/speech_8k.wav --out reply.wav
89
73
  ```
90
74
 
91
75
  ```
@@ -165,7 +149,7 @@ name: caller interrupts the greeting
165
149
  steps:
166
150
  - wait_for: audio # let the agent get going
167
151
  - wait: 1.5 # streaming silence, not stopping
168
- - say: ../fixtures/speech/interrupt.wav
152
+ - say: ../fixtures/speech_8k.wav
169
153
  - expect: clear # a correct agent stops talking
170
154
  - wait: 1.0
171
155
  ```
@@ -3,10 +3,9 @@
3
3
  > A framework-agnostic Twilio Media Streams simulator. Test your voice agent's
4
4
  > WebSocket endpoint locally, at full protocol fidelity, without placing a real call.
5
5
 
6
- **Status:** All six phases complete, gates 1-4 passed. Public and published on
7
- PyPI. Gate 5's clean-install half is done -- the package was installed from
8
- PyPI into an empty virtualenv and exercised; what is still owed is someone who
9
- is not the author reading the README cold.
6
+ **Status:** Phases 1-5 complete, gates 1-4 passed, Phase 6 under way. Public,
7
+ not yet on PyPI. Gate 5 (fresh-eyes / clean-machine) is partly done and partly
8
+ owed.
10
9
  **License:** Apache-2.0
11
10
  **Language:** Python 3.11+
12
11
  **Name:** `streamdouble` — `dialtone` was taken on PyPI. See [Progress](#progress).
@@ -342,9 +341,9 @@ That is the proof the tool has value beyond the happy path.
342
341
  - [x] CONTRIBUTING.md and issue templates. The protocol-difference template
343
342
  leads with "tell us where the simulation is wrong", because that is the
344
343
  most valuable report this project can receive.
345
- - [x] **PyPI publish — done.** `.github/workflows/release.yml` stays
346
- manual-dispatch with `publish: false` by default, so no release happens
347
- by accident. 0.1.0.dev0 went out first; 0.1.0 is the real one.
344
+ - [ ] **PyPI publish — not yet done.** `.github/workflows/release.yml` is
345
+ manual-dispatch only, with `publish: false` by default, so the ordinary
346
+ run builds and verifies without uploading anything.
348
347
 
349
348
  > ### 🟡 REVIEW GATE 5 — Fresh-eyes pass — PARTLY DONE
350
349
  >
@@ -370,7 +369,7 @@ That is the proof the tool has value beyond the happy path.
370
369
 
371
370
  ---
372
371
 
373
- ### Phase 6 — Distribution DONE
372
+ ### Phase 6 — Distribution 🔨 IN PROGRESS
374
373
 
375
374
  - [x] **Claude Code skill wrapper** — `skill/SKILL.md`. Carries the judgement
376
375
  as well as the commands: disable what the agent touches on hangup before
@@ -433,7 +432,7 @@ something personally useful; that is the checkpoint that sustains the rest.
433
432
  - [ ] A stranger installs it and gets a result in under five minutes
434
433
  - [ ] Reproduces at least one real bug that a phone call would have been needed to find
435
434
  - [ ] README has a demo GIF and an honest comparison table
436
- - [x] Published to PyPI under Apache-2.0
435
+ - [ ] Published to PyPI under AGPL-3.0
437
436
 
438
437
  ---
439
438
 
@@ -5,10 +5,9 @@ WebSocket endpoint locally, at full protocol fidelity, without placing a real ca
5
5
 
6
6
  ![streamdouble placing a simulated Twilio call](docs/demo.svg)
7
7
 
8
- > **Status: early, but it works.** Places real calls, records the reply,
9
- > simulates bad networks, runs scripted scenarios, and gates on latency in CI.
10
- > Validated against a production voice agent, where it found a real bug.
11
- > Expect the API to move before 1.0.
8
+ > **Status: pre-alpha, under active construction.** Phases 1–5 of 6 complete.
9
+ > Places real calls, records the reply, simulates bad networks, runs scripted
10
+ > scenarios, and gates on latency in CI. Not yet published to PyPI.
12
11
 
13
12
  ---
14
13
 
@@ -30,27 +29,12 @@ enough that your agent cannot tell it isn't Twilio.
30
29
  Two terminals. No Twilio account, no tunnel, no phone.
31
30
 
32
31
  ```bash
33
- pip install streamdouble
34
- ```
35
-
36
- Point it at your agent, with any WAV as the caller's voice:
37
-
38
- ```bash
39
- streamdouble call ws://localhost:8000/media-stream --audio hello.wav --out reply.wav
40
- ```
41
-
42
- `reply.wav` is what your agent said back.
43
-
44
- **No voice agent yet?** Clone this repository — it ships one to talk to, plus
45
- the audio fixtures:
46
-
47
- ```bash
48
- git clone https://github.com/shaswat28/streamdouble && cd streamdouble
49
- python examples/echo_agent.py --port 8000 # terminal one
32
+ pip install -e ".[dev]"
33
+ python examples/echo_agent.py --port 8000
50
34
  ```
51
35
 
52
36
  ```bash
53
- streamdouble call ws://localhost:8000/media-stream --audio fixtures/speech_8k.wav --out reply.wav # terminal two
37
+ streamdouble call ws://localhost:8000/media-stream --audio fixtures/speech_8k.wav --out reply.wav
54
38
  ```
55
39
 
56
40
  ```
@@ -130,7 +114,7 @@ name: caller interrupts the greeting
130
114
  steps:
131
115
  - wait_for: audio # let the agent get going
132
116
  - wait: 1.5 # streaming silence, not stopping
133
- - say: ../fixtures/speech/interrupt.wav
117
+ - say: ../fixtures/speech_8k.wav
134
118
  - expect: clear # a correct agent stops talking
135
119
  - wait: 1.0
136
120
  ```
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "streamdouble"
7
- version = "0.1.0"
7
+ version = "0.1.0.dev0"
8
8
  description = "A framework-agnostic Twilio Media Streams simulator. Test your voice agent's WebSocket endpoint locally, at full protocol fidelity, without placing a real call."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -9,6 +9,6 @@ Twilio Media Streams protocol.
9
9
 
10
10
  from __future__ import annotations
11
11
 
12
- __version__ = "0.1.0"
12
+ __version__ = "0.1.0.dev0"
13
13
 
14
14
  __all__ = ["__version__"]
File without changes