openrtc 0.2.3__tar.gz → 0.3.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.
Files changed (157) hide show
  1. {openrtc-0.2.3 → openrtc-0.3.0}/PKG-INFO +22 -1
  2. {openrtc-0.2.3 → openrtc-0.3.0}/README.md +21 -0
  3. {openrtc-0.2.3 → openrtc-0.3.0}/docs/changelog.md +17 -1
  4. openrtc-0.3.0/docs/superpowers/plans/2026-06-08-session-observer-protocol.md +954 -0
  5. openrtc-0.3.0/docs/superpowers/specs/2026-06-08-session-observer-protocol-design.md +252 -0
  6. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/__init__.py +10 -0
  7. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/core/pool.py +63 -2
  8. openrtc-0.3.0/src/openrtc/observability/__init__.py +13 -0
  9. openrtc-0.3.0/src/openrtc/observability/observer.py +224 -0
  10. openrtc-0.3.0/tests/test_session_observer.py +421 -0
  11. openrtc-0.2.3/tests/integration/__init__.py +0 -0
  12. {openrtc-0.2.3 → openrtc-0.3.0}/.coderabbit.yaml +0 -0
  13. {openrtc-0.2.3 → openrtc-0.3.0}/.editorconfig +0 -0
  14. {openrtc-0.2.3 → openrtc-0.3.0}/.env.example +0 -0
  15. {openrtc-0.2.3 → openrtc-0.3.0}/.github/FUNDING.yml +0 -0
  16. {openrtc-0.2.3 → openrtc-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  17. {openrtc-0.2.3 → openrtc-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  18. {openrtc-0.2.3 → openrtc-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  19. {openrtc-0.2.3 → openrtc-0.3.0}/.github/dependabot.yml +0 -0
  20. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/audit.yml +0 -0
  21. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/bench.yml +0 -0
  22. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/build.yml +0 -0
  23. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/canary.yml +0 -0
  24. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/deploy-docs.yml +0 -0
  25. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/docs.yml +0 -0
  26. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/integration.yml +0 -0
  27. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/lint.yml +0 -0
  28. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/publish.yml +0 -0
  29. {openrtc-0.2.3 → openrtc-0.3.0}/.github/workflows/test.yml +0 -0
  30. {openrtc-0.2.3 → openrtc-0.3.0}/.gitignore +0 -0
  31. {openrtc-0.2.3 → openrtc-0.3.0}/.pre-commit-config.yaml +0 -0
  32. {openrtc-0.2.3 → openrtc-0.3.0}/AGENTS.md +0 -0
  33. {openrtc-0.2.3 → openrtc-0.3.0}/CLAUDE.md +0 -0
  34. {openrtc-0.2.3 → openrtc-0.3.0}/CONTRIBUTING.md +0 -0
  35. {openrtc-0.2.3 → openrtc-0.3.0}/LICENSE +0 -0
  36. {openrtc-0.2.3 → openrtc-0.3.0}/Makefile +0 -0
  37. {openrtc-0.2.3 → openrtc-0.3.0}/assets/banner.png +0 -0
  38. {openrtc-0.2.3 → openrtc-0.3.0}/assets/logo.png +0 -0
  39. {openrtc-0.2.3 → openrtc-0.3.0}/codecov.yml +0 -0
  40. {openrtc-0.2.3 → openrtc-0.3.0}/docker-compose.test.yml +0 -0
  41. {openrtc-0.2.3 → openrtc-0.3.0}/docs/.vitepress/config.ts +0 -0
  42. {openrtc-0.2.3 → openrtc-0.3.0}/docs/.vitepress/theme/custom.css +0 -0
  43. {openrtc-0.2.3 → openrtc-0.3.0}/docs/.vitepress/theme/index.ts +0 -0
  44. {openrtc-0.2.3 → openrtc-0.3.0}/docs/api/pool.md +0 -0
  45. {openrtc-0.2.3 → openrtc-0.3.0}/docs/audit-2026-05-02.md +0 -0
  46. {openrtc-0.2.3 → openrtc-0.3.0}/docs/benchmarks/density-v0.1.md +0 -0
  47. {openrtc-0.2.3 → openrtc-0.3.0}/docs/cli.md +0 -0
  48. {openrtc-0.2.3 → openrtc-0.3.0}/docs/concepts/architecture.md +0 -0
  49. {openrtc-0.2.3 → openrtc-0.3.0}/docs/deployment/github-pages.md +0 -0
  50. {openrtc-0.2.3 → openrtc-0.3.0}/docs/design/agent-server-integration.md +0 -0
  51. {openrtc-0.2.3 → openrtc-0.3.0}/docs/design/job-executor-protocol.md +0 -0
  52. {openrtc-0.2.3 → openrtc-0.3.0}/docs/design/proc-pool-surface.md +0 -0
  53. {openrtc-0.2.3 → openrtc-0.3.0}/docs/design/v0.1.md +0 -0
  54. {openrtc-0.2.3 → openrtc-0.3.0}/docs/examples.md +0 -0
  55. {openrtc-0.2.3 → openrtc-0.3.0}/docs/getting-started.md +0 -0
  56. {openrtc-0.2.3 → openrtc-0.3.0}/docs/index.md +0 -0
  57. {openrtc-0.2.3 → openrtc-0.3.0}/docs/package-lock.json +0 -0
  58. {openrtc-0.2.3 → openrtc-0.3.0}/docs/package.json +0 -0
  59. {openrtc-0.2.3 → openrtc-0.3.0}/docs/public/banner.png +0 -0
  60. {openrtc-0.2.3 → openrtc-0.3.0}/docs/public/logo.png +0 -0
  61. {openrtc-0.2.3 → openrtc-0.3.0}/docs/public/logo.svg +0 -0
  62. {openrtc-0.2.3 → openrtc-0.3.0}/docs/release-v0.1.md +0 -0
  63. {openrtc-0.2.3 → openrtc-0.3.0}/examples/agents/dental.py +0 -0
  64. {openrtc-0.2.3 → openrtc-0.3.0}/examples/agents/restaurant.py +0 -0
  65. {openrtc-0.2.3 → openrtc-0.3.0}/examples/density_demo.py +0 -0
  66. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/.dockerignore +0 -0
  67. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/.env.example +0 -0
  68. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/.gitignore +0 -0
  69. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/Dockerfile +0 -0
  70. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/README.md +0 -0
  71. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/app.css +0 -0
  72. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/components/agents-ui/agent-audio-visualizer-wave.tsx +0 -0
  73. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/components/agents-ui/agent-chat-transcript.tsx +0 -0
  74. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/components/agents-ui/agent-session-provider.tsx +0 -0
  75. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/components/demo-call-page.tsx +0 -0
  76. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/root.tsx +0 -0
  77. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/routes/api.token.ts +0 -0
  78. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/routes/dentist.tsx +0 -0
  79. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/routes/home.tsx +0 -0
  80. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/routes/restaurant.tsx +0 -0
  81. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/routes.ts +0 -0
  82. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/welcome/logo-dark.svg +0 -0
  83. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/welcome/logo-light.svg +0 -0
  84. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/app/welcome/welcome.tsx +0 -0
  85. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/package-lock.json +0 -0
  86. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/package.json +0 -0
  87. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/public/favicon.ico +0 -0
  88. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/react-router.config.ts +0 -0
  89. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/tsconfig.json +0 -0
  90. {openrtc-0.2.3 → openrtc-0.3.0}/examples/frontend/vite.config.ts +0 -0
  91. {openrtc-0.2.3 → openrtc-0.3.0}/examples/main.py +0 -0
  92. {openrtc-0.2.3 → openrtc-0.3.0}/pyproject.toml +0 -0
  93. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/cli/__init__.py +0 -0
  94. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/cli/commands.py +0 -0
  95. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/cli/dashboard.py +0 -0
  96. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/cli/entry.py +0 -0
  97. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/cli/livekit.py +0 -0
  98. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/cli/params.py +0 -0
  99. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/cli/reporter.py +0 -0
  100. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/cli/types.py +0 -0
  101. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/core/__init__.py +0 -0
  102. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/core/config.py +0 -0
  103. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/core/discovery.py +0 -0
  104. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/core/routing.py +0 -0
  105. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/core/serialization.py +0 -0
  106. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/core/turn_handling.py +0 -0
  107. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/execution/__init__.py +0 -0
  108. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/execution/coroutine.py +0 -0
  109. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/execution/coroutine_server.py +0 -0
  110. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/execution/file_watcher.py +0 -0
  111. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/execution/prewarm.py +0 -0
  112. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/observability/metrics.py +0 -0
  113. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/observability/snapshot.py +0 -0
  114. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/observability/stream.py +0 -0
  115. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/py.typed +0 -0
  116. {openrtc-0.2.3/src/openrtc/observability → openrtc-0.3.0/src/openrtc/tui}/__init__.py +0 -0
  117. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/tui/app.py +0 -0
  118. {openrtc-0.2.3 → openrtc-0.3.0}/src/openrtc/types.py +0 -0
  119. {openrtc-0.2.3/src/openrtc/tui → openrtc-0.3.0/tests/benchmarks}/__init__.py +0 -0
  120. {openrtc-0.2.3 → openrtc-0.3.0}/tests/benchmarks/density.py +0 -0
  121. {openrtc-0.2.3 → openrtc-0.3.0}/tests/benchmarks/throughput.py +0 -0
  122. {openrtc-0.2.3 → openrtc-0.3.0}/tests/conftest.py +0 -0
  123. {openrtc-0.2.3/tests/benchmarks → openrtc-0.3.0/tests/execution}/__init__.py +0 -0
  124. {openrtc-0.2.3 → openrtc-0.3.0}/tests/execution/test_file_watcher.py +0 -0
  125. {openrtc-0.2.3 → openrtc-0.3.0}/tests/execution/test_file_watcher_smoke.py +0 -0
  126. {openrtc-0.2.3 → openrtc-0.3.0}/tests/integration/README.md +0 -0
  127. {openrtc-0.2.3/tests/execution → openrtc-0.3.0/tests/integration}/__init__.py +0 -0
  128. {openrtc-0.2.3 → openrtc-0.3.0}/tests/integration/conftest.py +0 -0
  129. {openrtc-0.2.3 → openrtc-0.3.0}/tests/integration/test_concurrent_real_calls.py +0 -0
  130. {openrtc-0.2.3 → openrtc-0.3.0}/tests/integration/test_coroutine_realroom.py +0 -0
  131. {openrtc-0.2.3 → openrtc-0.3.0}/tests/integration/test_dev_server_fixture.py +0 -0
  132. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_cli.py +0 -0
  133. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_cli_optional_extra_integration.py +0 -0
  134. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_cli_params.py +0 -0
  135. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_config.py +0 -0
  136. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_coroutine_backpressure.py +0 -0
  137. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_coroutine_coverage.py +0 -0
  138. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_coroutine_drain.py +0 -0
  139. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_coroutine_isolation.py +0 -0
  140. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_coroutine_job_context.py +0 -0
  141. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_coroutine_lifecycle.py +0 -0
  142. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_coroutine_server.py +0 -0
  143. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_coroutine_skeleton.py +0 -0
  144. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_coroutine_smoke.py +0 -0
  145. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_dashboard.py +0 -0
  146. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_discovery.py +0 -0
  147. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_isolation_process_parity.py +0 -0
  148. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_metrics_stream.py +0 -0
  149. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_pool.py +0 -0
  150. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_resources.py +0 -0
  151. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_routing.py +0 -0
  152. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_savings_readout.py +0 -0
  153. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_serialization.py +0 -0
  154. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_throughput_bench.py +0 -0
  155. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_tui_app.py +0 -0
  156. {openrtc-0.2.3 → openrtc-0.3.0}/tests/test_turn_handling.py +0 -0
  157. {openrtc-0.2.3 → openrtc-0.3.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openrtc
3
- Version: 0.2.3
3
+ Version: 0.3.0
4
4
  Summary: Run multiple LiveKit voice agents in a single shared worker process.
5
5
  Project-URL: Homepage, https://github.com/mahimailabs/openrtc
6
6
  Project-URL: Repository, https://github.com/mahimailabs/openrtc
@@ -443,6 +443,27 @@ Pass instantiated provider objects through to `livekit-agents` unchanged, for ex
443
443
 
444
444
  If you pass strings such as `openai/gpt-4.1-mini`, OpenRTC leaves them as-is and the LiveKit runtime interprets them for your deployment.
445
445
 
446
+ ## Session observers
447
+
448
+ Attach external telemetry to every session without subclassing or touching OpenRTC internals. Any object with two async methods is a `SessionObserver` (structural typing, no base class):
449
+
450
+ ```python
451
+ from openrtc import AgentPool, SessionInfo, SessionOutcome
452
+
453
+
454
+ class LoggingObserver:
455
+ async def on_session_start(self, info: SessionInfo, session: object) -> None:
456
+ print(f"live: {info.agent_name} in {info.room_name}")
457
+
458
+ async def on_session_end(self, info: SessionInfo, outcome: SessionOutcome) -> None:
459
+ print(f"done: {info.agent_name} -> {outcome.status.value}")
460
+
461
+
462
+ pool = AgentPool(observers=[LoggingObserver()]) # or pool.add_observer(...)
463
+ ```
464
+
465
+ `on_session_start` receives the live `AgentSession`, which is where you subscribe to its metrics. `on_session_end` receives the terminal outcome (`SUCCESS`, `FAILED`, or `CANCELLED`). Observer calls are isolated: a raising or slow observer is logged and skipped, never crashing the session. In `process` isolation mode an observer must be picklable, so build live resources lazily on the first `on_session_start`.
466
+
446
467
  ## CLI and TUI
447
468
 
448
469
  Install `openrtc[cli]` to get `openrtc` on your PATH. Subcommands follow the LiveKit Agents CLI shape (`dev`, `start`, `console`, `connect`, `download-files`), plus `list` and `tui`. For most commands you can pass the agents directory (or, for `tui`, the metrics JSONL file) as the first path argument instead of `--agents-dir` / `--watch`.
@@ -411,6 +411,27 @@ Pass instantiated provider objects through to `livekit-agents` unchanged, for ex
411
411
 
412
412
  If you pass strings such as `openai/gpt-4.1-mini`, OpenRTC leaves them as-is and the LiveKit runtime interprets them for your deployment.
413
413
 
414
+ ## Session observers
415
+
416
+ Attach external telemetry to every session without subclassing or touching OpenRTC internals. Any object with two async methods is a `SessionObserver` (structural typing, no base class):
417
+
418
+ ```python
419
+ from openrtc import AgentPool, SessionInfo, SessionOutcome
420
+
421
+
422
+ class LoggingObserver:
423
+ async def on_session_start(self, info: SessionInfo, session: object) -> None:
424
+ print(f"live: {info.agent_name} in {info.room_name}")
425
+
426
+ async def on_session_end(self, info: SessionInfo, outcome: SessionOutcome) -> None:
427
+ print(f"done: {info.agent_name} -> {outcome.status.value}")
428
+
429
+
430
+ pool = AgentPool(observers=[LoggingObserver()]) # or pool.add_observer(...)
431
+ ```
432
+
433
+ `on_session_start` receives the live `AgentSession`, which is where you subscribe to its metrics. `on_session_end` receives the terminal outcome (`SUCCESS`, `FAILED`, or `CANCELLED`). Observer calls are isolated: a raising or slow observer is logged and skipped, never crashing the session. In `process` isolation mode an observer must be picklable, so build live resources lazily on the first `on_session_start`.
434
+
414
435
  ## CLI and TUI
415
436
 
416
437
  Install `openrtc[cli]` to get `openrtc` on your PATH. Subcommands follow the LiveKit Agents CLI shape (`dev`, `start`, `console`, `connect`, `download-files`), plus `list` and `tui`. For most commands you can pass the agents directory (or, for `tui`, the metrics JSONL file) as the first path argument instead of `--agents-dir` / `--watch`.
@@ -59,6 +59,14 @@ Changes that have landed on `main` but have not yet been tagged for release.
59
59
  `livekit-agents` and is allowed to fail.
60
60
  - New `docker-compose.test.yml` + `tests/integration/conftest.py`
61
61
  fixture harness for local and CI integration runs.
62
+ - Public `SessionObserver` protocol (`openrtc.SessionObserver`,
63
+ `SessionInfo`, `SessionOutcome`, `SessionStatus`) plus
64
+ `AgentPool(observers=[...])` and `AgentPool.add_observer(...)`. External
65
+ telemetry attaches to each live session through the pool:
66
+ `on_session_start` hands the live `AgentSession`, `on_session_end` the
67
+ terminal outcome. Observer faults are isolated (logged and skipped,
68
+ bounded by a timeout) and never crash the session. Additive and backward
69
+ compatible; the built-in metrics store is unchanged.
62
70
 
63
71
  **Changed**
64
72
 
@@ -147,6 +155,14 @@ contributor onboarding matches what's in the repo.
147
155
 
148
156
  <!-- releases -->
149
157
 
158
+ ## [0.2.3] - 2026-05-30
159
+
160
+ ### Added
161
+ - Day-one savings readout: each worker logs the fleet-collapse idle-baseline memory saved (N agents in one shared-prewarm worker vs N separate livekit-agents workers) once at startup, for both `pool.run()` and `openrtc dev/start`, with no `--dashboard` flag. The line claims only idle baseline saved (not per-session density), stays neutral for a single agent, degrades gracefully when RSS is unavailable, and names its equal-baseline assumption.
162
+ - README: a one-screen "Migrating from livekit-agents" recipe (N per-agent workers to one AgentPool).
163
+
164
+ ---
165
+
150
166
  ## [0.2.2] - 2026-05-30
151
167
 
152
168
  ### Fixed
@@ -177,7 +193,7 @@ contributor onboarding matches what's in the repo.
177
193
  ## What's Changed
178
194
  * Feat: light websocket by @mahimairaja in https://github.com/mahimailabs/openrtc-runtime/pull/30
179
195
  * docs: bring docs/ in sync with v0.1 surface by @mahimairaja in https://github.com/mahimailabs/openrtc-runtime/pull/35
180
- * Feat: struc refac by @mahimairaja in https://github.com/mahimailabs/openrtc-runtime/pull/36
196
+ * Feat: structural refactor by @mahimairaja in https://github.com/mahimailabs/openrtc-runtime/pull/36
181
197
  * Feat/coroutine pool by @mahimairaja in https://github.com/mahimailabs/openrtc-runtime/pull/37
182
198
  * Feat/coroutine pool prod by @mahimairaja in https://github.com/mahimailabs/openrtc-runtime/pull/38
183
199