chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
from typing import Any, Optional, Generic, TypeVar, Literal, TypedDict, Union, Dict
|
||||
from dataclasses import dataclass
|
||||
from abc import ABC, abstractmethod
|
||||
import random
|
||||
import string
|
||||
|
||||
from .widget_component import WidgetComponent
|
||||
from ..constants import SKILL_LOCALE_CONFIG, INTENT_OBJECT
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
UtteranceSender = Literal['leon', 'owner']
|
||||
|
||||
|
||||
class SendUtteranceWidgetEventMethodParams(TypedDict):
|
||||
from_: UtteranceSender
|
||||
utterance: str
|
||||
|
||||
|
||||
class RunSkillActionWidgetEventMethodParams(TypedDict):
|
||||
action_name: str
|
||||
params: Dict[str, Any]
|
||||
|
||||
|
||||
class SendUtteranceOptions(TypedDict, total=False):
|
||||
from_: Optional[UtteranceSender]
|
||||
data: Optional[Dict[str, Any]]
|
||||
|
||||
|
||||
class WidgetEventMethod(TypedDict):
|
||||
methodName: Literal['send_utterance', 'run_skill_action']
|
||||
methodParams: Union[
|
||||
SendUtteranceWidgetEventMethodParams,
|
||||
RunSkillActionWidgetEventMethodParams
|
||||
]
|
||||
|
||||
|
||||
@dataclass
|
||||
class WidgetOptions(Generic[T]):
|
||||
wrapper_props: dict[str, Any] = None
|
||||
params: T = None
|
||||
on_fetch: Optional[dict[str, Any]] = None
|
||||
|
||||
|
||||
class Widget(ABC, Generic[T]):
|
||||
def __init__(self, options: WidgetOptions[T]):
|
||||
if options.wrapper_props:
|
||||
self.wrapper_props = options.wrapper_props
|
||||
else:
|
||||
self.wrapper_props = None
|
||||
self.action_name = f"{INTENT_OBJECT['skill_name']}:{INTENT_OBJECT['action_name']}"
|
||||
self.params = options.params
|
||||
self.widget = self.__class__.__name__
|
||||
if options.on_fetch:
|
||||
self.on_fetch = {
|
||||
'widgetId': options.on_fetch.get('widget_id'),
|
||||
'actionName': f"{INTENT_OBJECT['skill_name']}:{options.on_fetch.get('action_name')}"
|
||||
}
|
||||
else:
|
||||
self.on_fetch = None
|
||||
self.id = options.on_fetch.get('widget_id') if options.on_fetch \
|
||||
else f"{self.widget.lower()}-{''.join(random.choices(string.ascii_lowercase + string.digits, k=8))}"
|
||||
|
||||
@abstractmethod
|
||||
def render(self) -> WidgetComponent:
|
||||
pass
|
||||
|
||||
def send_utterance(self, key: str, options: Optional[Dict[str, Any]] = None) -> WidgetEventMethod:
|
||||
"""
|
||||
Indicate the core to send a given utterance
|
||||
:param key: The key of the content
|
||||
:param options: The options of the utterance
|
||||
"""
|
||||
utterance_content = self.content(key, options.get('data') if options else None)
|
||||
from_ = options.get('from', 'owner') if options else 'owner'
|
||||
|
||||
return WidgetEventMethod(
|
||||
methodName='send_utterance',
|
||||
methodParams={
|
||||
'from': from_,
|
||||
'utterance': utterance_content
|
||||
}
|
||||
)
|
||||
|
||||
def run_skill_action(self, action_name: str, params: Dict[str, Any]) -> WidgetEventMethod:
|
||||
"""
|
||||
Indicate the core to run a given skill action
|
||||
:param action_name: The name of the action
|
||||
:param params: The parameters of the action
|
||||
"""
|
||||
return WidgetEventMethod(
|
||||
methodName='run_skill_action',
|
||||
methodParams={
|
||||
'actionName': action_name,
|
||||
'params': params
|
||||
}
|
||||
)
|
||||
|
||||
def content(self, key: str, data: Optional[Dict[str, Any]] = None) -> str:
|
||||
"""
|
||||
Grab and compute the target content of the widget
|
||||
:param key: The key of the content
|
||||
:param data: The data to apply
|
||||
"""
|
||||
widget_contents = SKILL_LOCALE_CONFIG.get('widget_contents', {})
|
||||
|
||||
if key not in widget_contents:
|
||||
return 'INVALID'
|
||||
|
||||
content = widget_contents[key]
|
||||
|
||||
if isinstance(content, list):
|
||||
content = random.choice(content)
|
||||
|
||||
if data:
|
||||
for k, v in data.items():
|
||||
content = content.replace(f"{{{{ {key} }}}}", str(v))
|
||||
|
||||
return content
|
||||
Reference in New Issue
Block a user