dv-pipecat-flows 0.0.23.dev12__tar.gz → 0.0.26.dev145__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.26.dev145/.agents/skills/pipecat-logs/SKILL.md +237 -0
- dv_pipecat_flows-0.0.26.dev145/.agents/skills/pipecat-logs/query-reference.md +165 -0
- dv_pipecat_flows-0.0.26.dev145/.claude/skills/pipecat-logs/SKILL.md +237 -0
- dv_pipecat_flows-0.0.26.dev145/.claude/skills/pipecat-logs/query-reference.md +165 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/.gitignore +0 -2
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/AGENTS.md +31 -3
- {dv_pipecat_flows-0.0.23.dev12/src/dv_pipecat_flows.egg-info → dv_pipecat_flows-0.0.26.dev145}/PKG-INFO +1 -1
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/pyproject.toml +4 -0
- dv_pipecat_flows-0.0.26.dev145/scripts/build_uae_pipecat_secret_blob.py +315 -0
- dv_pipecat_flows-0.0.26.dev145/scripts/check-ar-package.py +103 -0
- dv_pipecat_flows-0.0.26.dev145/scripts/test_build_uae_pipecat_secret_blob.py +86 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145/src/dv_pipecat_flows.egg-info}/PKG-INFO +1 -1
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/dv_pipecat_flows.egg-info/SOURCES.txt +7 -7
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/dv_pipecat_flows.egg-info/scm_file_list.json +219 -6
- dv_pipecat_flows-0.0.26.dev145/src/dv_pipecat_flows.egg-info/scm_version.json +8 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/exceptions.py +19 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/manager.py +868 -56
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/processors/user_turn_observer.py +148 -1
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/types.py +13 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/uv.lock +2 -0
- dv_pipecat_flows-0.0.23.dev12/.agents/skills/loki-logs/SKILL.md +0 -121
- dv_pipecat_flows-0.0.23.dev12/.agents/skills/loki-logs/query-reference.md +0 -113
- dv_pipecat_flows-0.0.23.dev12/.claude/skills/loki-logs/SKILL.md +0 -121
- dv_pipecat_flows-0.0.23.dev12/.claude/skills/loki-logs/query-reference.md +0 -113
- dv_pipecat_flows-0.0.23.dev12/scripts/azure_latency_probe.py +0 -220
- dv_pipecat_flows-0.0.23.dev12/scripts/check-pypi-package.py +0 -27
- dv_pipecat_flows-0.0.23.dev12/scripts/langfuse_export.py +0 -321
- dv_pipecat_flows-0.0.23.dev12/src/dv_pipecat_flows.egg-info/scm_version.json +0 -8
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/.gitattributes +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/.pre-commit-config.yaml +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/.python-version +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/.readthedocs.yaml +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/CHANGELOG.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/CLAUDE.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/CONTRIBUTING.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/LICENSE +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/MANIFEST.in +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/README.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/.env.example +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/.gitignore +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/README.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/docs/ARCHITECTURE.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/docs/CODE_MAP.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/docs/CONFIG.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/docs/CONTRACTS.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/docs/COPILOT_TODO.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/docs/DISTRIBUTION.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/docs/HLD.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/docs/METHODS.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/docs/VOICE_E2E.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/ANALYSIS_stagehand_vs_hybrid.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/RESULTS.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/_env.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/bench.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/bench_browseruse.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/bench_stagehand.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/inspect_browseruse.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/inspect_browseruse_showcase.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/inspect_stagehand_prompt.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/pages/checkout.html +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/pages/dashboard.html +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/pages/signup.html +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/results_browseruse.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/results_perception.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/results_stagehand.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/tasks.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/try_hybrid.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/try_hybrid_multistep.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/eval/try_hybrid_oneshot.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/pyproject.toml +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/scripts/dev-stack.sh +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/browser_copilot/uv.lock +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/dev-requirements.txt +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/docker-compose.dev.yml +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/.eslintrc.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/.prettierrc +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/css/tailwind.css +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/examples/food_ordering.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/examples/movie_explorer.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/examples/patient_intake.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/examples/restaurant_reservation.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/examples/travel_planner.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/favicon.png +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/favicon.svg +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/index.html +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/editor/canvas.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/editor/editorState.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/editor/sidePanel.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/editor/toolbar.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/main.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/nodes/baseNode.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/nodes/endNode.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/nodes/flowNode.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/nodes/functionNode.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/nodes/index.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/nodes/mergeNode.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/nodes/startNode.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/types.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/utils/export.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/utils/helpers.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/utils/import.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/js/utils/validation.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/jsdoc.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/package-lock.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/package.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/postcss.config.cjs +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/public/favicon.png +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/public/favicon.svg +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/tailwind.config.cjs +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/vercel.json +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/editor/vite.config.js +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/engine_primitives_plan.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/env.example +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/images/food-ordering-flow.png +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/pipecat-flows.png +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/pipecat_upgrade.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/remote-asterisk-code/README.md +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/remote-asterisk-code/extensions.conf +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/remote-asterisk-code/rtp.conf +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/requirements.txt +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/scripts/fix-ruff.sh +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/scripts/pre-commit.sh +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/setup.cfg +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/dv_pipecat_flows.egg-info/dependency_links.txt +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/dv_pipecat_flows.egg-info/requires.txt +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/dv_pipecat_flows.egg-info/top_level.txt +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/__init__.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/actions.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/adapters.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/condition_evaluator.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/flow_validator.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/processors/__init__.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/processors/router_mode_guard.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/processors/speak_interruption_guard.py +0 -0
- {dv_pipecat_flows-0.0.23.dev12 → dv_pipecat_flows-0.0.26.dev145}/src/pipecat_flows/router_mode.py +0 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pipecat-logs
|
|
3
|
+
description: Fetch and analyze pipecat application logs from VictoriaLogs by call ID or call SID. Use when debugging call issues, investigating errors, or analyzing bot behavior for a specific call. Accepts any call identifier — the Ringg call id, a provider-native id, a telephony provider UUID, or an Asterisk sid (the last two are resolved first) — and optional environment (staging/production).
|
|
4
|
+
argument-hint: <call_id|call_sid> [staging|production]
|
|
5
|
+
allowed-tools: Bash(curl *), Bash(jq *), Bash(kubectl *), Bash(pkill *)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Pipecat Logs Fetcher
|
|
9
|
+
|
|
10
|
+
Fetch logs from **VictoriaLogs** for a specific pipecat call and analyze them.
|
|
11
|
+
|
|
12
|
+
> Pipecat logging moved from Loki to VictoriaLogs in 2026-08. The old Loki
|
|
13
|
+
> instance (`35.154.72.110:3100`) is still up and still answers `200`, but it
|
|
14
|
+
> receives only a residual trickle (~18 lines/hour of pod-shutdown noise). It
|
|
15
|
+
> returns **an empty result set rather than an error** for every real query, so
|
|
16
|
+
> a stale Loki query looks like "this call has no logs" instead of like a
|
|
17
|
+
> broken endpoint. Do not query it.
|
|
18
|
+
|
|
19
|
+
## Parameters
|
|
20
|
+
|
|
21
|
+
- `search` — **any call identifier** (required): the Ringg call id (`01a03784-…`), a provider-native id (`3825374100`, `e42e1ec1…`), a telephony provider UUID, or an Asterisk sid. The last two need a resolve hop — see step 3.
|
|
22
|
+
- `for` — **environment** (optional): `production` (default) or `staging`
|
|
23
|
+
|
|
24
|
+
## Where pipecat logs actually live
|
|
25
|
+
|
|
26
|
+
VictoriaLogs is **regional** — three independent instances, each storing only
|
|
27
|
+
its own cluster's logs, each behind its own `vmauth` (max 4 concurrent reads).
|
|
28
|
+
There is no cross-region query.
|
|
29
|
+
|
|
30
|
+
| Instance | Cluster | Holds |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| **us-east1** | `desivocal-prod-us-e1-cluster` | **all pipecat** — `dv-pipecat` (`production`), `dv-pipecat-canary`, `dv-pipecat-stage` (`staging`) |
|
|
33
|
+
| Mumbai | `desivocal-prod-cluster` | backend / taskiq / temporal only — **no pipecat** |
|
|
34
|
+
| KSA | `desivocal-prod-cluster-ksa` | backend / taskiq only — **no pipecat** |
|
|
35
|
+
|
|
36
|
+
**Always query us-east1 for pipecat, whatever the call's region.** Both
|
|
37
|
+
production and staging pipecat live there, separated by the `environment`
|
|
38
|
+
field. The Mumbai cluster does have a `dv-pipecat` Deployment, but it is a
|
|
39
|
+
single idle replica (us-east1 runs ~900) — it serves no traffic, and its pods
|
|
40
|
+
lack the `logs.ringg.ai/collect=application` label that Mumbai's Vector agent
|
|
41
|
+
selects on, so nothing from it is collected anyway. An empty Mumbai result is
|
|
42
|
+
therefore expected and means nothing.
|
|
43
|
+
|
|
44
|
+
Non-pipecat lookups do need the other two: the backend's
|
|
45
|
+
`new-calling-agent-taskiq-call-completion` logs live in Mumbai (India) or KSA.
|
|
46
|
+
See "Cross-checking against the backend" below.
|
|
47
|
+
|
|
48
|
+
## Instructions
|
|
49
|
+
|
|
50
|
+
### 1. Parse arguments
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
IDENTIFIER = search
|
|
54
|
+
ENV = for (default: "production")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Normalize `prod` to `production`. If `IDENTIFIER` is missing, ask the user.
|
|
58
|
+
|
|
59
|
+
**Do not branch on what the identifier looks like.** A call has several ids and
|
|
60
|
+
they are not interchangeable — but you cannot tell which kind you were handed
|
|
61
|
+
by its shape, so always try the indexed field first and only resolve if it
|
|
62
|
+
comes back empty (step 3). What exists in practice:
|
|
63
|
+
|
|
64
|
+
| Identifier | Example | `call_id:=` works? |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| Ringg call id (UUIDv7, `01a0…`) | `01a03784-c580-7811-95ef-20ef317f8352` | **yes** |
|
|
67
|
+
| provider-native numeric | `3825374100` | **yes** |
|
|
68
|
+
| provider-native 32-hex | `e42e1ec169ea4ab5abba0f49480b84ba` | **yes** |
|
|
69
|
+
| telephony provider's own UUID | `db6bd116-5197-4cad-8df6-d39bbbcc4565` | **no — 0 rows** |
|
|
70
|
+
| Asterisk sid | `1787637558.655495` | **no — 0 rows** |
|
|
71
|
+
|
|
72
|
+
The indexed `call_id` field carries the **Ringg** id — which the logs also call
|
|
73
|
+
`callback_call_id`. The last two rows are the trap: a provider UUID looks
|
|
74
|
+
exactly like a Ringg id and silently returns nothing, and the sid returns only
|
|
75
|
+
a few callback lines. Both are recoverable — see step 3.
|
|
76
|
+
|
|
77
|
+
### 2. Open a port-forward to the us-east1 VictoriaLogs
|
|
78
|
+
|
|
79
|
+
The regional read endpoints (`use1.victorialogs.internal:8427` etc.) resolve
|
|
80
|
+
only inside their own cluster, so query `svc/victoria-logs` through a
|
|
81
|
+
port-forward. Start it in the background and poll until it answers — do not
|
|
82
|
+
`sleep` in the foreground:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
kubectl --context gke_desivocalprod01_us-east1_desivocal-prod-us-e1-cluster \
|
|
86
|
+
-n victorialogs port-forward svc/victoria-logs 9430:9428 > /tmp/vl-pf.log 2>&1 &
|
|
87
|
+
|
|
88
|
+
curl -sf --retry 30 --retry-delay 1 --retry-connrefused -m 10 \
|
|
89
|
+
"http://127.0.0.1:9430/select/logsql/query" \
|
|
90
|
+
--data-urlencode 'query=_time:5m * | limit 1' -o /dev/null
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The readiness check must be `curl`'s own `--retry-connrefused`, not a shell
|
|
94
|
+
retry loop. The forward takes ~1-2s to bind, and until it does `curl` fails
|
|
95
|
+
with connection-refused **instantly** — `-m` never applies, because there is
|
|
96
|
+
nothing to wait on. A bare `for i in 1..10; do curl … && break; done` therefore
|
|
97
|
+
burns all ten attempts in milliseconds and reports failure on a port-forward
|
|
98
|
+
that is about to come up. Only `--retry-delay` actually waits.
|
|
99
|
+
|
|
100
|
+
Tear it down with `pkill -f "port-forward svc/victoria-logs"` when finished.
|
|
101
|
+
|
|
102
|
+
### 3. Query
|
|
103
|
+
|
|
104
|
+
**Timezone note:** user-supplied times are **IST (Asia/Kolkata, UTC+5:30)**.
|
|
105
|
+
LogsQL `_time` accepts relative ranges (`_time:1d`) or absolute UTC
|
|
106
|
+
(`_time:[2026-08-25T04:00:00Z, 2026-08-25T05:00:00Z]`) — convert before querying.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
curl -s -m 60 "http://127.0.0.1:9430/select/logsql/query" \
|
|
110
|
+
--data-urlencode "query=_time:1d application:dv-pipecat environment:=<ENV> call_id:=\"<IDENTIFIER>\" | limit 500" \
|
|
111
|
+
-o /tmp/vl.json
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`call_id` is an indexed field, and matching it is **strictly better than a
|
|
115
|
+
substring search** — not just faster. Most lines carry the field without
|
|
116
|
+
printing the id in their text, so substring under-returns badly. Measured on
|
|
117
|
+
three live calls:
|
|
118
|
+
|
|
119
|
+
| id | `call_id:=` | substring |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `01a03784-…` | 82 lines | 27 |
|
|
122
|
+
| `3825374100` | 84 lines | 32 |
|
|
123
|
+
| `e42e1ec1…` | 177 lines | 34 |
|
|
124
|
+
|
|
125
|
+
**If it returns 0 rows, the identifier is a provider id, not the Ringg id.**
|
|
126
|
+
Recover the real one and re-query — this is the difference between "this call
|
|
127
|
+
barely logged anything" and the actual call:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
REAL=$(curl -s -m 60 "http://127.0.0.1:9430/select/logsql/query" \
|
|
131
|
+
--data-urlencode "query=_time:1d application:dv-pipecat \"<IDENTIFIER>\" | fields call_id, _msg | limit 20" \
|
|
132
|
+
| { grep -oE '"call_id":"[^"u][^"]*"|callback_call_id[=: ]+[0-9a-f-]{8,}' || true; } \
|
|
133
|
+
| grep -oE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' | sort -u | head -1)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Then re-run the indexed query with `$REAL`. A bare substring filter is the last
|
|
137
|
+
resort, and also the only way to see early-startup lines (`[run_bot] call_id=…`
|
|
138
|
+
and friends), which are logged before the call context is bound and so carry no
|
|
139
|
+
`call_id` field at all — they show as `call_id: "unknown"` or omit it.
|
|
140
|
+
|
|
141
|
+
If the result is empty, in order: try the other `environment`; drop the
|
|
142
|
+
`environment` filter; widen `_time` (max range is 720h); try
|
|
143
|
+
`application:~"dv-pipecat"` to include `dv-pipecat-canary`.
|
|
144
|
+
|
|
145
|
+
### 4. Parse and display
|
|
146
|
+
|
|
147
|
+
The response is **JSON Lines** — one JSON object per line, not a wrapped
|
|
148
|
+
envelope. `jq .` on the whole file fails; parse per line:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
jq -r '[._time, (.level // "-"), ._msg] | @tsv' /tmp/vl.json | sort
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Results come back unordered, so **sort by `_time` yourself**. Display
|
|
155
|
+
chronologically (earliest first) with timestamp, level, and message.
|
|
156
|
+
|
|
157
|
+
Useful fields: `_time`, `_msg`, `level`, `call_id`, `pod`, `application`,
|
|
158
|
+
`environment`, `cluster`, `container`, `logger`, `module`, `function`, `line`.
|
|
159
|
+
|
|
160
|
+
Two field names differ from the backend's records and are easy to get wrong:
|
|
161
|
+
pipecat logs the pod as **`pod`**, not `pod_name`, and its **`level` is
|
|
162
|
+
lowercase** (`debug`/`info`/`warning`/`error`) while the parallel `severity`
|
|
163
|
+
field is uppercase. A filter on the wrong one silently matches nothing.
|
|
164
|
+
|
|
165
|
+
### 5. Analyze
|
|
166
|
+
|
|
167
|
+
After displaying the logs, provide a brief analysis:
|
|
168
|
+
|
|
169
|
+
1. **Call timeline**: what happened (connected, greeted, conversation, ended)
|
|
170
|
+
2. **Errors/warnings**: highlight ERROR/WARNING lines
|
|
171
|
+
3. **Tool calls**: function/tool calls made during the call
|
|
172
|
+
4. **TTS/STT activity**: speech-related events
|
|
173
|
+
5. **Call outcome**: normal hangup, error, transfer, timeout
|
|
174
|
+
6. **Anomalies**: long silences, repeated errors, unexpected transitions
|
|
175
|
+
|
|
176
|
+
Note the session shape while reading — it changes which pipeline is running and
|
|
177
|
+
therefore which failures are possible. `Using single_node bot` vs a FlowManager
|
|
178
|
+
line; `channel=livekit|daily|telephony|smallwebrtc`; and `text mode, starting
|
|
179
|
+
flow` / `Local recording disabled for text-only session` / `lk.chat message ->
|
|
180
|
+
queued to LLM`, which mark a **text-only** session (no STT, no
|
|
181
|
+
`TranscriptionFrame`).
|
|
182
|
+
|
|
183
|
+
### 6. Grafana link
|
|
184
|
+
|
|
185
|
+
Give the user a link to the pipecat dashboard (datasource `vl-use1`, i.e. the
|
|
186
|
+
same us-east1 store queried above):
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
http://10.120.0.49/d/vl-pipecat-logs
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Its variables are `environment`, `application`, `container`, `pod`, `call_id`,
|
|
193
|
+
`trace_id`, `message_substring`, `minimum_level`. The host is an internal
|
|
194
|
+
LoadBalancer IP — reachable on the VPN, not from the public internet.
|
|
195
|
+
|
|
196
|
+
## Cross-checking against the backend
|
|
197
|
+
|
|
198
|
+
When pipecat logs are thin, the backend's call-completion payload is a good
|
|
199
|
+
second source: it dumps the whole completion object, including
|
|
200
|
+
`function_calls_detailed` with each tool's `response_data` — so a failing
|
|
201
|
+
tool's error string is greppable even without pipecat logs. It lives in the
|
|
202
|
+
**Mumbai** (India) or **KSA** VL instance, not us-east1:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
kubectl --context gke_desivocalprod01_asia-south1_desivocal-prod-cluster \
|
|
206
|
+
-n victorialogs port-forward svc/victoria-logs 9429:9428 > /tmp/vl-pf-mum.log 2>&1 &
|
|
207
|
+
|
|
208
|
+
curl -s -m 60 "http://127.0.0.1:9429/select/logsql/query" \
|
|
209
|
+
--data-urlencode 'query=_time:1d application:new-calling-agent-taskiq-call-completion "<IDENTIFIER>" | limit 50'
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
KSA is `gke_desivocalprod01_me-central2_desivocal-prod-cluster-ksa`, same
|
|
213
|
+
namespace and service.
|
|
214
|
+
|
|
215
|
+
## Troubleshooting
|
|
216
|
+
|
|
217
|
+
- **Empty result, `200` status** — the usual cause is the wrong region or a
|
|
218
|
+
missing `_time` window, not a missing call. Work through the fallbacks in
|
|
219
|
+
step 3 before concluding the call has no logs.
|
|
220
|
+
- **`too big time range selected`** — `_time:` is mandatory and capped at 720h.
|
|
221
|
+
A query with no `_time` filter is rejected with a `1677-09-21 → 2262-04-11`
|
|
222
|
+
range in the message; that is the missing-filter error, not a real range.
|
|
223
|
+
- **`jq: parse error`** — the response is JSON Lines; see step 4.
|
|
224
|
+
- **Port-forward drops** — `kubectl port-forward` dies on idle or on pod
|
|
225
|
+
rotation. Re-run step 2; the retry makes that safe to repeat.
|
|
226
|
+
- **Zero rows, or only a handful** — you were almost certainly handed a
|
|
227
|
+
provider id rather than the Ringg one. Resolve it (step 3) instead of
|
|
228
|
+
widening the time range.
|
|
229
|
+
- **Slow or refused reads** — each region's `vmauth` allows 4 concurrent reads.
|
|
230
|
+
Serialize queries rather than fanning out.
|
|
231
|
+
- **A migrated webcall with no pipecat logs at all** — webcalls with
|
|
232
|
+
`telephony_provider=livekit` run on LiveKit Agents, not pipecat, and log to
|
|
233
|
+
GCP Cloud Logging (`desivocalprod01`, container `ringg-webcall`).
|
|
234
|
+
|
|
235
|
+
## Reference
|
|
236
|
+
|
|
237
|
+
For LogsQL syntax and more filtering options, see [query-reference.md](query-reference.md).
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# LogsQL Query Reference for Pipecat Logs
|
|
2
|
+
|
|
3
|
+
VictoriaLogs uses **LogsQL**, not LogQL. The two look similar and are not
|
|
4
|
+
compatible: there are no `{label="value"}` stream selectors, no `|=` line
|
|
5
|
+
filters, and no `| json` / `| line_format` stages. Fields are filtered
|
|
6
|
+
directly, and the pipeline after `|` uses named pipes (`limit`, `stats`,
|
|
7
|
+
`sort`, `fields`, `field_names`).
|
|
8
|
+
|
|
9
|
+
Full syntax: <https://docs.victoriametrics.com/victorialogs/logsql/>
|
|
10
|
+
|
|
11
|
+
## Base query pattern
|
|
12
|
+
|
|
13
|
+
```logsql
|
|
14
|
+
_time:1d application:dv-pipecat environment:=production call_id:="<call_id>" | limit 500
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`_time:` is **mandatory** on every query and capped at 720h. Omitting it is
|
|
18
|
+
rejected with a `[1677-09-21 … 2262-04-11]` range in the error — that is the
|
|
19
|
+
missing-filter message, not a real range you asked for.
|
|
20
|
+
|
|
21
|
+
## Filter forms
|
|
22
|
+
|
|
23
|
+
| Form | Meaning |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `field:="exact"` | exact field match (fastest — use for `call_id`) |
|
|
26
|
+
| `field:"phrase"` | phrase match within the field |
|
|
27
|
+
| `field:~"regex"` | regexp match, e.g. `application:~"dv-pipecat"` |
|
|
28
|
+
| `"substring"` | substring across the whole record — the `\|=` equivalent |
|
|
29
|
+
| `field:*` | field exists |
|
|
30
|
+
| `-field:="x"` | negation |
|
|
31
|
+
| `a AND b`, `a OR b` | boolean (bare space is AND) |
|
|
32
|
+
|
|
33
|
+
## Time ranges
|
|
34
|
+
|
|
35
|
+
```logsql
|
|
36
|
+
_time:5m _time:1h _time:1d _time:7d
|
|
37
|
+
_time:[2026-08-25T04:00:00Z, 2026-08-25T05:00:00Z]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Absolute times are **UTC**. User-supplied times are IST (UTC+5:30) — subtract
|
|
41
|
+
5h30m first.
|
|
42
|
+
|
|
43
|
+
## Common variations
|
|
44
|
+
|
|
45
|
+
**Errors only** — `level` is lowercase on pipecat records; the uppercase
|
|
46
|
+
values live on the parallel `severity` field, so match case-insensitively or
|
|
47
|
+
pick one field deliberately:
|
|
48
|
+
```logsql
|
|
49
|
+
_time:1d application:dv-pipecat call_id:="<call_id>" level:~"(?i)error|critical" | limit 200
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Warnings and above:**
|
|
53
|
+
```logsql
|
|
54
|
+
_time:1d application:dv-pipecat call_id:="<call_id>" severity:~"WARNING|ERROR|CRITICAL" | limit 200
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Keyword within a call** (LLM / TTS / tool calls / VAD):
|
|
58
|
+
```logsql
|
|
59
|
+
_time:1d application:dv-pipecat call_id:="<call_id>" "LLM" | limit 200
|
|
60
|
+
_time:1d application:dv-pipecat call_id:="<call_id>" _msg:~"function|tool_call|generic_function" | limit 200
|
|
61
|
+
_time:1d application:dv-pipecat call_id:="<call_id>" _msg:~"VAD|speaking|speech|silence|idle" | limit 200
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**One error string across all calls** — how you find out whether a bug is
|
|
65
|
+
systemic and how often it fires:
|
|
66
|
+
```logsql
|
|
67
|
+
_time:1d application:dv-pipecat "TaskManager is still not initialized" | limit 200
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**By pod** — the field is `pod`; `pod_name` exists on the backend's records
|
|
71
|
+
but **not** on pipecat's, and filtering on it silently matches nothing:
|
|
72
|
+
```logsql
|
|
73
|
+
_time:1h application:dv-pipecat pod:~"dv-pipecat-canary" | limit 200
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Include canary:**
|
|
77
|
+
```logsql
|
|
78
|
+
_time:1d application:~"dv-pipecat" call_id:="<call_id>" | limit 500
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Aggregation and discovery pipes
|
|
82
|
+
|
|
83
|
+
```logsql
|
|
84
|
+
_time:30m * | stats by (application, cluster, environment) count() # what's in this instance
|
|
85
|
+
_time:1h application:dv-pipecat | stats by (level) count() # error-rate breakdown
|
|
86
|
+
_time:1h application:dv-pipecat | limit 500 | field_names # available fields
|
|
87
|
+
_time:1d application:dv-pipecat "<error>" | fields _time, call_id, pod | limit 200
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`stats by (...)` is the cheap way to answer "which region / app / pod is this
|
|
91
|
+
happening in" before pulling raw lines.
|
|
92
|
+
|
|
93
|
+
## API endpoints
|
|
94
|
+
|
|
95
|
+
| Endpoint | Purpose |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `POST /select/logsql/query` | Query logs (use `--data-urlencode 'query=…'`) |
|
|
98
|
+
| `POST /select/logsql/hits` | Hit counts bucketed over time |
|
|
99
|
+
| `GET /select/logsql/field_names` | Field names for a query |
|
|
100
|
+
| `GET /select/logsql/field_values` | Values for one field |
|
|
101
|
+
|
|
102
|
+
Parameters: `query` (LogsQL, includes its own time filter), and optionally
|
|
103
|
+
`start` / `end` / `limit`. There is no `direction` — order with a `sort` pipe
|
|
104
|
+
or sort client-side.
|
|
105
|
+
|
|
106
|
+
## Response structure
|
|
107
|
+
|
|
108
|
+
**JSON Lines** — one JSON object per line, no envelope. `jq .` over the whole
|
|
109
|
+
body fails; parse per line:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
{"_time":"2026-08-25T04:09:20.448Z","_msg":"Call config: …","level":"info","call_id":"01a0371b-…","pod":"dv-pipecat-…"}
|
|
113
|
+
{"_time":"2026-08-25T04:09:20.455Z","_msg":"BYOK status: …","level":"info","call_id":"01a0371b-…","pod":"dv-pipecat-…"}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
jq -r '[._time, (.level // "-"), ._msg] | @tsv' /tmp/vl.json | sort
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Results are unordered — sort by `_time` yourself.
|
|
121
|
+
|
|
122
|
+
## Fields on pipecat records
|
|
123
|
+
|
|
124
|
+
`_time`, `_msg`, `level`, `severity`, `call_id`, `pod`, `node`, `application`,
|
|
125
|
+
`container`, `namespace`, `cluster`, `environment`, `logger`, `module`,
|
|
126
|
+
`function`, `line`, `process`, `thread`, `stream`, `_extras_dropped`,
|
|
127
|
+
`_truncated`.
|
|
128
|
+
|
|
129
|
+
`level` is lowercase, `severity` is uppercase, and the pod is `pod` — **not**
|
|
130
|
+
`pod_name`. The backend's records carry a different and larger set
|
|
131
|
+
(`pod_name`, `trace_id`, `agent_id`, `workspace_id`, `region`, `host_ip`,
|
|
132
|
+
`correlation_id`, …), so don't carry a working backend filter over to a pipecat
|
|
133
|
+
query unchanged. `| limit N | field_names` on a live window is the way to check.
|
|
134
|
+
|
|
135
|
+
Vector sets `cluster` / `environment` / the `kubernetes` metadata itself and
|
|
136
|
+
strips any same-named keys from the application payload, so those cannot be
|
|
137
|
+
spoofed by a log line — they are reliable for filtering.
|
|
138
|
+
|
|
139
|
+
## Infrastructure
|
|
140
|
+
|
|
141
|
+
Three regional instances, no cross-region query, each behind its own `vmauth`
|
|
142
|
+
(max 4 concurrent reads). All are `svc/victoria-logs:9428` in namespace
|
|
143
|
+
`victorialogs`; the `*.victorialogs.internal:8427` read endpoints resolve only
|
|
144
|
+
inside their own cluster, so port-forward from a laptop.
|
|
145
|
+
|
|
146
|
+
| Region | kubectl context | Holds |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| us-east1 | `gke_desivocalprod01_us-east1_desivocal-prod-us-e1-cluster` | **all pipecat**, prod + staging |
|
|
149
|
+
| Mumbai | `gke_desivocalprod01_asia-south1_desivocal-prod-cluster` | backend / taskiq / temporal |
|
|
150
|
+
| KSA | `gke_desivocalprod01_me-central2_desivocal-prod-cluster-ksa` | backend / taskiq |
|
|
151
|
+
|
|
152
|
+
- **Grafana**: `http://10.120.0.49` (internal LB — VPN only), pipecat dashboard
|
|
153
|
+
uid `vl-pipecat-logs`, datasources `vl-use1` (default) / `vl-mumbai` / `vl-ksa`.
|
|
154
|
+
- **Collection**: a Vector DaemonSet per cluster ships to the regional `vmauth`.
|
|
155
|
+
Mumbai, KSA and staging collect only Pods labelled
|
|
156
|
+
`logs.ringg.ai/collect=application`; us-east1 collects everything except Pods
|
|
157
|
+
labelled `vector.dev/exclude`. So in Mumbai/KSA, "no logs for this workload"
|
|
158
|
+
can mean "not labelled for collection", not "not running".
|
|
159
|
+
|
|
160
|
+
## Environment values
|
|
161
|
+
|
|
162
|
+
| Environment | `environment` value | Pipecat application |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| Production | `production` | `dv-pipecat`, `dv-pipecat-canary` |
|
|
165
|
+
| Staging | `staging` | `dv-pipecat-stage` |
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pipecat-logs
|
|
3
|
+
description: Fetch and analyze pipecat application logs from VictoriaLogs by call ID or call SID. Use when debugging call issues, investigating errors, or analyzing bot behavior for a specific call. Accepts any call identifier — the Ringg call id, a provider-native id, a telephony provider UUID, or an Asterisk sid (the last two are resolved first) — and optional environment (staging/production).
|
|
4
|
+
argument-hint: <call_id|call_sid> [staging|production]
|
|
5
|
+
allowed-tools: Bash(curl *), Bash(jq *), Bash(kubectl *), Bash(pkill *)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Pipecat Logs Fetcher
|
|
9
|
+
|
|
10
|
+
Fetch logs from **VictoriaLogs** for a specific pipecat call and analyze them.
|
|
11
|
+
|
|
12
|
+
> Pipecat logging moved from Loki to VictoriaLogs in 2026-08. The old Loki
|
|
13
|
+
> instance (`35.154.72.110:3100`) is still up and still answers `200`, but it
|
|
14
|
+
> receives only a residual trickle (~18 lines/hour of pod-shutdown noise). It
|
|
15
|
+
> returns **an empty result set rather than an error** for every real query, so
|
|
16
|
+
> a stale Loki query looks like "this call has no logs" instead of like a
|
|
17
|
+
> broken endpoint. Do not query it.
|
|
18
|
+
|
|
19
|
+
## Parameters
|
|
20
|
+
|
|
21
|
+
- `search` — **any call identifier** (required): the Ringg call id (`01a03784-…`), a provider-native id (`3825374100`, `e42e1ec1…`), a telephony provider UUID, or an Asterisk sid. The last two need a resolve hop — see step 3.
|
|
22
|
+
- `for` — **environment** (optional): `production` (default) or `staging`
|
|
23
|
+
|
|
24
|
+
## Where pipecat logs actually live
|
|
25
|
+
|
|
26
|
+
VictoriaLogs is **regional** — three independent instances, each storing only
|
|
27
|
+
its own cluster's logs, each behind its own `vmauth` (max 4 concurrent reads).
|
|
28
|
+
There is no cross-region query.
|
|
29
|
+
|
|
30
|
+
| Instance | Cluster | Holds |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| **us-east1** | `desivocal-prod-us-e1-cluster` | **all pipecat** — `dv-pipecat` (`production`), `dv-pipecat-canary`, `dv-pipecat-stage` (`staging`) |
|
|
33
|
+
| Mumbai | `desivocal-prod-cluster` | backend / taskiq / temporal only — **no pipecat** |
|
|
34
|
+
| KSA | `desivocal-prod-cluster-ksa` | backend / taskiq only — **no pipecat** |
|
|
35
|
+
|
|
36
|
+
**Always query us-east1 for pipecat, whatever the call's region.** Both
|
|
37
|
+
production and staging pipecat live there, separated by the `environment`
|
|
38
|
+
field. The Mumbai cluster does have a `dv-pipecat` Deployment, but it is a
|
|
39
|
+
single idle replica (us-east1 runs ~900) — it serves no traffic, and its pods
|
|
40
|
+
lack the `logs.ringg.ai/collect=application` label that Mumbai's Vector agent
|
|
41
|
+
selects on, so nothing from it is collected anyway. An empty Mumbai result is
|
|
42
|
+
therefore expected and means nothing.
|
|
43
|
+
|
|
44
|
+
Non-pipecat lookups do need the other two: the backend's
|
|
45
|
+
`new-calling-agent-taskiq-call-completion` logs live in Mumbai (India) or KSA.
|
|
46
|
+
See "Cross-checking against the backend" below.
|
|
47
|
+
|
|
48
|
+
## Instructions
|
|
49
|
+
|
|
50
|
+
### 1. Parse arguments
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
IDENTIFIER = search
|
|
54
|
+
ENV = for (default: "production")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Normalize `prod` to `production`. If `IDENTIFIER` is missing, ask the user.
|
|
58
|
+
|
|
59
|
+
**Do not branch on what the identifier looks like.** A call has several ids and
|
|
60
|
+
they are not interchangeable — but you cannot tell which kind you were handed
|
|
61
|
+
by its shape, so always try the indexed field first and only resolve if it
|
|
62
|
+
comes back empty (step 3). What exists in practice:
|
|
63
|
+
|
|
64
|
+
| Identifier | Example | `call_id:=` works? |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| Ringg call id (UUIDv7, `01a0…`) | `01a03784-c580-7811-95ef-20ef317f8352` | **yes** |
|
|
67
|
+
| provider-native numeric | `3825374100` | **yes** |
|
|
68
|
+
| provider-native 32-hex | `e42e1ec169ea4ab5abba0f49480b84ba` | **yes** |
|
|
69
|
+
| telephony provider's own UUID | `db6bd116-5197-4cad-8df6-d39bbbcc4565` | **no — 0 rows** |
|
|
70
|
+
| Asterisk sid | `1787637558.655495` | **no — 0 rows** |
|
|
71
|
+
|
|
72
|
+
The indexed `call_id` field carries the **Ringg** id — which the logs also call
|
|
73
|
+
`callback_call_id`. The last two rows are the trap: a provider UUID looks
|
|
74
|
+
exactly like a Ringg id and silently returns nothing, and the sid returns only
|
|
75
|
+
a few callback lines. Both are recoverable — see step 3.
|
|
76
|
+
|
|
77
|
+
### 2. Open a port-forward to the us-east1 VictoriaLogs
|
|
78
|
+
|
|
79
|
+
The regional read endpoints (`use1.victorialogs.internal:8427` etc.) resolve
|
|
80
|
+
only inside their own cluster, so query `svc/victoria-logs` through a
|
|
81
|
+
port-forward. Start it in the background and poll until it answers — do not
|
|
82
|
+
`sleep` in the foreground:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
kubectl --context gke_desivocalprod01_us-east1_desivocal-prod-us-e1-cluster \
|
|
86
|
+
-n victorialogs port-forward svc/victoria-logs 9430:9428 > /tmp/vl-pf.log 2>&1 &
|
|
87
|
+
|
|
88
|
+
curl -sf --retry 30 --retry-delay 1 --retry-connrefused -m 10 \
|
|
89
|
+
"http://127.0.0.1:9430/select/logsql/query" \
|
|
90
|
+
--data-urlencode 'query=_time:5m * | limit 1' -o /dev/null
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The readiness check must be `curl`'s own `--retry-connrefused`, not a shell
|
|
94
|
+
retry loop. The forward takes ~1-2s to bind, and until it does `curl` fails
|
|
95
|
+
with connection-refused **instantly** — `-m` never applies, because there is
|
|
96
|
+
nothing to wait on. A bare `for i in 1..10; do curl … && break; done` therefore
|
|
97
|
+
burns all ten attempts in milliseconds and reports failure on a port-forward
|
|
98
|
+
that is about to come up. Only `--retry-delay` actually waits.
|
|
99
|
+
|
|
100
|
+
Tear it down with `pkill -f "port-forward svc/victoria-logs"` when finished.
|
|
101
|
+
|
|
102
|
+
### 3. Query
|
|
103
|
+
|
|
104
|
+
**Timezone note:** user-supplied times are **IST (Asia/Kolkata, UTC+5:30)**.
|
|
105
|
+
LogsQL `_time` accepts relative ranges (`_time:1d`) or absolute UTC
|
|
106
|
+
(`_time:[2026-08-25T04:00:00Z, 2026-08-25T05:00:00Z]`) — convert before querying.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
curl -s -m 60 "http://127.0.0.1:9430/select/logsql/query" \
|
|
110
|
+
--data-urlencode "query=_time:1d application:dv-pipecat environment:=<ENV> call_id:=\"<IDENTIFIER>\" | limit 500" \
|
|
111
|
+
-o /tmp/vl.json
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`call_id` is an indexed field, and matching it is **strictly better than a
|
|
115
|
+
substring search** — not just faster. Most lines carry the field without
|
|
116
|
+
printing the id in their text, so substring under-returns badly. Measured on
|
|
117
|
+
three live calls:
|
|
118
|
+
|
|
119
|
+
| id | `call_id:=` | substring |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `01a03784-…` | 82 lines | 27 |
|
|
122
|
+
| `3825374100` | 84 lines | 32 |
|
|
123
|
+
| `e42e1ec1…` | 177 lines | 34 |
|
|
124
|
+
|
|
125
|
+
**If it returns 0 rows, the identifier is a provider id, not the Ringg id.**
|
|
126
|
+
Recover the real one and re-query — this is the difference between "this call
|
|
127
|
+
barely logged anything" and the actual call:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
REAL=$(curl -s -m 60 "http://127.0.0.1:9430/select/logsql/query" \
|
|
131
|
+
--data-urlencode "query=_time:1d application:dv-pipecat \"<IDENTIFIER>\" | fields call_id, _msg | limit 20" \
|
|
132
|
+
| { grep -oE '"call_id":"[^"u][^"]*"|callback_call_id[=: ]+[0-9a-f-]{8,}' || true; } \
|
|
133
|
+
| grep -oE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' | sort -u | head -1)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Then re-run the indexed query with `$REAL`. A bare substring filter is the last
|
|
137
|
+
resort, and also the only way to see early-startup lines (`[run_bot] call_id=…`
|
|
138
|
+
and friends), which are logged before the call context is bound and so carry no
|
|
139
|
+
`call_id` field at all — they show as `call_id: "unknown"` or omit it.
|
|
140
|
+
|
|
141
|
+
If the result is empty, in order: try the other `environment`; drop the
|
|
142
|
+
`environment` filter; widen `_time` (max range is 720h); try
|
|
143
|
+
`application:~"dv-pipecat"` to include `dv-pipecat-canary`.
|
|
144
|
+
|
|
145
|
+
### 4. Parse and display
|
|
146
|
+
|
|
147
|
+
The response is **JSON Lines** — one JSON object per line, not a wrapped
|
|
148
|
+
envelope. `jq .` on the whole file fails; parse per line:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
jq -r '[._time, (.level // "-"), ._msg] | @tsv' /tmp/vl.json | sort
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Results come back unordered, so **sort by `_time` yourself**. Display
|
|
155
|
+
chronologically (earliest first) with timestamp, level, and message.
|
|
156
|
+
|
|
157
|
+
Useful fields: `_time`, `_msg`, `level`, `call_id`, `pod`, `application`,
|
|
158
|
+
`environment`, `cluster`, `container`, `logger`, `module`, `function`, `line`.
|
|
159
|
+
|
|
160
|
+
Two field names differ from the backend's records and are easy to get wrong:
|
|
161
|
+
pipecat logs the pod as **`pod`**, not `pod_name`, and its **`level` is
|
|
162
|
+
lowercase** (`debug`/`info`/`warning`/`error`) while the parallel `severity`
|
|
163
|
+
field is uppercase. A filter on the wrong one silently matches nothing.
|
|
164
|
+
|
|
165
|
+
### 5. Analyze
|
|
166
|
+
|
|
167
|
+
After displaying the logs, provide a brief analysis:
|
|
168
|
+
|
|
169
|
+
1. **Call timeline**: what happened (connected, greeted, conversation, ended)
|
|
170
|
+
2. **Errors/warnings**: highlight ERROR/WARNING lines
|
|
171
|
+
3. **Tool calls**: function/tool calls made during the call
|
|
172
|
+
4. **TTS/STT activity**: speech-related events
|
|
173
|
+
5. **Call outcome**: normal hangup, error, transfer, timeout
|
|
174
|
+
6. **Anomalies**: long silences, repeated errors, unexpected transitions
|
|
175
|
+
|
|
176
|
+
Note the session shape while reading — it changes which pipeline is running and
|
|
177
|
+
therefore which failures are possible. `Using single_node bot` vs a FlowManager
|
|
178
|
+
line; `channel=livekit|daily|telephony|smallwebrtc`; and `text mode, starting
|
|
179
|
+
flow` / `Local recording disabled for text-only session` / `lk.chat message ->
|
|
180
|
+
queued to LLM`, which mark a **text-only** session (no STT, no
|
|
181
|
+
`TranscriptionFrame`).
|
|
182
|
+
|
|
183
|
+
### 6. Grafana link
|
|
184
|
+
|
|
185
|
+
Give the user a link to the pipecat dashboard (datasource `vl-use1`, i.e. the
|
|
186
|
+
same us-east1 store queried above):
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
http://10.120.0.49/d/vl-pipecat-logs
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Its variables are `environment`, `application`, `container`, `pod`, `call_id`,
|
|
193
|
+
`trace_id`, `message_substring`, `minimum_level`. The host is an internal
|
|
194
|
+
LoadBalancer IP — reachable on the VPN, not from the public internet.
|
|
195
|
+
|
|
196
|
+
## Cross-checking against the backend
|
|
197
|
+
|
|
198
|
+
When pipecat logs are thin, the backend's call-completion payload is a good
|
|
199
|
+
second source: it dumps the whole completion object, including
|
|
200
|
+
`function_calls_detailed` with each tool's `response_data` — so a failing
|
|
201
|
+
tool's error string is greppable even without pipecat logs. It lives in the
|
|
202
|
+
**Mumbai** (India) or **KSA** VL instance, not us-east1:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
kubectl --context gke_desivocalprod01_asia-south1_desivocal-prod-cluster \
|
|
206
|
+
-n victorialogs port-forward svc/victoria-logs 9429:9428 > /tmp/vl-pf-mum.log 2>&1 &
|
|
207
|
+
|
|
208
|
+
curl -s -m 60 "http://127.0.0.1:9429/select/logsql/query" \
|
|
209
|
+
--data-urlencode 'query=_time:1d application:new-calling-agent-taskiq-call-completion "<IDENTIFIER>" | limit 50'
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
KSA is `gke_desivocalprod01_me-central2_desivocal-prod-cluster-ksa`, same
|
|
213
|
+
namespace and service.
|
|
214
|
+
|
|
215
|
+
## Troubleshooting
|
|
216
|
+
|
|
217
|
+
- **Empty result, `200` status** — the usual cause is the wrong region or a
|
|
218
|
+
missing `_time` window, not a missing call. Work through the fallbacks in
|
|
219
|
+
step 3 before concluding the call has no logs.
|
|
220
|
+
- **`too big time range selected`** — `_time:` is mandatory and capped at 720h.
|
|
221
|
+
A query with no `_time` filter is rejected with a `1677-09-21 → 2262-04-11`
|
|
222
|
+
range in the message; that is the missing-filter error, not a real range.
|
|
223
|
+
- **`jq: parse error`** — the response is JSON Lines; see step 4.
|
|
224
|
+
- **Port-forward drops** — `kubectl port-forward` dies on idle or on pod
|
|
225
|
+
rotation. Re-run step 2; the retry makes that safe to repeat.
|
|
226
|
+
- **Zero rows, or only a handful** — you were almost certainly handed a
|
|
227
|
+
provider id rather than the Ringg one. Resolve it (step 3) instead of
|
|
228
|
+
widening the time range.
|
|
229
|
+
- **Slow or refused reads** — each region's `vmauth` allows 4 concurrent reads.
|
|
230
|
+
Serialize queries rather than fanning out.
|
|
231
|
+
- **A migrated webcall with no pipecat logs at all** — webcalls with
|
|
232
|
+
`telephony_provider=livekit` run on LiveKit Agents, not pipecat, and log to
|
|
233
|
+
GCP Cloud Logging (`desivocalprod01`, container `ringg-webcall`).
|
|
234
|
+
|
|
235
|
+
## Reference
|
|
236
|
+
|
|
237
|
+
For LogsQL syntax and more filtering options, see [query-reference.md](query-reference.md).
|