Merge branch 'master' into dev

Resolved all conflicts using dev (HEAD) version:
- func_tool_manager.py: migrated old implementation into new architecture
- tool_loop_agent_runner.py: preserve lazy_load mode, remove step limit
- Platform adapters, dashboard, core modules: use HEAD version
This commit is contained in:
LIghtJUNction
2026-04-10 20:58:41 +08:00
17 changed files with 1932 additions and 304 deletions
+15 -8
View File
@@ -147,7 +147,6 @@ def iter_markdown_links(content: str):
This scanner intentionally handles inline `[]()` links used in the docs tree.
It does not parse reference-style links or arbitrary HTML.
"""
index = 0
while index < len(content):
label_start = content.find("[", index)
@@ -292,7 +291,9 @@ class LinkResolver:
self.source_pages = discover_source_pages(str(self.source_root))
def resolve_base_target(
self, base_target: str, source_path: str
self,
base_target: str,
source_path: str,
) -> ResolutionResult:
return resolve_link_path(
base_target=base_target,
@@ -302,7 +303,9 @@ class LinkResolver:
)
def resolve_markdown_target(
self, target: str, source_path: str
self,
target: str,
source_path: str,
) -> tuple[str | None, str]:
parsed_target = parse_doc_target(target)
if parsed_target is None:
@@ -386,7 +389,7 @@ def rewrite_links(
segment.text,
source_path=source_path,
resolver=resolver,
)
),
)
continue
@@ -404,7 +407,8 @@ def find_unresolved_doc_links(source_root: Path) -> list[str]:
content = (root / source_path).read_text(encoding="utf-8")
for link in iter_markdown_links(content):
resolved_path, _ = resolver.resolve_markdown_target(
link.target, source_path
link.target,
source_path,
)
if resolved_path is not None:
continue
@@ -523,7 +527,9 @@ def build_sidebar(page_infos: list[PageInfo]) -> str:
def build_page_info(
source_root: Path, source_path: str, resolver: LinkResolver
source_root: Path,
source_path: str,
resolver: LinkResolver,
) -> PageInfo:
source_file = source_root / source_path
content = source_file.read_text(encoding="utf-8")
@@ -608,7 +614,7 @@ def sync_docs_to_wiki(source_root: Path, wiki_root: Path) -> None:
def main() -> int:
parser = argparse.ArgumentParser(
description="Sync AstrBot docs content to GitHub wiki pages."
description="Sync AstrBot docs content to GitHub wiki pages.",
)
parser.add_argument(
"--source-root",
@@ -635,7 +641,8 @@ def main() -> int:
return 0
sync_docs_to_wiki(
source_root=Path(args.source_root), wiki_root=Path(args.wiki_root)
source_root=Path(args.source_root),
wiki_root=Path(args.wiki_root),
)
return 0
+18 -7
View File
@@ -27,7 +27,8 @@ IMAGE_EXTS = {
MD_IMAGE_RE = re.compile(r"!\[[^\]]*\]\(([^)]+)\)")
HTML_IMG_RE = re.compile(
r"<img\b[^>]*\bsrc\s*=\s*([\"'])([^\"']+)\1[^>]*>", re.IGNORECASE
r"<img\b[^>]*\bsrc\s*=\s*([\"'])([^\"']+)\1[^>]*>",
re.IGNORECASE,
)
logger = logging.getLogger(__name__)
@@ -35,7 +36,7 @@ logger = logging.getLogger(__name__)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Upload all locally referenced images from Markdown docs to Cloudflare R2 using rclone."
description="Upload all locally referenced images from Markdown docs to Cloudflare R2 using rclone.",
)
parser.add_argument("--remote", required=True, help="rclone remote name, e.g. r2")
parser.add_argument("--bucket", default="", help="bucket name in remote path")
@@ -50,10 +51,14 @@ def parse_args() -> argparse.Namespace:
help="docs root to scan for .md files (default: current directory)",
)
parser.add_argument(
"--dry-run", action="store_true", help="preview uploads without sending files"
"--dry-run",
action="store_true",
help="preview uploads without sending files",
)
parser.add_argument(
"--list-only", action="store_true", help="only print matched image files"
"--list-only",
action="store_true",
help="only print matched image files",
)
parser.add_argument(
"--rewrite-markdown",
@@ -137,7 +142,8 @@ def find_markdown_files(root: Path) -> list[Path]:
def collect_images(
root: Path, md_files: Sequence[Path]
root: Path,
md_files: Sequence[Path],
) -> tuple[set[Path], list[tuple[Path, str]]]:
images: set[Path] = set()
missing: list[tuple[Path, str]] = []
@@ -193,7 +199,10 @@ def build_public_url(base: str, object_path: str) -> str:
def run_rclone_upload(
root: Path, target: str, rel_files: Iterable[str], dry_run: bool
root: Path,
target: str,
rel_files: Iterable[str],
dry_run: bool,
) -> None:
if shutil.which("rclone") is None:
raise RuntimeError("rclone not found in PATH")
@@ -263,7 +272,9 @@ def rewrite_markdown_files(
if not url:
return match.group(0)
return match.group(0).replace(
f"src={quote_ch}{raw}{quote_ch}", f"src={quote_ch}{url}{quote_ch}", 1
f"src={quote_ch}{raw}{quote_ch}",
f"src={quote_ch}{url}{quote_ch}",
1,
)
updated = MD_IMAGE_RE.sub(md_repl, text)