dv-pipecat-flows 0.0.23.dev8__tar.gz → 0.0.23.dev9__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 (91) hide show
  1. {dv_pipecat_flows-0.0.23.dev8/src/dv_pipecat_flows.egg-info → dv_pipecat_flows-0.0.23.dev9}/PKG-INFO +1 -1
  2. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9/src/dv_pipecat_flows.egg-info}/PKG-INFO +1 -1
  3. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/actions.py +42 -14
  4. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/.agents/skills/loki-logs/SKILL.md +0 -0
  5. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/.agents/skills/loki-logs/query-reference.md +0 -0
  6. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/.claude/skills/loki-logs/SKILL.md +0 -0
  7. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/.claude/skills/loki-logs/query-reference.md +0 -0
  8. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/.gitattributes +0 -0
  9. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/.gitignore +0 -0
  10. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/.pre-commit-config.yaml +0 -0
  11. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/.python-version +0 -0
  12. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/.readthedocs.yaml +0 -0
  13. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/AGENTS.md +0 -0
  14. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/CHANGELOG.md +0 -0
  15. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/CLAUDE.md +0 -0
  16. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/CONTRIBUTING.md +0 -0
  17. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/LICENSE +0 -0
  18. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/MANIFEST.in +0 -0
  19. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/README.md +0 -0
  20. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/dev-requirements.txt +0 -0
  21. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/docker-compose.dev.yml +0 -0
  22. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/.eslintrc.json +0 -0
  23. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/.prettierrc +0 -0
  24. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/css/tailwind.css +0 -0
  25. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/examples/food_ordering.json +0 -0
  26. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/examples/movie_explorer.json +0 -0
  27. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/examples/patient_intake.json +0 -0
  28. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/examples/restaurant_reservation.json +0 -0
  29. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/examples/travel_planner.json +0 -0
  30. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/favicon.png +0 -0
  31. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/favicon.svg +0 -0
  32. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/index.html +0 -0
  33. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/editor/canvas.js +0 -0
  34. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/editor/editorState.js +0 -0
  35. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/editor/sidePanel.js +0 -0
  36. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/editor/toolbar.js +0 -0
  37. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/main.js +0 -0
  38. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/nodes/baseNode.js +0 -0
  39. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/nodes/endNode.js +0 -0
  40. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/nodes/flowNode.js +0 -0
  41. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/nodes/functionNode.js +0 -0
  42. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/nodes/index.js +0 -0
  43. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/nodes/mergeNode.js +0 -0
  44. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/nodes/startNode.js +0 -0
  45. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/types.js +0 -0
  46. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/utils/export.js +0 -0
  47. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/utils/helpers.js +0 -0
  48. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/utils/import.js +0 -0
  49. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/js/utils/validation.js +0 -0
  50. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/jsdoc.json +0 -0
  51. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/package-lock.json +0 -0
  52. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/package.json +0 -0
  53. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/postcss.config.cjs +0 -0
  54. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/public/favicon.png +0 -0
  55. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/public/favicon.svg +0 -0
  56. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/tailwind.config.cjs +0 -0
  57. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/vercel.json +0 -0
  58. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/editor/vite.config.js +0 -0
  59. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/engine_primitives_plan.md +0 -0
  60. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/env.example +0 -0
  61. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/images/food-ordering-flow.png +0 -0
  62. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/pipecat-flows.png +0 -0
  63. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/pipecat_upgrade.md +0 -0
  64. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/pyproject.toml +0 -0
  65. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/remote-asterisk-code/README.md +0 -0
  66. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/remote-asterisk-code/extensions.conf +0 -0
  67. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/remote-asterisk-code/rtp.conf +0 -0
  68. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/requirements.txt +0 -0
  69. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/scripts/check-pypi-package.py +0 -0
  70. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/scripts/fix-ruff.sh +0 -0
  71. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/scripts/pre-commit.sh +0 -0
  72. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/setup.cfg +0 -0
  73. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/dv_pipecat_flows.egg-info/SOURCES.txt +0 -0
  74. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/dv_pipecat_flows.egg-info/dependency_links.txt +0 -0
  75. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/dv_pipecat_flows.egg-info/requires.txt +0 -0
  76. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/dv_pipecat_flows.egg-info/scm_file_list.json +0 -0
  77. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/dv_pipecat_flows.egg-info/scm_version.json +0 -0
  78. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/dv_pipecat_flows.egg-info/top_level.txt +0 -0
  79. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/__init__.py +0 -0
  80. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/adapters.py +0 -0
  81. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/condition_evaluator.py +0 -0
  82. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/exceptions.py +0 -0
  83. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/flow_validator.py +0 -0
  84. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/manager.py +0 -0
  85. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/processors/__init__.py +0 -0
  86. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/processors/router_mode_guard.py +0 -0
  87. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/processors/speak_interruption_guard.py +0 -0
  88. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/processors/user_turn_observer.py +0 -0
  89. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/router_mode.py +0 -0
  90. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/src/pipecat_flows/types.py +0 -0
  91. {dv_pipecat_flows-0.0.23.dev8 → dv_pipecat_flows-0.0.23.dev9}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dv-pipecat-flows
