fix: empty-list scope, get_tree bool casing, md fence tracking; dedupe base URL

- local get_agent_tools: `set(doc_ids) if doc_ids is not None else None` so
  doc_ids=[] is a scope of nothing (reject all), not open mode. The public
  query path already guarded []; this hardens direct callers.
- legacy get_tree: send summary=true/false (lowercase) instead of Python's
  capitalized True/False, matching the modern CloudBackend and the API.
- markdown parser: track the opening fence character so a ```-fence isn't
  closed by a ~~~ line (CommonMark), keeping '#'-lines inside it out of headings.
- dedupe the cloud base URL: single API_BASE in cloud_api, referenced by
  CloudBackend and PageIndexClient (was three independent copies).

Regression tests for each.
This commit is contained in:
mountain 2026-07-10 11:17:20 +08:00
parent e18ccdeaf8
commit d97231b480
8 changed files with 83 additions and 15 deletions

View file

@ -8,11 +8,16 @@ import requests
from .errors import PageIndexAPIError
# Single source of truth for the cloud API base URL — imported by the modern
# CloudBackend (as API_BASE) and PageIndexClient so a staging/migration change
# only has to happen here.
API_BASE = "https://api.pageindex.ai"
class LegacyCloudAPI:
"""Compatibility layer for the pageindex 0.2.x cloud SDK API."""
BASE_URL = "https://api.pageindex.ai"
BASE_URL = API_BASE
def __init__(self, api_key: str, base_url: str | None = None):
self.api_key = api_key
@ -85,7 +90,11 @@ class LegacyCloudAPI:
def get_tree(self, doc_id: str, node_summary: bool = False) -> dict[str, Any]:
response = self._request(
"GET",
f"/doc/{self._enc(doc_id)}/?type=tree&summary={node_summary}",
# Lowercase the bool: a Python f-string renders True/False with a
# capital letter, but the API expects summary=true/false (the modern
# CloudBackend sends lowercase). A case-sensitive server would
# otherwise silently drop node summaries.
f"/doc/{self._enc(doc_id)}/?type=tree&summary={'true' if node_summary else 'false'}",
"Failed to get tree result",
)
return response.json()