Update
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .schema import InteractionRequest, WidgetModel, flatten_widgets
|
||||
|
||||
|
||||
def project_markdown(request: InteractionRequest, interaction_id: str) -> str:
|
||||
lines: list[str] = [f"### {request.title}", ""]
|
||||
if request.description:
|
||||
lines.append(request.description)
|
||||
lines.append("")
|
||||
for widget in request.widgets:
|
||||
lines.extend(_widget_lines(widget))
|
||||
actions = f"[{request.submit_label}]"
|
||||
if request.cancelable:
|
||||
actions += f" [{request.cancel_label}]"
|
||||
lines.append("")
|
||||
lines.append(actions)
|
||||
lines.append(f"<!-- ai-interaction:{interaction_id} -->")
|
||||
return "\n".join(lines).strip() + "\n"
|
||||
|
||||
|
||||
def project_plain_menu(request: InteractionRequest) -> str:
|
||||
lines: list[str] = [request.title]
|
||||
if request.description:
|
||||
lines.append(request.description)
|
||||
lines.append("")
|
||||
widgets = [
|
||||
w
|
||||
for w in flatten_widgets(request.widgets)
|
||||
if w.type != "//"
|
||||
]
|
||||
if len(widgets) == 1 and widgets[0].type == "confirm":
|
||||
lines.append(f"Reply: yes | no | cancel")
|
||||
return "\n".join(lines).strip() + "\n"
|
||||
if len(widgets) == 1 and widgets[0].type in ("choice", "select"):
|
||||
options = widgets[0].options[:12]
|
||||
lines.append(f"{widgets[0].label}")
|
||||
for index, option in enumerate(options, start=1):
|
||||
lines.append(f"{index}. {option.label} (`{option.value}`)")
|
||||
lines.append("")
|
||||
lines.append(f"Reply with a number (1-{len(options)}) or `cancel`.")
|
||||
return "\n".join(lines).strip() + "\n"
|
||||
for widget in widgets:
|
||||
if widget.type in ("choice", "choice_multi", "select"):
|
||||
lines.append(f"{widget.label}:")
|
||||
for index, option in enumerate(widget.options[:12], start=1):
|
||||
lines.append(f" {index}. {option.label} (`{option.value}`)")
|
||||
elif widget.type == "confirm":
|
||||
lines.append(f"{widget.label}: yes | no")
|
||||
else:
|
||||
lines.append(f"{widget.label}: (free text)")
|
||||
lines.append("")
|
||||
lines.append("Reply with values, or `cancel`.")
|
||||
return "\n".join(lines).strip() + "\n"
|
||||
|
||||
|
||||
def _widget_lines(widget: WidgetModel, indent: str = "") -> list[str]:
|
||||
if widget.type == "//":
|
||||
return [f"{indent}{widget.text or widget.label}", ""]
|
||||
if widget.type == "group":
|
||||
lines = [f"{indent}**{widget.label}**", ""]
|
||||
for child in widget.widgets:
|
||||
lines.extend(_widget_lines(child, indent + " "))
|
||||
return lines
|
||||
req = "required" if widget.required else "optional"
|
||||
lines = [f"{indent}- [ ] **{widget.name}** ({req}) — {widget.label}"]
|
||||
if widget.help:
|
||||
lines.append(f"{indent} _{widget.help}_")
|
||||
if widget.type == "confirm":
|
||||
default = widget.default
|
||||
yes = "•" if default is True else " "
|
||||
no = "•" if default is False else " "
|
||||
lines.append(f"{indent} - ({yes}) `true` — Yes")
|
||||
lines.append(f"{indent} - ({no}) `false` — No")
|
||||
elif widget.type in ("choice", "select"):
|
||||
default = str(widget.default) if widget.default is not None else ""
|
||||
for option in widget.options:
|
||||
mark = "•" if option.value == default else " "
|
||||
desc = f" — {option.description}" if option.description else ""
|
||||
lines.append(
|
||||
f"{indent} - ({mark}) `{option.value}` — {option.label}{desc}"
|
||||
)
|
||||
elif widget.type == "choice_multi":
|
||||
defaults = set(widget.default or []) if isinstance(widget.default, list) else set()
|
||||
for option in widget.options:
|
||||
mark = "x" if option.value in defaults else " "
|
||||
desc = f" — {option.description}" if option.description else ""
|
||||
lines.append(
|
||||
f"{indent} - [{mark}] `{option.value}` — {option.label}{desc}"
|
||||
)
|
||||
elif widget.type == "text":
|
||||
extra = f", max {widget.max_length}" if widget.max_length else ""
|
||||
lines.append(f"{indent} - _free text{extra}_")
|
||||
elif widget.type == "number":
|
||||
parts = []
|
||||
if widget.min is not None:
|
||||
parts.append(f"min {widget.min}")
|
||||
if widget.max is not None:
|
||||
parts.append(f"max {widget.max}")
|
||||
hint = (", " + ", ".join(parts)) if parts else ""
|
||||
lines.append(f"{indent} - _number{hint}_")
|
||||
elif widget.type == "date":
|
||||
lines.append(f"{indent} - _date DD/MM/YYYY_")
|
||||
return lines
|
||||
Reference in New Issue
Block a user