Files
wehub-resource-sync 4e0f4422d0
Check Markdown links / markdown-link-check (push) Waiting to run
Pytest / test (3.11) (push) Waiting to run
Pytest / test (3.12) (push) Waiting to run
build-docs / deploy (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:25:42 +08:00

109 lines
3.9 KiB
Python

import re
from collections.abc import Callable
from typing import Any
from sweagent.tools.commands import Command
def _guard_multiline_input(action: str, match_fct: Callable[[str], re.Match | None]) -> str:
"""Split action by multiline commands, then append the first line in each multiline command with "<< '{end_name}'".
Multiline commands (which are specified by an end_name) are commands that span multiple lines and are terminated by a specific end_name.
Their multi-line argument is sent using a heredoc, which is a way to send a multi-line string to a command in bash.
"""
parsed_action = []
rem_action = action
while rem_action.strip():
first_match = match_fct(rem_action)
if first_match:
pre_action = rem_action[: first_match.start()]
match_action = rem_action[first_match.start() : first_match.end()]
rem_action = rem_action[first_match.end() :]
if pre_action.strip():
parsed_action.append(pre_action)
if match_action.strip():
eof = first_match.group(3).strip()
if not match_action.split("\n")[0].strip().endswith(f"<< '{eof}'"):
guarded_command = match_action[first_match.start() :]
first_line = guarded_command.split("\n")[0]
guarded_command = guarded_command.replace(first_line, first_line + f" << '{eof}'", 1)
parsed_action.append(guarded_command)
else:
parsed_action.append(match_action)
else:
parsed_action.append(rem_action)
rem_action = ""
return "\n".join(parsed_action)
def _should_quote(value: Any, command: Command) -> bool:
"""Returns True if the value should be quoted, False otherwise."""
if command.name == "bash":
return False
return isinstance(value, str) and command.end_name is None
def get_signature(cmd):
"""Generate a command signature from its arguments.
Args:
cmd: Command object to generate signature for
Returns:
Formatted signature string
"""
signature = cmd.name
if "arguments" in cmd.__dict__ and cmd.arguments is not None:
if cmd.end_name is None:
for argument in cmd.arguments:
param = argument.name
if argument.required:
signature += f" <{param}>"
else:
signature += f" [<{param}>]"
else:
for argument in cmd.arguments[:-1]:
param = argument.name
if argument.required:
signature += f" <{param}>"
else:
signature += f" [<{param}>]"
signature += f"\n{list(cmd.arguments[-1].keys())[0]}\n{cmd.end_name}"
return signature
def generate_command_docs(
commands: list[Command],
subroutine_types,
**kwargs,
) -> str:
"""Generate detailed command documentation.
Format includes docstring, signature and argument details.
Args:
commands: List of commands to document
subroutine_types: List of subroutines to document
**kwargs: Additional format variables for docstrings
Returns:
Formatted documentation string
"""
docs = ""
for cmd in commands + subroutine_types:
docs += f"{cmd.name}:\n"
if cmd.docstring is not None:
docs += f" docstring: {cmd.docstring.format(**kwargs)}\n"
if cmd.signature is not None:
docs += f" signature: {cmd.signature}\n"
else:
docs += f" signature: {get_signature(cmd)}\n"
if cmd.arguments:
docs += " arguments:\n"
for argument in cmd.arguments:
param = argument.name
req_string = "required" if argument.required else "optional"
docs += f" - {param} ({argument.type}) [{req_string}]: {argument.description}\n"
docs += "\n"
return docs