mirror of
https://github.com/langchain-ai/docs.git
synced 2026-07-19 16:33:35 -04:00
134 lines
4.6 KiB
Python
134 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
import urllib.request
|
|
from pathlib import Path
|
|
from urllib.parse import urlsplit, urlunsplit
|
|
from typing import Any
|
|
|
|
|
|
# Ref API JSON (?format=json). For JS, the config object matches CreateDeepAgentParams
|
|
# (the argument to `createDeepAgent`); see
|
|
# https://reference.langchain.com/api/ref/javascript/deepagents/types/CreateDeepAgentParams
|
|
PYTHON_REF_JSON_URL = "https://reference.langchain.com/api/ref/python/deepagents/create_deep_agent?format=json"
|
|
JS_CREATE_DEEP_AGENT_PARAMS_JSON_URL = "https://reference.langchain.com/api/ref/javascript/deepagents/types/CreateDeepAgentParams?format=json"
|
|
|
|
PY_SNIPPET_PATH = Path("src/snippets/create-deep-agent-config-options-py.mdx")
|
|
JS_SNIPPET_PATH = Path("src/snippets/create-deep-agent-config-options-js.mdx")
|
|
|
|
|
|
def _strip_query_and_fragment(url: str) -> str:
|
|
parts = urlsplit(url)
|
|
return urlunsplit((parts.scheme, parts.netloc, parts.path, "", ""))
|
|
|
|
|
|
def _normalize_fetch_url(url: str) -> str:
|
|
base = _strip_query_and_fragment(url)
|
|
return f"{base}?format=json" if "format=" not in url else url
|
|
|
|
|
|
def _fetch_json(url: str) -> Any:
|
|
req = urllib.request.Request(
|
|
_normalize_fetch_url(url),
|
|
headers={
|
|
"User-Agent": "langchain-docs-sync-bot/1.0",
|
|
"Accept": "application/json",
|
|
},
|
|
)
|
|
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
charset = resp.headers.get_content_charset() or "utf-8"
|
|
return json.loads(resp.read().decode(charset))
|
|
|
|
|
|
def _render_js_config_snippet(member_name_types: list[tuple[str, str]]) -> str:
|
|
"""
|
|
Render a docs-friendly createDeepAgent config object snippet that focuses on the
|
|
parameter surface, not the full generic function signature.
|
|
Order and types come from the CreateDeepAgentParams JSON (members list).
|
|
"""
|
|
ordered: list[tuple[str, str]] = []
|
|
seen: set[str] = set()
|
|
for name, typ in member_name_types:
|
|
if name not in seen:
|
|
ordered.append((name, typ))
|
|
seen.add(name)
|
|
|
|
lines = ["const agent = createDeepAgent({"]
|
|
for i, (key, hint) in enumerate(ordered):
|
|
suffix = "," if i < len(ordered) - 1 else ""
|
|
lines.append(f" {key}?: {hint}{suffix}")
|
|
lines.append("});")
|
|
return "```typescript\n" + "\n".join(lines) + "\n```\n"
|
|
|
|
|
|
def _py_signature_from_json(data: dict[str, Any]) -> str:
|
|
try:
|
|
code = data["signature"]
|
|
except KeyError as e:
|
|
raise RuntimeError("Python ref JSON missing 'signature'") from e
|
|
code = code.rstrip()
|
|
# API reference often has a trailing comma after the last param; the docs prefer omitting it.
|
|
code = re.sub(r",(\n\s*)\) ->", r"\1) ->", code, count=1)
|
|
return f"```python\n{code}\n```\n"
|
|
|
|
|
|
def _js_members_name_types(data: dict[str, Any]) -> list[tuple[str, str]]:
|
|
try:
|
|
members = data["members"]
|
|
except KeyError as e:
|
|
raise RuntimeError("CreateDeepAgentParams JSON missing 'members'") from e
|
|
out: list[tuple[str, str]] = []
|
|
for m in members:
|
|
if m.get("kind") != "property" or m.get("visibility") != "public":
|
|
continue
|
|
name = m.get("name")
|
|
typ = m.get("type")
|
|
if not isinstance(name, str) or not isinstance(typ, str):
|
|
continue
|
|
out.append((name, typ))
|
|
if not out:
|
|
raise RuntimeError("No public properties found on CreateDeepAgentParams JSON")
|
|
return out
|
|
|
|
|
|
def _write_if_changed(path: Path, new_content: str) -> bool:
|
|
old = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
if old == new_content:
|
|
return False
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_text(new_content, encoding="utf-8")
|
|
return True
|
|
|
|
|
|
def main() -> int:
|
|
py_data = _fetch_json(PYTHON_REF_JSON_URL)
|
|
js_params_data = _fetch_json(JS_CREATE_DEEP_AGENT_PARAMS_JSON_URL)
|
|
|
|
if not isinstance(py_data, dict) or not isinstance(js_params_data, dict):
|
|
raise RuntimeError("Unexpected JSON root type from ref API")
|
|
|
|
py_block = _py_signature_from_json(py_data)
|
|
|
|
if js_params_data.get("name") != "CreateDeepAgentParams":
|
|
raise RuntimeError("CreateDeepAgentParams ref JSON missing expected name")
|
|
|
|
js_member_tuples = _js_members_name_types(js_params_data)
|
|
js_block = _render_js_config_snippet(js_member_tuples)
|
|
|
|
changed = False
|
|
changed |= _write_if_changed(PY_SNIPPET_PATH, py_block)
|
|
changed |= _write_if_changed(JS_SNIPPET_PATH, js_block)
|
|
|
|
if changed:
|
|
print("Updated deepagents signature snippets.")
|
|
else:
|
|
print("No deepagents signature snippet changes detected.")
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|