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.
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/PKG-INFO +8 -24
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/PLAN.md +8 -9
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/README.md +7 -23
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/pyproject.toml +1 -1
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/__init__.py +1 -1
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.gitattributes +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/ISSUE_TEMPLATE/protocol-difference.yml +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/workflows/ci.yml +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/workflows/release.yml +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.gitignore +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/CLAUDE.md +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/CONTRIBUTING.md +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/LICENSE +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/docs/demo.svg +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/docs/launch-drafts.md +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/docs/mulaw-gotchas.md +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/examples/echo_agent.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/alias_bait_44k.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/long_8k.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/make_fixtures.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/make_speech.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/noisy_8k.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/partial_frame_8k.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/silence_8k.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_16k.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_44k_stereo.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_8k.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_8k_24bit.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_8k_32bit.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/speech_8k_8bit.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/fixtures/tone_440_8k.wav +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/scenarios/barge_in.yaml +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/scenarios/hangup.yaml +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/scenarios/no_input.yaml +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/skill/SKILL.md +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/audio.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/chaos.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/cli.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/g711.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/metrics.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/pacer.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/protocol.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/scenario.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/src/streamdouble/session.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/conftest.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/golden/frames.json +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_audio.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_chaos.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_cli.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_documented_commands.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_g711.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_golden.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_integration_echo.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_measurement_validity.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_metrics.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_pacer.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_protocol.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_review_gate_1.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_review_gate_2.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_review_gate_3.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_review_gate_4.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_scenario.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_scenario_execution.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_session.py +0 -0
- {streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/tests/test_signal_integrity.py +0 -0
- {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
|

|
|
42
42
|
|
|
43
|
-
> **Status:
|
|
44
|
-
>
|
|
45
|
-
>
|
|
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
|
|
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
|
|
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/
|
|
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:**
|
|
7
|
-
PyPI. Gate 5
|
|
8
|
-
|
|
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
|
-
- [
|
|
346
|
-
manual-dispatch with `publish: false` by default, so
|
|
347
|
-
|
|
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
|
|
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
|
-
- [
|
|
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
|

|
|
7
7
|
|
|
8
|
-
> **Status:
|
|
9
|
-
>
|
|
10
|
-
>
|
|
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
|
|
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
|
|
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/
|
|
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"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{streamdouble-0.1.0 → streamdouble-0.1.0.dev0}/.github/ISSUE_TEMPLATE/protocol-difference.yml
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
|
|
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
|
|
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
|