"""Echo 节点入口。 通过 wov_sdk.server.run_node 启动标准节点 HTTP 服务,并注册 invoke 处理器。 节点启动后打印 WOV_NODE_READY 行,等待 wov-api 的 NodeManager 调用。 """ from __future__ import annotations import json from pathlib import Path from wov_sdk.models import InvokeRequest, InvokeResponse, NodeManifest from wov_sdk.server import run_node def _resolve_input_text(request: InvokeRequest, node_root: Path) -> str: """按优先级解析输入文本:直接文本 > 文件 URI > 默认字符串。""" # 优先使用请求中直接携带的 text 字段。 text = request.inputs.get("text") if text is not None: return str(text) # 其次读取 file_uri 指向的文件;相对路径以节点仓库根目录为基准。 file_uri = request.inputs.get("file_uri") if file_uri: path = Path(file_uri) if not path.is_absolute(): path = node_root / path return path.read_text(encoding="utf-8") # 都没有时返回固定文本,保证节点总有可演示的输出。 return "echo" def invoke(request: InvokeRequest) -> InvokeResponse: """处理节点调用:把解析出的文本写入产物并返回 URI。""" # 节点仓库根目录用于解析相对文件路径。 node_root = Path(__file__).resolve().parent.parent output_dir = Path(request.output_dir) output_dir.mkdir(parents=True, exist_ok=True) text = _resolve_input_text(request, node_root) # 产物必须落在请求给定的 output_dir,调度器按 run 与节点组织目录。 output_path = output_dir / "echo.txt" output_path.write_text(text, encoding="utf-8") return InvokeResponse( status="completed", outputs={ "text": text, "file_uri": str(output_path), }, ) def main() -> None: """加载节点清单并以本模块的 invoke 处理器启动服务。""" manifest_path = Path(__file__).resolve().parent.parent / "node.manifest.json" with open(manifest_path, "r", encoding="utf-8") as f: manifest = NodeManifest.from_dict(json.load(f)) run_node(manifest, invoke) if __name__ == "__main__": main()