Implement chatmark Form
This commit is contained in:
parent
9049046034
commit
7ffb03a857
90
libs/chatmark/form.py
Normal file
90
libs/chatmark/form.py
Normal file
@ -0,0 +1,90 @@
|
||||
from typing import List, Optional, Dict
|
||||
from .iobase import pipe_interaction
|
||||
from .widgets import Widget, Button
|
||||
|
||||
# TODO: 讨论以下是 feature or bug?
|
||||
# 1. chatmark语法: radio 无法指定默认选项
|
||||
# 2. chatmark实现:button 点完后显示个x
|
||||
# 3. chatmark实现:form 里不能有button
|
||||
|
||||
|
||||
class Form:
|
||||
"""
|
||||
A container for different widgets
|
||||
|
||||
Syntax:
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
components: List[Widget | str],
|
||||
title: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
components: components in the form, can be widgets (except Button) or strings
|
||||
title: title of the form
|
||||
"""
|
||||
assert (
|
||||
any(isinstance(c, Button) for c in components) is False
|
||||
), "Button is not allowed in Form"
|
||||
|
||||
self._components = components
|
||||
self._title = title
|
||||
|
||||
self._rendered = False
|
||||
|
||||
@property
|
||||
def components(self) -> List[Widget | str]:
|
||||
"""
|
||||
Return the components
|
||||
"""
|
||||
return self._components
|
||||
|
||||
def _in_chatmark(self) -> str:
|
||||
"""
|
||||
Generate ChatMark syntax for all components
|
||||
"""
|
||||
lines = []
|
||||
|
||||
if self._title:
|
||||
lines.append(self._title)
|
||||
|
||||
for c in self.components:
|
||||
if isinstance(c, str):
|
||||
lines.append(c)
|
||||
elif isinstance(c, Widget):
|
||||
lines.append(c._in_chatmark())
|
||||
else:
|
||||
raise ValueError(f"Invalid component {c}")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
def _parse_response(self, response: Dict):
|
||||
"""
|
||||
Parse response from user input
|
||||
"""
|
||||
for c in self.components:
|
||||
if isinstance(c, Widget):
|
||||
c._parse_response(response)
|
||||
|
||||
def render(self):
|
||||
"""
|
||||
Render to receive user input
|
||||
"""
|
||||
if self._rendered:
|
||||
# already rendered once
|
||||
# not sure if the constraint is necessary
|
||||
# could be removed if re-rendering is needed
|
||||
raise RuntimeError("Widget can only be rendered once")
|
||||
|
||||
self._rendered = True
|
||||
|
||||
lines = [
|
||||
"```chatmark type=form",
|
||||
self._in_chatmark(),
|
||||
"```",
|
||||
]
|
||||
|
||||
chatmark = "\n".join(lines)
|
||||
response = pipe_interaction(chatmark)
|
||||
self._parse_response(response)
|
Loading…
x
Reference in New Issue
Block a user