85 lines
2.2 KiB
Python
85 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
from enum import Enum
|
|
from typing import Any
|
|
|
|
from ...llm.chat_context import Instructions
|
|
from ...types import NOT_GIVEN, NotGivenOr
|
|
from ...utils import is_given
|
|
|
|
|
|
class DtmfEvent(str, Enum):
|
|
ONE = "1"
|
|
TWO = "2"
|
|
THREE = "3"
|
|
FOUR = "4"
|
|
FIVE = "5"
|
|
SIX = "6"
|
|
SEVEN = "7"
|
|
EIGHT = "8"
|
|
NINE = "9"
|
|
ZERO = "0"
|
|
STAR = "*"
|
|
POUND = "#"
|
|
A = "A"
|
|
B = "B"
|
|
C = "C"
|
|
D = "D"
|
|
|
|
|
|
def dtmf_event_to_code(event: DtmfEvent) -> int:
|
|
if event.value.isdigit():
|
|
return int(event.value)
|
|
elif event.value == "*":
|
|
return 10
|
|
elif event.value == "#":
|
|
return 11
|
|
elif event.value in ["A", "B", "C", "D"]:
|
|
# DTMF codes 10-15 are used for letters A-D
|
|
return ord(event.value) - ord("A") + 12
|
|
else:
|
|
raise ValueError(f"Invalid DTMF event: {event}")
|
|
|
|
|
|
def format_dtmf(events: list[DtmfEvent]) -> str:
|
|
return " ".join(event.value for event in events)
|
|
|
|
|
|
class WorkflowInstructions(Instructions):
|
|
"""Customizable instruction sections for built-in workflow tasks.
|
|
|
|
Extends :class:`Instructions` with ``persona`` and ``extra`` fields
|
|
that workflow tasks resolve against their own templates and defaults.
|
|
|
|
Each field overrides that section when set; leave as ``NOT_GIVEN`` to
|
|
preserve the workflow's built-in default. Set to ``""`` to remove a
|
|
section entirely.
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
audio: str = "",
|
|
*,
|
|
text: str | None = None,
|
|
persona: NotGivenOr[Instructions | str] = NOT_GIVEN,
|
|
extra: Instructions | str = "",
|
|
) -> None:
|
|
super().__init__(audio=audio, text=text)
|
|
self.persona: NotGivenOr[Instructions | str] = persona
|
|
self.extra: Instructions | str = extra
|
|
|
|
def resolve(
|
|
self,
|
|
*,
|
|
template: str,
|
|
default_persona: str,
|
|
**format_kwargs: Any,
|
|
) -> Instructions:
|
|
"""Resolve into a final :class:`Instructions` by formatting the template."""
|
|
return Instructions.resolve_template(
|
|
template,
|
|
persona=self.persona if is_given(self.persona) else default_persona,
|
|
extra=self.extra,
|
|
**format_kwargs,
|
|
)
|