feat: improve tool-call bridging and env documentation
This commit is contained in:
@@ -40,7 +40,39 @@ def _pick_lingma_binary_path(inner_zip: zipfile.ZipFile) -> str:
|
||||
raise RuntimeError("Lingma binary not found inside nested zip")
|
||||
|
||||
|
||||
def _query_marketplace_latest_vsix(publisher: str, extension: str) -> tuple[str, str, dict]:
|
||||
def _infer_release_root(member_path: str) -> str:
|
||||
parts = [p for p in member_path.split("/") if p]
|
||||
if "x86_64_linux" in parts:
|
||||
idx = parts.index("x86_64_linux")
|
||||
if idx > 0:
|
||||
return "/".join(parts[:idx])
|
||||
if len(parts) > 1:
|
||||
return parts[0]
|
||||
return ""
|
||||
|
||||
|
||||
def _extract_release_tree(
|
||||
inner_zip: zipfile.ZipFile, release_root: str, out_dir: Path
|
||||
) -> None:
|
||||
prefix = f"{release_root}/" if release_root else ""
|
||||
for info in inner_zip.infolist():
|
||||
name = info.filename
|
||||
if not name or name.endswith("/"):
|
||||
continue
|
||||
if prefix and not name.startswith(prefix):
|
||||
continue
|
||||
rel = name[len(prefix) :] if prefix else name
|
||||
if not rel:
|
||||
continue
|
||||
dest = out_dir / rel
|
||||
dest.parent.mkdir(parents=True, exist_ok=True)
|
||||
with inner_zip.open(info, "r") as src, dest.open("wb") as dst:
|
||||
dst.write(src.read())
|
||||
|
||||
|
||||
def _query_marketplace_latest_vsix(
|
||||
publisher: str, extension: str
|
||||
) -> tuple[str, str, dict]:
|
||||
api = "https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery"
|
||||
payload = {
|
||||
"filters": [
|
||||
@@ -58,7 +90,9 @@ def _query_marketplace_latest_vsix(publisher: str, extension: str) -> tuple[str,
|
||||
"assetTypes": [],
|
||||
"flags": 950,
|
||||
}
|
||||
req = urllib.request.Request(api, data=json.dumps(payload).encode("utf-8"), method="POST")
|
||||
req = urllib.request.Request(
|
||||
api, data=json.dumps(payload).encode("utf-8"), method="POST"
|
||||
)
|
||||
req.add_header("accept", "application/json;api-version=3.0-preview.1")
|
||||
req.add_header("content-type", "application/json")
|
||||
req.add_header("x-market-client-id", "VSCode 1.115.0")
|
||||
@@ -83,7 +117,11 @@ def _query_marketplace_latest_vsix(publisher: str, extension: str) -> tuple[str,
|
||||
"https://marketplace.visualstudio.com/_apis/public/gallery/"
|
||||
f"publishers/{publisher}/vsextensions/{extension}/{version}/vspackage"
|
||||
)
|
||||
return vsix_url, version, {"publisher": publisher, "extension": extension, "version": version}
|
||||
return (
|
||||
vsix_url,
|
||||
version,
|
||||
{"publisher": publisher, "extension": extension, "version": version},
|
||||
)
|
||||
|
||||
|
||||
def bootstrap_from_vsix() -> None:
|
||||
@@ -106,7 +144,9 @@ def bootstrap_from_vsix() -> None:
|
||||
old_marker = {}
|
||||
if marker_path.exists():
|
||||
try:
|
||||
old_marker = json.loads(marker_path.read_text(encoding="utf-8", errors="ignore"))
|
||||
old_marker = json.loads(
|
||||
marker_path.read_text(encoding="utf-8", errors="ignore")
|
||||
)
|
||||
except Exception:
|
||||
old_marker = {}
|
||||
|
||||
@@ -115,15 +155,17 @@ def bootstrap_from_vsix() -> None:
|
||||
source_meta = {"source": source_type}
|
||||
if source_type == "marketplace":
|
||||
try:
|
||||
resolved_url, resolved_version, source_meta = _query_marketplace_latest_vsix(
|
||||
mp_publisher, mp_extension
|
||||
resolved_url, resolved_version, source_meta = (
|
||||
_query_marketplace_latest_vsix(mp_publisher, mp_extension)
|
||||
)
|
||||
print(
|
||||
f"[bootstrap] marketplace latest: {mp_publisher}.{mp_extension} "
|
||||
f"version={resolved_version}"
|
||||
)
|
||||
except Exception as exc:
|
||||
print(f"[bootstrap] marketplace query failed, fallback to LINGMA_VSIX_URL: {exc}")
|
||||
print(
|
||||
f"[bootstrap] marketplace query failed, fallback to LINGMA_VSIX_URL: {exc}"
|
||||
)
|
||||
resolved_url = vsix_url
|
||||
|
||||
if (
|
||||
@@ -144,9 +186,18 @@ def bootstrap_from_vsix() -> None:
|
||||
|
||||
print(f"[bootstrap] downloading VSIX: {resolved_url}")
|
||||
try:
|
||||
with urllib.request.urlopen(resolved_url, timeout=120) as r:
|
||||
data = r.read()
|
||||
vsix_path.write_bytes(data)
|
||||
with (
|
||||
urllib.request.urlopen(resolved_url, timeout=30) as r,
|
||||
vsix_path.open("wb") as f,
|
||||
):
|
||||
total = 0
|
||||
while True:
|
||||
chunk = r.read(1024 * 1024)
|
||||
if not chunk:
|
||||
break
|
||||
f.write(chunk)
|
||||
total += len(chunk)
|
||||
print(f"[bootstrap] VSIX downloaded bytes={total}")
|
||||
except Exception as exc:
|
||||
if lingma_bin.exists():
|
||||
print(f"[bootstrap] download failed, fallback to existing Lingma: {exc}")
|
||||
@@ -162,10 +213,18 @@ def bootstrap_from_vsix() -> None:
|
||||
with zipfile.ZipFile(io.BytesIO(nested_zip_bytes), "r") as inner_zip:
|
||||
lingma_member = _pick_lingma_binary_path(inner_zip)
|
||||
lingma_bytes = inner_zip.read(lingma_member)
|
||||
release_root = _infer_release_root(lingma_member)
|
||||
lingma_bin.parent.mkdir(parents=True, exist_ok=True)
|
||||
release_dir = lingma_bin.parent / (release_root or "2.5.20")
|
||||
_extract_release_tree(inner_zip, release_root, release_dir)
|
||||
|
||||
lingma_bin.parent.mkdir(parents=True, exist_ok=True)
|
||||
lingma_bin.write_bytes(lingma_bytes)
|
||||
os.chmod(lingma_bin, 0o755)
|
||||
extension_main = release_dir / "extension" / "main.js"
|
||||
if extension_main.exists():
|
||||
print(f"[bootstrap] extension ready: {extension_main}")
|
||||
else:
|
||||
print(f"[bootstrap] extension missing under: {release_dir}")
|
||||
|
||||
marker = {
|
||||
"source": source_type,
|
||||
@@ -174,6 +233,7 @@ def bootstrap_from_vsix() -> None:
|
||||
"downloaded_at": int(time.time()),
|
||||
"nested_zip": nested_zip_name,
|
||||
"member": lingma_member,
|
||||
"release_root": release_root,
|
||||
"size": len(lingma_bytes),
|
||||
}
|
||||
marker.update(source_meta)
|
||||
|
||||
Reference in New Issue
Block a user