dv-pipecat-flows 0.0.0.dev2766__tar.gz → 0.0.0.dev2810__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.
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/AGENTS.md +17 -0
- {dv_pipecat_flows-0.0.0.dev2766/src/dv_pipecat_flows.egg-info → dv_pipecat_flows-0.0.0.dev2810}/PKG-INFO +1 -1
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810/src/dv_pipecat_flows.egg-info}/PKG-INFO +1 -1
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/dv_pipecat_flows.egg-info/scm_file_list.json +12 -2
- dv_pipecat_flows-0.0.0.dev2810/src/dv_pipecat_flows.egg-info/scm_version.json +8 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/manager.py +61 -21
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/processors/router_mode_guard.py +0 -11
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/processors/user_turn_observer.py +11 -32
- dv_pipecat_flows-0.0.0.dev2766/src/dv_pipecat_flows.egg-info/scm_version.json +0 -8
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.agents/skills/loki-logs/SKILL.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.agents/skills/loki-logs/query-reference.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.claude/skills/loki-logs/SKILL.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.claude/skills/loki-logs/query-reference.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.gitattributes +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.gitignore +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.pre-commit-config.yaml +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.python-version +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.readthedocs.yaml +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/CHANGELOG.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/CLAUDE.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/CONTRIBUTING.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/LICENSE +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/MANIFEST.in +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/README.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/.env.example +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/.gitignore +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/README.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/ARCHITECTURE.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/CODE_MAP.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/CONFIG.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/CONTRACTS.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/COPILOT_TODO.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/DISTRIBUTION.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/HLD.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/METHODS.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/VOICE_E2E.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/ANALYSIS_stagehand_vs_hybrid.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/RESULTS.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/_env.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/bench.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/bench_browseruse.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/bench_stagehand.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/inspect_browseruse.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/inspect_browseruse_showcase.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/inspect_stagehand_prompt.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/pages/checkout.html +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/pages/dashboard.html +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/pages/signup.html +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/results_browseruse.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/results_perception.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/results_stagehand.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/tasks.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/try_hybrid.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/try_hybrid_multistep.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/try_hybrid_oneshot.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/pyproject.toml +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/scripts/dev-stack.sh +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/uv.lock +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/dev-requirements.txt +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/docker-compose.dev.yml +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/.eslintrc.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/.prettierrc +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/css/tailwind.css +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/examples/food_ordering.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/examples/movie_explorer.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/examples/patient_intake.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/examples/restaurant_reservation.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/examples/travel_planner.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/favicon.png +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/favicon.svg +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/index.html +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/editor/canvas.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/editor/editorState.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/editor/sidePanel.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/editor/toolbar.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/main.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/baseNode.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/endNode.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/flowNode.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/functionNode.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/index.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/mergeNode.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/startNode.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/types.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/utils/export.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/utils/helpers.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/utils/import.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/utils/validation.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/jsdoc.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/package-lock.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/package.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/postcss.config.cjs +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/public/favicon.png +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/public/favicon.svg +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/tailwind.config.cjs +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/vercel.json +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/vite.config.js +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/engine_primitives_plan.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/env.example +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/images/food-ordering-flow.png +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/pipecat-flows.png +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/pipecat_upgrade.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/pyproject.toml +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/remote-asterisk-code/README.md +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/remote-asterisk-code/extensions.conf +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/remote-asterisk-code/rtp.conf +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/requirements.txt +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/scripts/azure_latency_probe.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/scripts/check-pypi-package.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/scripts/fix-ruff.sh +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/scripts/langfuse_export.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/scripts/pre-commit.sh +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/setup.cfg +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/dv_pipecat_flows.egg-info/SOURCES.txt +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/dv_pipecat_flows.egg-info/dependency_links.txt +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/dv_pipecat_flows.egg-info/requires.txt +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/dv_pipecat_flows.egg-info/top_level.txt +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/__init__.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/actions.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/adapters.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/condition_evaluator.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/exceptions.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/flow_validator.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/processors/__init__.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/processors/speak_interruption_guard.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/router_mode.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/types.py +0 -0
- {dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/uv.lock +0 -0
|
@@ -125,6 +125,23 @@ Example `call_config`:
|
|
|
125
125
|
- `tests/test_manager.py`, `tests/test_actions.py`, etc., cover FlowManager and ActionManager edge cases (context resets, action ordering, function registration). Extend these tests when adding new features.
|
|
126
126
|
- Logging: see the dedicated section below for Loguru usage and the custom logger configuration.
|
|
127
127
|
|
|
128
|
+
## Metrics & Observability
|
|
129
|
+
|
|
130
|
+
- **SDK**: `ringg-telemetry` (metrics-only facade over OpenTelemetry). Initialised once per process in the FastAPI lifespan — `ringg-bot/server.py` — gated on `ENABLE_METRICS`. Export path is OTLP/gRPC → the in-cluster `otel-gateway` → **Google Managed Prometheus**. Tracing is a *separate* stack (Langfuse, `ringg-bot/utils/tracing.py`); the two are unrelated.
|
|
131
|
+
- **Declare instruments in one place**: the registry block near the bottom of `ringg-bot/utils/metrics_collector.py`. Module-level handles (`ringg_metrics.histogram/counter/gauge`), created at import, resolved lazily. Keep the cardinality justification in a comment next to each — the `labels=(...)` tuple is a hard allowlist, and the SDK **silently drops** any label not in it.
|
|
132
|
+
- **Record from a lazily-importing, swallow-all helper** when the call site is on a per-turn hot path — see `_record_redis_latency` in `ringg-bot/ringg_processors/llm_cache.py` and `_record_router_metrics` in `ringg-bot/utils/language_detection.py`. Telemetry must never raise into a live call, and the import must not drag the metrics stack into eval scripts.
|
|
133
|
+
- **Names**: the SDK prefixes everything with `ringg.` and GMP rewrites it for PromQL — `ringg.language.router.duration` + `unit="s"` becomes `ringg_language_router_duration_seconds_{bucket,count,sum}`; a counter with `unit="1"` becomes `..._total`. A non-standard unit gets appended as a suffix, so use `"1"` even for money (put "USD" in the description).
|
|
134
|
+
- **Dashboards as code**: `k8s/monitoring/dashboards/` — one JSON per dashboard plus a README with the `gcloud monitoring dashboards create/update` commands and the assigned resource ids.
|
|
135
|
+
- **Tests**: `ringg_telemetry.testing.install_test_provider()` / `uninstall_test_provider()` route handles to an in-memory reader. See `ringg-bot/tests/test_metrics_bridge.py` and `tests/test_language_router_metrics.py`.
|
|
136
|
+
|
|
137
|
+
## Data Residency
|
|
138
|
+
|
|
139
|
+
- Some regions forbid their call data leaving regional storage. The single definition of that rule is `is_data_residency_restricted(region)` in `ringg-bot/utils/artifact_store.py` (currently `{"ksa"}`). **Consult it before any new write to the long-lived artifact bucket** — `RUNTIME_CONFIG_BUCKET` is US-located.
|
|
140
|
+
- Restricted regions **skip** the write entirely: there is no fallback bucket and no re-routing. Applies to the runtime-config snapshot, the tool-call snapshot and the language-router samples (`utils/generic_functions/cleanup.py`, `utils/language_sample_store.py`). The data still reaches the region's own backend via the `call_completion` POST, and transcripts/recordings still go to the regional bucket via `utils/transcript._get_gcs_bucket`.
|
|
141
|
+
- `region` is a **per-call** value (`RunConfig.region`, set by the backend), not a pod env var. On the two artifact uploaders it is keyword-only and *required* precisely so a new call site cannot become a violation by omission.
|
|
142
|
+
- Skipping the upload must not skip local cleanup: `LOCAL_STORAGE_DIR` is the pod's `/tmp` and the pod outlives thousands of calls, so anything buffered on disk still has to be unlinked on the skip path.
|
|
143
|
+
- Where feasible, gate at *capture* time too, not just upload time — e.g. `bot.py` passes `collect_samples=not is_data_residency_restricted(_region)` so raw user utterances are never written to `/tmp` for a restricted call.
|
|
144
|
+
|
|
128
145
|
## Logging
|
|
129
146
|
|
|
130
147
|
- We use Loguru for all application logging. Do not use the Python `logging` module in app code; always `from loguru import logger`.
|
|
@@ -211,6 +211,8 @@
|
|
|
211
211
|
"k8s/livekit/values-prod.yaml",
|
|
212
212
|
"k8s/livekit/values-stage.yaml",
|
|
213
213
|
"k8s/livekit/values.yaml",
|
|
214
|
+
"k8s/monitoring/dashboards/README.md",
|
|
215
|
+
"k8s/monitoring/dashboards/ringg-language-router.json",
|
|
214
216
|
"pipecat-flows.png",
|
|
215
217
|
"pipecat_upgrade.md",
|
|
216
218
|
"pyproject.toml",
|
|
@@ -357,8 +359,10 @@
|
|
|
357
359
|
"ringg-bot/test_bot.py",
|
|
358
360
|
"ringg-bot/tests/__init__.py",
|
|
359
361
|
"ringg-bot/tests/conftest.py",
|
|
362
|
+
"ringg-bot/tests/test_abandoned_call_report.py",
|
|
360
363
|
"ringg-bot/tests/test_action_call_variables.py",
|
|
361
364
|
"ringg-bot/tests/test_app_metrics.py",
|
|
365
|
+
"ringg-bot/tests/test_artifact_store.py",
|
|
362
366
|
"ringg-bot/tests/test_asterisk_ami_client.py",
|
|
363
367
|
"ringg-bot/tests/test_asterisk_ari_transfer_message.py",
|
|
364
368
|
"ringg-bot/tests/test_asterisk_v1_transfer_numbers.py",
|
|
@@ -380,6 +384,7 @@
|
|
|
380
384
|
"ringg-bot/tests/test_end_call_schema.py",
|
|
381
385
|
"ringg-bot/tests/test_env_config_asterisk_ami.py",
|
|
382
386
|
"ringg-bot/tests/test_execute_plan.py",
|
|
387
|
+
"ringg-bot/tests/test_find_button_api_config.py",
|
|
383
388
|
"ringg-bot/tests/test_flow_query_kb.py",
|
|
384
389
|
"ringg-bot/tests/test_gcs_fetch.py",
|
|
385
390
|
"ringg-bot/tests/test_http_client_diagnostics.py",
|
|
@@ -391,6 +396,7 @@
|
|
|
391
396
|
"ringg-bot/tests/test_job_reporting.py",
|
|
392
397
|
"ringg-bot/tests/test_kb_planner.py",
|
|
393
398
|
"ringg-bot/tests/test_language_map.py",
|
|
399
|
+
"ringg-bot/tests/test_language_router_metrics.py",
|
|
394
400
|
"ringg-bot/tests/test_language_sample_store.py",
|
|
395
401
|
"ringg-bot/tests/test_language_steering.py",
|
|
396
402
|
"ringg-bot/tests/test_llm_cache.py",
|
|
@@ -410,12 +416,15 @@
|
|
|
410
416
|
"ringg-bot/tests/test_on_call_sdk_context.py",
|
|
411
417
|
"ringg-bot/tests/test_ozonetel_inbound.py",
|
|
412
418
|
"ringg-bot/tests/test_ozonetel_transfer.py",
|
|
419
|
+
"ringg-bot/tests/test_rag_filter_operators.py",
|
|
420
|
+
"ringg-bot/tests/test_rag_filter_property_names.py",
|
|
413
421
|
"ringg-bot/tests/test_realtime_external_tts.py",
|
|
414
422
|
"ringg-bot/tests/test_recording_flush.py",
|
|
415
423
|
"ringg-bot/tests/test_recording_stereo.py",
|
|
416
424
|
"ringg-bot/tests/test_regression_monitor_sync.py",
|
|
417
425
|
"ringg-bot/tests/test_replay_kb_flag.py",
|
|
418
426
|
"ringg-bot/tests/test_runtime_config_language_normalization.py",
|
|
427
|
+
"ringg-bot/tests/test_runtime_config_upload.py",
|
|
419
428
|
"ringg-bot/tests/test_sdk_executor_flatten.py",
|
|
420
429
|
"ringg-bot/tests/test_sdk_tool_schema.py",
|
|
421
430
|
"ringg-bot/tests/test_send_blocks_calendar.py",
|
|
@@ -547,6 +556,7 @@
|
|
|
547
556
|
"ringg-bot/utils/tts.py",
|
|
548
557
|
"ringg-bot/utils/twilio_async_client.py",
|
|
549
558
|
"ringg-bot/utils/warning_messages.py",
|
|
559
|
+
"ringg-bot/utils/widget_transcript.py",
|
|
550
560
|
"ringg-bot/utils/word_timestamp_logger.py",
|
|
551
561
|
"ringg-bot/voice_services/asterisk/asterisk_service.py",
|
|
552
562
|
"ringg-bot/voice_services/asterisk/router.py",
|
|
@@ -625,6 +635,7 @@
|
|
|
625
635
|
"tests/test_condition_evaluator.py",
|
|
626
636
|
"tests/test_context_strategies.py",
|
|
627
637
|
"tests/test_credentials_resolver.py",
|
|
638
|
+
"tests/test_deployment_scaling_chart.py",
|
|
628
639
|
"tests/test_end_call_inactivity.py",
|
|
629
640
|
"tests/test_end_call_interruptible.py",
|
|
630
641
|
"tests/test_end_call_provider_dispatch.py",
|
|
@@ -639,10 +650,9 @@
|
|
|
639
650
|
"tests/test_openai_realtime_transcript_filter.py",
|
|
640
651
|
"tests/test_response_formatters.py",
|
|
641
652
|
"tests/test_router_extract_schema.py",
|
|
642
|
-
"tests/test_router_mode_guard.py",
|
|
643
653
|
"tests/test_router_no_unclear.py",
|
|
654
|
+
"tests/test_router_wait_idle.py",
|
|
644
655
|
"tests/test_tts_split_cache.py",
|
|
645
|
-
"tests/test_user_turn_observer.py",
|
|
646
656
|
"tests/test_voicemail_detector.py",
|
|
647
657
|
"uv.lock"
|
|
648
658
|
]
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/manager.py
RENAMED
|
@@ -1872,6 +1872,24 @@ In all of these cases, you can provide a `name` in your new node's config for de
|
|
|
1872
1872
|
label="jump",
|
|
1873
1873
|
)
|
|
1874
1874
|
|
|
1875
|
+
def _last_context_role(self) -> Optional[str]:
|
|
1876
|
+
"""Role of the last message in the live LLM context, or None when no
|
|
1877
|
+
context aggregator / empty context. Used by the router wait gate to
|
|
1878
|
+
tell a real committed user turn apart from system-generated context
|
|
1879
|
+
pushes (e.g. the idle warning's LLM-path append)."""
|
|
1880
|
+
if not self._context_aggregator:
|
|
1881
|
+
return None
|
|
1882
|
+
ctx = self._context_aggregator.user()._context
|
|
1883
|
+
messages = (
|
|
1884
|
+
ctx.get_messages() if hasattr(ctx, "get_messages") else getattr(ctx, "messages", [])
|
|
1885
|
+
)
|
|
1886
|
+
if not messages:
|
|
1887
|
+
return None
|
|
1888
|
+
last = messages[-1]
|
|
1889
|
+
if isinstance(last, dict):
|
|
1890
|
+
return last.get("role")
|
|
1891
|
+
return getattr(last, "role", None)
|
|
1892
|
+
|
|
1875
1893
|
async def _run_router_node(
|
|
1876
1894
|
self, node_id: str, node_config: Dict[str, Any]
|
|
1877
1895
|
) -> Optional[str]:
|
|
@@ -1905,10 +1923,19 @@ In all of these cases, you can provide a `name` in your new node's config for de
|
|
|
1905
1923
|
# `_run_router_node` captures a fresh entry_ts — the next iteration
|
|
1906
1924
|
# correctly waits for a NEW user reply instead of reclassifying the
|
|
1907
1925
|
# stale one that triggered the previous UNCLEAR.
|
|
1926
|
+
#
|
|
1927
|
+
# Silence handling is delegated to the user-idle processor: we re-arm
|
|
1928
|
+
# it for the duration of the wait (it was stopped at `_set_node`
|
|
1929
|
+
# entry) and block until the user actually replies. If they never do,
|
|
1930
|
+
# the idle processor's warning → end stages fire and end the call —
|
|
1931
|
+
# the router never classifies stale silence. The idle warning's
|
|
1932
|
+
# fixed-phrase TTSSpeakFrame passes RouterModeGuard; its LLM-path
|
|
1933
|
+
# fallback (realtime/chat-only/unsupported languages) is dropped by
|
|
1934
|
+
# the guard, so that warning is silent but the end stage still ends
|
|
1935
|
+
# the call.
|
|
1908
1936
|
observer = self._user_turn_observer
|
|
1909
1937
|
|
|
1910
|
-
|
|
1911
|
-
if observer is not None and timeout_s > 0:
|
|
1938
|
+
if observer is not None:
|
|
1912
1939
|
entry_ts = time.monotonic()
|
|
1913
1940
|
if observer.last_user_stopped_ts >= entry_ts:
|
|
1914
1941
|
logger.debug(
|
|
@@ -1929,28 +1956,41 @@ In all of these cases, you can provide a `name` in your new node's config for de
|
|
|
1929
1956
|
)
|
|
1930
1957
|
else:
|
|
1931
1958
|
logger.debug(
|
|
1932
|
-
f"Router '{node_id}': waiting
|
|
1933
|
-
f"UserStoppedSpeakingFrame"
|
|
1959
|
+
f"Router '{node_id}': waiting for "
|
|
1960
|
+
f"UserStoppedSpeakingFrame (idle processor armed)"
|
|
1934
1961
|
)
|
|
1962
|
+
await self._task.queue_frame(StartUserIdleProcessorFrame())
|
|
1935
1963
|
try:
|
|
1936
|
-
|
|
1937
|
-
observer.event.wait()
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1964
|
+
while True:
|
|
1965
|
+
await observer.event.wait()
|
|
1966
|
+
# The observer fires on EVERY OpenAILLMContextFrame,
|
|
1967
|
+
# and with idle armed there IS a competing source:
|
|
1968
|
+
# the idle warning's LLM path (chat-only sessions,
|
|
1969
|
+
# realtime LLMs) appends its prompt with
|
|
1970
|
+
# run_llm=True, which makes the user aggregator push
|
|
1971
|
+
# a context frame with NO new user turn. Accept the
|
|
1972
|
+
# wake only when the last context message is the
|
|
1973
|
+
# user's; otherwise keep waiting for the real reply
|
|
1974
|
+
# (or for idle end-stage to end the call).
|
|
1975
|
+
role = self._last_context_role()
|
|
1976
|
+
if role is None or role == "user":
|
|
1977
|
+
break
|
|
1978
|
+
logger.debug(
|
|
1979
|
+
f"Router '{node_id}': ignoring context push "
|
|
1980
|
+
f"with last role '{role}' (idle warning, not a "
|
|
1981
|
+
f"user reply); still waiting"
|
|
1982
|
+
)
|
|
1983
|
+
observer.event.clear()
|
|
1984
|
+
finally:
|
|
1985
|
+
# Restore the "idle stopped while the node is
|
|
1986
|
+
# processing" invariant for the classifier call.
|
|
1987
|
+
await self._task.queue_frame(
|
|
1988
|
+
StopUserIdleProcessorFrame()
|
|
1953
1989
|
)
|
|
1990
|
+
logger.debug(
|
|
1991
|
+
f"Router '{node_id}': user reply received after "
|
|
1992
|
+
f"{time.monotonic() - entry_ts:.2f}s"
|
|
1993
|
+
)
|
|
1954
1994
|
|
|
1955
1995
|
branches = node_config.get("router_branches") or []
|
|
1956
1996
|
extract = node_config.get("router_extract") or {}
|
|
@@ -48,7 +48,6 @@ from typing import Callable, Tuple, Type
|
|
|
48
48
|
|
|
49
49
|
from pipecat.frames.frames import (
|
|
50
50
|
Frame,
|
|
51
|
-
LLMContextFrame,
|
|
52
51
|
LLMMessagesFrame,
|
|
53
52
|
LLMRunFrame,
|
|
54
53
|
LLMTextFrame,
|
|
@@ -64,16 +63,6 @@ logger = logging.getLogger(__name__)
|
|
|
64
63
|
# race-free fix for the spurious-bot-text problem.
|
|
65
64
|
_TRIGGER_FRAME_TYPES: Tuple[Type[Frame], ...] = (
|
|
66
65
|
OpenAILLMContextFrame,
|
|
67
|
-
# Universal context frame. `LLMContextFrame` and `OpenAILLMContextFrame` are
|
|
68
|
-
# SIBLINGS (both extend Frame directly), so matching one does NOT match the
|
|
69
|
-
# other — both must be listed. The pipeline picks between them from a single
|
|
70
|
-
# switch in the bot: `context = LLMContext() if (_use_responses or
|
|
71
|
-
# _use_universal_for_google) else OpenAILLMContext()`. Omitting this one let
|
|
72
|
-
# the LLM fire during router-mode nodes on every Responses-API agent
|
|
73
|
-
# (gpt-5.4-mini/nano are forced onto Responses regardless of the
|
|
74
|
-
# `use_responses_api` toggle) and every google/gemma agent — the bot spoke
|
|
75
|
-
# spurious freeform text instead of routing silently.
|
|
76
|
-
LLMContextFrame,
|
|
77
66
|
LLMMessagesFrame,
|
|
78
67
|
LLMRunFrame,
|
|
79
68
|
)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""Observer that timestamps
|
|
2
|
-
(:class:`OpenAILLMContextFrame` **or** :class:`LLMContextFrame`) so router-mode
|
|
1
|
+
"""Observer that timestamps :class:`OpenAILLMContextFrame` so router-mode
|
|
3
2
|
nodes can detect "user turn is now committed to context" without reaching
|
|
4
3
|
into the user context aggregator's private state.
|
|
5
4
|
|
|
@@ -8,27 +7,22 @@ Why an observer, not a FrameProcessor:
|
|
|
8
7
|
public ``PipelineTask.add_observer`` API.
|
|
9
8
|
* We only need a passive timestamp + an ``asyncio.Event`` — no frame routing.
|
|
10
9
|
|
|
11
|
-
Why
|
|
10
|
+
Why ``OpenAILLMContextFrame`` and not ``UserStoppedSpeakingFrame``:
|
|
12
11
|
* ``UserStoppedSpeakingFrame`` is raw VAD — it fires the instant the mic
|
|
13
12
|
detects silence, BEFORE the STT final lands and BEFORE the user-context
|
|
14
13
|
aggregator appends the turn. Router gates that release on this signal
|
|
15
14
|
classify against an empty/stale context.
|
|
16
|
-
*
|
|
15
|
+
* ``OpenAILLMContextFrame`` is pushed by ``LLMUserContextAggregator``
|
|
17
16
|
(``llm_response._process_aggregation``) only AFTER the final transcript
|
|
18
17
|
is appended to the LLM context. It is the canonical "user turn is now
|
|
19
18
|
in the context the router will read" event.
|
|
20
19
|
* Router-mode never queues ``LLMRunFrame`` for the router node itself, so
|
|
21
|
-
the only
|
|
22
|
-
the aggregator's turn-complete path — no competing source.
|
|
23
|
-
|
|
24
|
-
BOTH context-frame flavours must be matched (see
|
|
25
|
-
``_USER_TURN_COMMITTED_FRAME_TYPES``): the aggregator emits
|
|
26
|
-
``LLMContextFrame`` on the Responses-API / google / gemma paths and
|
|
27
|
-
``OpenAILLMContextFrame`` on the Chat Completions path.
|
|
20
|
+
the only ``OpenAILLMContextFrame`` produced during a router invocation
|
|
21
|
+
comes from the aggregator's turn-complete path — no competing source.
|
|
28
22
|
|
|
29
23
|
State exposed:
|
|
30
24
|
* ``last_user_context_pushed_ts``: monotonic time of the latest
|
|
31
|
-
|
|
25
|
+
``OpenAILLMContextFrame`` (user turn committed to context).
|
|
32
26
|
* ``last_user_stopped_ts``: backwards-compatible alias kept in sync with
|
|
33
27
|
``last_user_context_pushed_ts`` so existing callers keep working.
|
|
34
28
|
* ``event``: ``asyncio.Event`` set on every such frame; the consumer is
|
|
@@ -44,41 +38,26 @@ from typing import List, Tuple
|
|
|
44
38
|
|
|
45
39
|
from pipecat.frames.frames import (
|
|
46
40
|
InterimTranscriptionFrame,
|
|
47
|
-
LLMContextFrame,
|
|
48
41
|
TranscriptionFrame,
|
|
49
42
|
UserStartedSpeakingFrame,
|
|
50
43
|
)
|
|
51
44
|
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContextFrame
|
|
52
45
|
from pipecat.observers.base_observer import BaseObserver, FramePushed
|
|
53
46
|
|
|
54
|
-
# Both context-frame flavours mean the same thing here: "the user's turn is now
|
|
55
|
-
# committed to the context the router will read". Which one the aggregator emits
|
|
56
|
-
# is decided by one switch in the bot:
|
|
57
|
-
#
|
|
58
|
-
# context = LLMContext() if (_use_responses or _use_universal_for_google)
|
|
59
|
-
# else OpenAILLMContext()
|
|
60
|
-
#
|
|
61
|
-
# They are SIBLINGS (both extend Frame directly, neither subclasses the other),
|
|
62
|
-
# so matching one does NOT match the other. Keying on only OpenAILLMContextFrame
|
|
63
|
-
# left every Responses-API / google / gemma agent's router waiting the full
|
|
64
|
-
# ``router_wait_for_user_timeout`` (15s) after the caller had already replied.
|
|
65
|
-
_USER_TURN_COMMITTED_FRAME_TYPES = (OpenAILLMContextFrame, LLMContextFrame)
|
|
66
|
-
|
|
67
47
|
# Bound the per-call transcript log so a very long call can't grow it without
|
|
68
48
|
# limit; far more than any single Collect dictation needs.
|
|
69
49
|
_MAX_TRANSCRIPT_LOG = 256
|
|
70
50
|
|
|
71
51
|
|
|
72
52
|
class UserTurnObserver(BaseObserver):
|
|
73
|
-
"""Tracks the timestamp of the most recent
|
|
53
|
+
"""Tracks the timestamp of the most recent ``OpenAILLMContextFrame``.
|
|
74
54
|
|
|
75
55
|
Router-mode uses this to (a) detect a user reply already committed to
|
|
76
56
|
context BEFORE the router was entered (barge-in during the preceding
|
|
77
57
|
Speak's TTS) and (b) await the NEXT user reply when none is available.
|
|
78
58
|
|
|
79
|
-
The observer is keyed on
|
|
80
|
-
``
|
|
81
|
-
``UserStoppedSpeakingFrame`` because only the former guarantees the
|
|
59
|
+
The observer is keyed on ``OpenAILLMContextFrame`` rather than the raw
|
|
60
|
+
VAD ``UserStoppedSpeakingFrame`` because only the former guarantees the
|
|
82
61
|
user's transcript has been appended to the LLM context the router reads.
|
|
83
62
|
"""
|
|
84
63
|
|
|
@@ -114,7 +93,7 @@ class UserTurnObserver(BaseObserver):
|
|
|
114
93
|
|
|
115
94
|
@property
|
|
116
95
|
def event(self) -> asyncio.Event:
|
|
117
|
-
"""The asyncio.Event set on each
|
|
96
|
+
"""The asyncio.Event set on each ``OpenAILLMContextFrame``.
|
|
118
97
|
|
|
119
98
|
Callers MUST ``.clear()`` before awaiting if they want to wait for the
|
|
120
99
|
NEXT frame (vs. immediately returning on a stale set state).
|
|
@@ -122,7 +101,7 @@ class UserTurnObserver(BaseObserver):
|
|
|
122
101
|
return self._event
|
|
123
102
|
|
|
124
103
|
async def on_push_frame(self, data: FramePushed) -> None:
|
|
125
|
-
if isinstance(data.frame,
|
|
104
|
+
if isinstance(data.frame, OpenAILLMContextFrame):
|
|
126
105
|
now = time.monotonic()
|
|
127
106
|
self.last_user_context_pushed_ts = now
|
|
128
107
|
self.last_user_stopped_ts = now
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.agents/skills/loki-logs/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/.claude/skills/loki-logs/SKILL.md
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
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/.env.example
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/.gitignore
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/CODE_MAP.md
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/CONFIG.md
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/CONTRACTS.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/HLD.md
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/METHODS.md
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/docs/VOICE_E2E.md
RENAMED
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/RESULTS.md
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/_env.py
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/bench.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
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/tasks.py
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/eval/try_hybrid.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/browser_copilot/pyproject.toml
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
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/examples/food_ordering.json
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
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/editor/canvas.js
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/editor/editorState.js
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/editor/sidePanel.js
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/editor/toolbar.js
RENAMED
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/baseNode.js
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/endNode.js
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/flowNode.js
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/functionNode.js
RENAMED
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/mergeNode.js
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/nodes/startNode.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/utils/helpers.js
RENAMED
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/js/utils/validation.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/editor/tailwind.config.cjs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/images/food-ordering-flow.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/remote-asterisk-code/README.md
RENAMED
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/remote-asterisk-code/rtp.conf
RENAMED
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/scripts/azure_latency_probe.py
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/scripts/check-pypi-package.py
RENAMED
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/scripts/langfuse_export.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/__init__.py
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/actions.py
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/adapters.py
RENAMED
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/router_mode.py
RENAMED
|
File without changes
|
{dv_pipecat_flows-0.0.0.dev2766 → dv_pipecat_flows-0.0.0.dev2810}/src/pipecat_flows/types.py
RENAMED
|
File without changes
|
|
File without changes
|