feat: add default initial context variables

This commit is contained in:
Abhishek Kumar 2026-04-02 14:32:43 +05:30
parent f368fe5134
commit 96c90376c3
8 changed files with 112 additions and 19 deletions

View file

@ -47,7 +47,6 @@ from api.services.workflow.pipecat_engine_variable_extractor import (
from api.services.workflow.tools.knowledge_base import (
retrieve_from_knowledge_base,
)
from api.services.workflow.tools.timezone import get_current_time
from api.utils.template_renderer import render_template
@ -149,15 +148,6 @@ class PipecatEngine:
# Helper that encapsulates custom tool management
self._custom_tool_manager = CustomToolManager(self)
# Add current time in EST (America/New_York) to gathered context
try:
est_time_result = get_current_time("America/New_York")
# The get_current_time utility returns a dict with 'datetime' field
# Store the ISO formatted datetime string under the key 'time'
self._gathered_context["time"] = est_time_result.get("datetime")
except Exception as e:
logger.error(f"Failed to fetch current EST time: {e}")
await self.set_node(self.workflow.start_node_id)
logger.debug(f"{self.__class__.__name__} initialized")

View file

@ -2,10 +2,17 @@
import json
import re
from typing import Any, Dict, Union
from datetime import datetime
from typing import Any, Dict, Optional, Union
from zoneinfo import ZoneInfo
from loguru import logger
from api.services.workflow.workflow import TEMPLATE_VAR_PATTERN
_CURRENT_TIME_PREFIX = "current_time"
_CURRENT_WEEKDAY_PREFIX = "current_weekday"
def get_nested_value(obj: Any, path: str) -> Any:
"""
@ -85,6 +92,70 @@ def render_template(
return _render_string(template, context)
def _extract_timezone_from_template(template_str: str) -> Optional[str]:
"""Extract the timezone from a ``current_time_<TZ>`` or ``current_weekday_<TZ>`` variable.
Returns the first IANA timezone found, or None.
"""
pattern = (
r"\{\{\s*(?:"
+ re.escape(_CURRENT_TIME_PREFIX)
+ r"|"
+ re.escape(_CURRENT_WEEKDAY_PREFIX)
+ r")_([^|\s}]+)"
)
match = re.search(pattern, template_str)
return match.group(1).strip() if match else None
def _resolve_builtin_variable(
variable_path: str, default_tz: Optional[str] = None
) -> Optional[str]:
"""Resolve built-in template variables that are available in all contexts.
Supported variables:
- ``current_time`` current time in UTC
- ``current_time_<TIMEZONE>`` current time in the given IANA timezone
- ``current_weekday`` current weekday name (uses *default_tz* if set, else UTC)
- ``current_weekday_<TIMEZONE>`` current weekday name in the given timezone
Args:
variable_path: The template variable name to resolve.
default_tz: Fallback timezone for ``current_weekday`` when no explicit
timezone suffix is provided (typically inferred from a
``current_time_<TZ>`` variable in the same template).
Returns:
The resolved string value, or None if *variable_path* is not a
recognised built-in.
"""
if variable_path == _CURRENT_TIME_PREFIX:
tz = ZoneInfo(default_tz) if default_tz else ZoneInfo("UTC")
return datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S %Z")
if variable_path.startswith(_CURRENT_TIME_PREFIX + "_"):
timezone = variable_path[len(_CURRENT_TIME_PREFIX) + 1 :]
try:
return datetime.now(ZoneInfo(timezone)).strftime("%Y-%m-%d %H:%M:%S %Z")
except Exception:
logger.warning(f"Invalid timezone in template variable: {timezone}")
return None
if variable_path == _CURRENT_WEEKDAY_PREFIX:
tz = ZoneInfo(default_tz) if default_tz else ZoneInfo("UTC")
return datetime.now(tz).strftime("%A")
if variable_path.startswith(_CURRENT_WEEKDAY_PREFIX + "_"):
timezone = variable_path[len(_CURRENT_WEEKDAY_PREFIX) + 1 :]
try:
return datetime.now(ZoneInfo(timezone)).strftime("%A")
except Exception:
logger.warning(f"Invalid timezone in template variable: {timezone}")
return None
return None
def _render_string(template_str: str, context: Dict[str, Any]) -> str:
"""
Render a string template with variable substitution.
@ -99,11 +170,20 @@ def _render_string(template_str: str, context: Dict[str, Any]) -> str:
if not template_str:
return template_str
# Pre-scan for a current_time_<TZ> variable so that {{current_weekday}}
# can inherit the same timezone instead of defaulting to UTC.
default_tz = _extract_timezone_from_template(template_str)
def _replace(match: re.Match[str]) -> str: # type: ignore[type-arg]
variable_path = match.group(1).strip()
filter_name = match.group(2).strip() if match.group(2) else None
filter_value = match.group(3).strip() if match.group(3) else None
# Check for built-in variables first (current_time, current_weekday)
builtin_value = _resolve_builtin_variable(variable_path, default_tz)
if builtin_value is not None:
return builtin_value
# Get value using nested path lookup
value = get_nested_value(context, variable_path)