temporal_parser
¶
Full name: tenets.core.prompt.temporal_parser
temporal_parser¶
Enhanced temporal parsing for dates, times, and ranges.
Supports multiple date formats, natural language expressions, recurring patterns, and date ranges with comprehensive parsing capabilities.
Classes¶
TemporalExpressiondataclass
¶
TemporalPatternMatcher¶
Pattern-based temporal expression matching.
Initialize with temporal patterns.
PARAMETER | DESCRIPTION |
---|---|
patterns_file | Path to temporal patterns JSON file |
Source code in tenets/core/prompt/temporal_parser.py
TemporalParser¶
Main temporal parser combining all approaches.
Initialize temporal parser.
PARAMETER | DESCRIPTION |
---|---|
patterns_file | Path to temporal patterns JSON file |
Source code in tenets/core/prompt/temporal_parser.py
Functions¶
parse¶
Parse temporal expressions from text.
PARAMETER | DESCRIPTION |
---|---|
text | Text to parse TYPE: |
RETURNS | DESCRIPTION |
---|---|
List[TemporalExpression] | List of temporal expressions |
Source code in tenets/core/prompt/temporal_parser.py
def parse(self, text: str) -> List[TemporalExpression]:
"""Parse temporal expressions from text.
Args:
text: Text to parse
Returns:
List of temporal expressions
"""
expressions = []
# Limit text length for very long prompts to prevent timeouts
MAX_TEXT_LENGTH = 10000 # Characters for temporal parsing
if len(text) > MAX_TEXT_LENGTH:
# Only parse the first portion for temporal expressions
# (dates are usually at the beginning of prompts anyway)
text = text[:MAX_TEXT_LENGTH]
# 1. Check for absolute dates
absolute_exprs = self._parse_absolute_dates(text)
expressions.extend(absolute_exprs)
# 2. Check for relative dates
relative_exprs = self._parse_relative_dates(text)
expressions.extend(relative_exprs)
# 3. Check for date ranges
range_exprs = self._parse_date_ranges(text)
expressions.extend(range_exprs)
# 4. Check for recurring patterns
recurring_exprs = self._parse_recurring_patterns(text)
expressions.extend(recurring_exprs)
# 5. Try dateutil parser if available (but skip for very long texts)
if DATEUTIL_AVAILABLE and not expressions and len(text) < 5000:
try:
dateutil_exprs = self._parse_with_dateutil(text)
expressions.extend(dateutil_exprs)
except Exception as e:
# Log but don't fail if dateutil has issues
self.logger.debug(f"Dateutil parsing failed: {e}")
# Remove duplicates and sort by position
unique_expressions = self._deduplicate_expressions(expressions)
return unique_expressions
get_temporal_context¶
Get overall temporal context from expressions.
PARAMETER | DESCRIPTION |
---|---|
expressions | List of temporal expressions TYPE: |
RETURNS | DESCRIPTION |
---|---|
Dict[str, Any] | Temporal context summary |
Source code in tenets/core/prompt/temporal_parser.py
def get_temporal_context(self, expressions: List[TemporalExpression]) -> Dict[str, Any]:
"""Get overall temporal context from expressions.
Args:
expressions: List of temporal expressions
Returns:
Temporal context summary
"""
if not expressions:
return {
"has_temporal": False,
"timeframe": None,
"is_historical": False,
"is_future": False,
"is_current": False,
"has_recurring": False,
"expressions": 0,
"types": [],
"min_date": None,
"max_date": None,
}
# Find overall timeframe
all_dates = []
for expr in expressions:
if expr.start_date:
all_dates.append(expr.start_date)
if expr.end_date:
all_dates.append(expr.end_date)
if all_dates:
min_date = min(all_dates)
max_date = max(all_dates)
# Determine temporal orientation
now = self._now()
is_historical = max_date < now
is_future = min_date > now
is_current = min_date <= now <= max_date
# Calculate timeframe
if min_date == max_date:
timeframe = min_date.strftime("%Y-%m-%d")
else:
duration = max_date - min_date
if duration.days == 0:
timeframe = "today"
elif duration.days == 1:
timeframe = "1 day"
elif duration.days < 7:
timeframe = f"{duration.days} days"
elif duration.days < 30:
weeks = duration.days // 7
timeframe = f"{weeks} week{'s' if weeks > 1 else ''}"
elif duration.days < 365:
months = duration.days // 30
timeframe = f"{months} month{'s' if months > 1 else ''}"
else:
years = duration.days // 365
timeframe = f"{years} year{'s' if years > 1 else ''}"
else:
is_historical = False
is_future = False
is_current = True
timeframe = "unspecified"
min_date = None
max_date = None
# Check for recurring patterns
has_recurring = any(expr.is_recurring for expr in expressions)
return {
"has_temporal": True,
"timeframe": timeframe,
"is_historical": is_historical,
"is_future": is_future,
"is_current": is_current,
"has_recurring": has_recurring,
"expressions": len(expressions),
"types": list(set(expr.type for expr in expressions)),
"min_date": min_date.isoformat() if min_date else None,
"max_date": max_date.isoformat() if max_date else None,
}
extract_temporal_features¶
Extract all temporal features from text.
PARAMETER | DESCRIPTION |
---|---|
text | Text to analyze TYPE: |
RETURNS | DESCRIPTION |
---|---|
Dict[str, Any] | Dictionary with temporal features and context |
Source code in tenets/core/prompt/temporal_parser.py
def extract_temporal_features(self, text: str) -> Dict[str, Any]:
"""Extract all temporal features from text.
Args:
text: Text to analyze
Returns:
Dictionary with temporal features and context
"""
# Parse expressions
expressions = self.parse(text)
# Get temporal context
context = self.get_temporal_context(expressions)
# Add the parsed expressions
context["expressions_detail"] = [
{
"text": expr.text,
"type": expr.type,
"start": expr.start_date.isoformat() if expr.start_date else None,
"end": expr.end_date.isoformat() if expr.end_date else None,
"confidence": expr.confidence,
"timeframe": expr.timeframe,
"is_recurring": expr.is_recurring,
"recurrence": expr.recurrence_pattern,
}
for expr in expressions
]
return context