3
- Version: 0.0.23.dev8
3
+ Version: 0.0.23.dev9
4
4
  Summary: Conversation Flow management for Pipecat AI applications
5
5
  License: BSD 2-Clause License
6
6
  Project-URL: Source, https://github.com/pipecat-ai/pipecat-flows
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dv-pipecat-flows
3
- Version: 0.0.23.dev8
3
+ Version: 0.0.23.dev9
4
4
  Summary: Conversation Flow management for Pipecat AI applications
5
5
  License: BSD 2-Clause License
6
6
  Project-URL: Source, https://github.com/pipecat-ai/pipecat-flows
@@ -71,6 +71,42 @@ ONGOING_ACTIONS_WAIT_TIMEOUT_S = 60.0
71
71
  _EXTRACT_VAR_RE = re.compile(
72
72
  r"@?\[\{\s*([A-Za-z_][A-Za-z0-9_.]*)\s*\}\]"
73
73
  )
74
+ # Whole string is exactly ONE token (``[{x}]`` / ``@[{x}]``, no surrounding
75
+ # text). Callers that want to preserve a resolved list/dict value rather than
76
+ # stringify it (e.g. chaining a JSON array into a later webhook body) match on
77
+ # this and use ``resolve_extract_path`` directly.
78
+ _EXACT_EXTRACT_RE = re.compile(
79
+ r"^@?\[\{\s*([A-Za-z_][A-Za-z0-9_.]*)\s*\}\]$"
80
+ )
81
+
82
+
83
+ def resolve_extract_path(state: dict, key: str):
84
+ """Walk a dotted ``a.b.0.c`` path through nested dicts/lists in ``state``.
85
+
86
+ Numeric segments index lists (an Action node's stored response is often a
87
+ root array). Returns ``None`` on any missing/out-of-range segment.
88
+ """
89
+ cur = state
90
+ for seg in key.split("."):
91
+ if isinstance(cur, dict) and seg in cur:
92
+ cur = cur[seg]
93
+ elif isinstance(cur, list):
94
+ try:
95
+ cur = cur[int(seg)]
96
+ except (ValueError, IndexError, TypeError):
97
+ return None
98
+ else:
99
+ return None
100
+ return cur
101
+
102
+
103
+ def exact_extract_key(text: str):
104
+ """Return the inner dotted key iff ``text`` is exactly one extract token
105
+ (``[{a.b}]`` / ``@[{a.b}]``), else ``None``. Whitespace-tolerant."""
106
+ if not isinstance(text, str):
107
+ return None
108
+ match = _EXACT_EXTRACT_RE.match(text.strip())
109
+ return match.group(1) if match else None
74
110
 
75
111
 
76
112
  def substitute_extract_vars(text: str, state: dict) -> str:
@@ -79,25 +115,17 @@ def substitute_extract_vars(text: str, state: dict) -> str:
79
115
  Supports dotted paths (``[{user.name}]``). Unknown variables (key not
80
116
  in state, or any path segment missing) are LEFT LITERAL — the marker
81
117
  survives so downstream debugging can spot the misconfigured extract.
118
+
119
+ Always returns a STRING (values are ``str()``-ified) — this is the
120
+ TTS/text-interpolation path. Callers needing to preserve a resolved
121
+ list/dict (e.g. a JSON webhook body value that is exactly one token)
122
+ should special-case ``exact_extract_key`` + ``resolve_extract_path``.
82
123
  """
83
124
  if not text or "[{" not in text or not isinstance(state, dict):
84
125
  return text
85
126
 
86
127
  def _resolve(key: str):
87
- cur = state
88
- for seg in key.split("."):
89
- if isinstance(cur, dict) and seg in cur:
90
- cur = cur[seg]
91
- elif isinstance(cur, list):
92
- # Numeric segment indexes a list — an Action node's stored
93
- # response is often a root array (``[{action_1.0.title}]``).
94
- try:
95
- cur = cur[int(seg)]
96
- except (ValueError, IndexError, TypeError):
97
- return None
98
- else:
99
- return None
100
- return cur
128
+ return resolve_extract_path(state, key)
101
129
 
102
130
  def _repl(match: "re.Match[str]") -> str:
103
131
  value = _resolve(match.group(1))