sycommon-python-lib 0.2.8a7__py3-none-any.whl → 0.2.8a8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sycli/cli.py CHANGED
@@ -173,6 +173,11 @@ def _create_parser() -> argparse.ArgumentParser:
173
173
  p_acp.add_argument("--config", "-c", help="Path to ACP config file (default: .sycli/acp.yaml)")
174
174
  p_acp.add_argument("--project-root", "-r", default=".", help="Project root directory")
175
175
 
176
+ # ── acp-serve ──
177
+ p_acp_serve = sub.add_parser(
178
+ "acp-serve", help="Serve a DeepAgent as Zed ACP agent over stdio (LLM-backed)")
179
+ p_acp_serve.add_argument("--project-root", "-r", default=".", help="Project root directory")
180
+
176
181
  # ── version ──
177
182
  sub.add_parser("version", help="Show version")
178
183
 
@@ -243,6 +248,10 @@ def main() -> None:
243
248
  from sycli.commands.acp_cmd import handle_acp
244
249
  sys.exit(handle_acp(args))
245
250
 
251
+ elif args.command == "acp-serve":
252
+ from sycli.commands.acp_serve_cmd import handle_acp_serve
253
+ sys.exit(handle_acp_serve(args))
254
+
246
255
 
247
256
  def _handle_status(args) -> None:
248
257
  """Show current RL state."""
@@ -0,0 +1,113 @@
1
+ """sycli acp-serve command — 把 DeepAgent 起成 Zed ACP agent(stdio)。
2
+
3
+ 与 `sycli acp` 的区别:
4
+ - acp:把 .sycli/acp.yaml 里的静态 CLI 工具暴露成 ACP agent(无 LLM,纯命令路由)。
5
+ - acp-serve:把一个真的 DeepAgent(LLM + 本地 shell 后端)暴露成 ACP agent,
6
+ Zed/其它 ACP client 连上后即可对话式驱动它干活。
7
+
8
+ stdio 约定:stdout 是 JSON-RPC 通道,一切诊断输出走 stderr。
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import signal
14
+ import sys
15
+ from pathlib import Path
16
+
17
+
18
+ def _e(msg: str) -> None:
19
+ """stderr 诊断输出(stdout 留给 JSON-RPC)。"""
20
+ print(f" {msg}", file=sys.stderr)
21
+
22
+
23
+ def handle_acp_serve(args) -> int:
24
+ """Handle `sycli acp-serve` command.
25
+
26
+ Flow:
27
+ 1. Resolve project root, load sycli.json(LLM 配置)
28
+ 2. Build DeepAgent graph(LLM + LocalShellBackend)
29
+ 3. Serve over stdio as Zed ACP agent (blocking)
30
+
31
+ Args:
32
+ args: Parsed argparse namespace with project_root.
33
+
34
+ Returns:
35
+ Exit code (0 for success, 1 for error).
36
+ """
37
+ project_root = Path(args.project_root or ".").resolve()
38
+ config_path = project_root / ".sycli" / "sycli.json"
39
+
40
+ from sycli.models.config_models import SycliConfig
41
+
42
+ config = SycliConfig.load(config_path)
43
+ issues = config.validate_config()
44
+ fatal = [i for i in issues if "base_url" in i or "api_key" in i]
45
+ if fatal:
46
+ for i in fatal:
47
+ _e(f"✘ Config: {i}")
48
+ _e("✘ LLM 未配置,无法启动 DeepAgent。先运行 `sycli init` 或检查 sycli.json。")
49
+ return 1
50
+
51
+ # Print summary to stderr(stdout 留给 stdio JSON-RPC)
52
+ _e("═" * 60)
53
+ _e("Zed ACP DeepAgent Server")
54
+ _e(f" Project: {project_root}")
55
+ _e(f" Config: {config_path if config_path.exists() else '(defaults)'}")
56
+ _e(f" Model: {config.llm.model} @ {config.llm.resolved_base_url()}")
57
+ _e(" Transport: stdio (JSON-RPC)")
58
+ _e("─" * 60)
59
+
60
+ # Build DeepAgent graph(延迟导入:出错时不污染 stdout)
61
+ def _build_graph():
62
+ from deepagents import create_deep_agent
63
+ from sycli.agents.factory import build_subagents
64
+ from sycli.core.backend import create_backend
65
+ from sycli.core.llm import create_llm
66
+
67
+ llm = create_llm(config.llm, streaming=True)
68
+ backend = create_backend(project_root)
69
+ subagents = build_subagents(config, llm, backend, project_name=project_root.name, mode="serve", project_root=str(project_root))
70
+ return create_deep_agent(
71
+ model=llm,
72
+ backend=backend,
73
+ system_prompt=(
74
+ "你是 sycli DeepAgent,正通过 ACP 协议被远程 client 驱动。"
75
+ "在项目根目录内完成任务;需要拆解任务时用 write_todos 维护计划。"
76
+ ),
77
+ subagents=subagents,
78
+ checkpointer=None, # langchain-acp 适配层自动挂进程内 checkpointer
79
+ debug=False,
80
+ name="sycli-acp-serve",
81
+ )
82
+
83
+ from sycommon.agent.acp.server_adapter import serve_graph
84
+
85
+ _shutdown = False
86
+
87
+ def _signal_handler(sig, frame):
88
+ nonlocal _shutdown
89
+ if _shutdown:
90
+ sys.exit(1)
91
+ _shutdown = True
92
+ _e("⚠ Shutting down ACP DeepAgent...")
93
+
94
+ signal.signal(signal.SIGINT, _signal_handler)
95
+
96
+ try:
97
+ serve_graph(
98
+ graph_factory=_build_graph,
99
+ agent_name="sycli-deepagent",
100
+ agent_title="sycli DeepAgent",
101
+ )
102
+ except KeyboardInterrupt:
103
+ _e("⚠ ACP DeepAgent stopped.")
104
+ return 0
105
+ except Exception as e:
106
+ _e(f"✘ ACP server failed: {e}")
107
+ import traceback
108
+
109
+ traceback.print_exc(file=sys.stderr)
110
+ return 1
111
+
112
+ return 0
113
+
@@ -0,0 +1,99 @@
1
+ """ACP server 适配器——把 LangGraph/DeepAgent graph 暴露成 ACP agent(stdio)。
2
+
3
+ 与 client.py 相反的方向:client.py 让我们的 agent 通过 ACP 调远程 agent(如 Codex);
4
+ 本模块让我们的 agent(DeepAgent compiled graph)反过来被 ACP client(Zed 编辑器、
5
+ 其它主控 agent)驱动,基于 langchain-acp 的 LangChainAcpAgent 适配层。
6
+
7
+ 对外暴露:
8
+ - serve_graph:把 compiled graph 包成 ACP agent 并阻塞跑 stdio JSON-RPC 循环。
9
+ - build_acp_server_agent:只构建 LangChainAcpAgent(不进 IO 循环,测试/嵌入用)。
10
+
11
+ 会话与状态:
12
+ - 每 ACP session 对应 graph 一个 thread_id(session_id),多轮上下文由
13
+ langgraph checkpointer 维持;无 checkpointer 的 graph 会被适配层自动挂
14
+ MemorySaver(进程内,进程退出即失)。
15
+ - deepagents 的 write_todos 计划事件经 DeepAgentsCompatibilityBridge 投影成
16
+ ACP AgentPlanUpdate,client(如 Zed)能实时看到计划进度。
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import logging
22
+ from typing import Any, Callable, Optional
23
+
24
+ from langchain_acp import create_acp_agent, run_acp
25
+ from langchain_acp.runtime.adapter import LangChainAcpAgent
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+ # graph 工厂类型:langchain-acp 以 FactoryGraphSource 调用工厂,签名是
30
+ # factory(session: AcpSessionContext) -> compiled graph(session 可忽略)。
31
+ # 声明成可选参以兼容「无参工厂」——我们只透传给 langchain-acp。
32
+ GraphFactory = Callable[..., Any]
33
+
34
+
35
+ def _adapt_factory(factory: GraphFactory) -> GraphFactory:
36
+ """把任意零参工厂包成 langchain-acp 要求的 (session) -> graph 签名。"""
37
+ def _wrapped(session: Any = None) -> Any: # noqa: ARG001
38
+ return factory()
39
+ return _wrapped
40
+
41
+
42
+ def build_acp_server_agent(
43
+ graph: Any = None,
44
+ *,
45
+ graph_factory: Optional[GraphFactory] = None,
46
+ agent_name: str = "sycommon-deepagent",
47
+ agent_title: str = "sycommon DeepAgent",
48
+ ) -> LangChainAcpAgent:
49
+ """构建 ACP 化的 agent(不进 IO 循环)。
50
+
51
+ Args:
52
+ graph: 已编译的 LangGraph/DeepAgent graph(与 graph_factory 二选一)。
53
+ graph_factory: 返回 compiled graph 的零参工厂(优先级低于 graph)。
54
+ agent_name: ACP agentInfo.name(client 侧展示用)。
55
+ agent_title: ACP agentInfo.title。
56
+
57
+ Returns:
58
+ LangChainAcpAgent,可直接传给 acp.run_agent 或自托管事件循环。
59
+ """
60
+ if graph is None and graph_factory is None:
61
+ raise ValueError("graph 与 graph_factory 至少提供一个")
62
+ agent = create_acp_agent(
63
+ graph=graph,
64
+ graph_factory=_adapt_factory(graph_factory) if graph_factory else None,
65
+ config=_make_config(agent_name, agent_title),
66
+ )
67
+ logger.info("[acp_server] agent 就绪 name=%s(等待 stdio client 连接)", agent_name)
68
+ return agent
69
+
70
+
71
+ def serve_graph(
72
+ graph: Any = None,
73
+ *,
74
+ graph_factory: Optional[GraphFactory] = None,
75
+ agent_name: str = "sycommon-deepagent",
76
+ agent_title: str = "sycommon DeepAgent",
77
+ ) -> None:
78
+ """把 graph 包成 ACP agent 并阻塞运行 stdio JSON-RPC 循环。
79
+
80
+ stdout 是 JSON-RPC 通道,任何日志必须走 stderr(上层负责 logging 配置)。
81
+ client 断开 stdin 或进程被 kill 时返回。
82
+ """
83
+ agent = build_acp_server_agent(
84
+ graph, graph_factory=graph_factory,
85
+ agent_name=agent_name, agent_title=agent_title,
86
+ )
87
+ run_acp(graph_source=agent._graph_source, config=agent._config)
88
+
89
+
90
+ def _make_config(agent_name: str, agent_title: str) -> Any:
91
+ """构造 AdapterConfig(agent 标识 + deepagents 兼容桥)。"""
92
+ from langchain_acp import AdapterConfig
93
+ from langchain_acp.bridges import DeepAgentsCompatibilityBridge
94
+
95
+ return AdapterConfig(
96
+ agent_name=agent_name,
97
+ agent_title=agent_title,
98
+ capability_bridges=(DeepAgentsCompatibilityBridge(),),
99
+ )
@@ -121,7 +121,7 @@ class MinioSyncService(metaclass=SingletonMeta):
121
121
  def _load_config(self, config: dict = None) -> dict:
122
122
  """从 Nacos 配置或环境变量加载 MinIO 配置"""
123
123
  if config:
124
- minio_cfg = config.get("Minio", {})
124
+ minio_cfg = config.get("Minio") or config.get("llm", {}).get("Minio") or {}
125
125
  if minio_cfg.get("endpoint"):
126
126
  return {
127
127
  "endpoint": minio_cfg.get("endpoint", ""),
@@ -134,7 +134,8 @@ class MinioSyncService(metaclass=SingletonMeta):
134
134
  try:
135
135
  from sycommon.config.Config import Config
136
136
  nacos_cfg = Config().config
137
- minio_cfg = nacos_cfg.get("Minio", {})
137
+ # Minio 配置挂在 llm 共享配置下(llm.Minio),不是顶层;这里兼容两种位置
138
+ minio_cfg = nacos_cfg.get("Minio") or nacos_cfg.get("llm", {}).get("Minio") or {}
138
139
  if minio_cfg.get("endpoint"):
139
140
  return {
140
141
  "endpoint": minio_cfg.get("endpoint", ""),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.8a7
3
+ Version: 0.2.8a8
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -43,7 +43,8 @@ Requires-Dist: minio==7.2.20
43
43
  Requires-Dist: langchain-mcp-adapters==0.3.2
44
44
  Requires-Dist: fastapi-mcp==0.4.0
45
45
  Requires-Dist: psycopg[binary,pool]==3.3.4
46
- Requires-Dist: agent-client-protocol==0.12.0
46
+ Requires-Dist: agent-client-protocol==0.11.0
47
+ Requires-Dist: langchain-acp==1.7.0
47
48
  Requires-Dist: pypinyin==0.55.0
48
49
 
49
50
  # sycommon-python-lib
@@ -61,7 +61,7 @@ command/templates/web/tools/mq.py.tpl,sha256=OMiZc4tI-rI2wYe7vYMuIStTB4YISJsaOIi
61
61
  nexus/__init__.py,sha256=U3xttvnZU9KqgzmgEx3TSjuJ8KDmIvPaVA6rqAdAI8A,1265
62
62
  sycli/__init__.py,sha256=KhBtgawbYr8KkVi2jEPmrfVOidBojsZHOB9s4xHv4L0,84
63
63
  sycli/__main__.py,sha256=d-RT-h0MqndA9xRO9YdHJjQt6YKGqTyDr69AHkHBlNE,121
64
- sycli/cli.py,sha256=RgwKvRQ8-vwLxJP8wE9OXQFDfGOkG-eBVl0uAWv64nQ,22639
64
+ sycli/cli.py,sha256=SJX9NS1IAX5_dyRezIUyWZahUbL0hGvH8AGdfFwaxAE,23044
65
65
  sycli/simple_chat_agent.py,sha256=_nnRqUhuhW27KNuWTnAzU97WMmo6M8dsx-ieYOyqfzM,6442
66
66
  sycli/acp/__init__.py,sha256=TalXyrLls6T9QML6CEKeCJ0X7I5uW79qsq_zCqXvAEg,823
67
67
  sycli/acp/config.py,sha256=AZlTMnkT9TxBjFo-VXMxvEiETMzrl_Urkc5EnpBtMzo,4472
@@ -85,6 +85,7 @@ sycli/cdp/capabilities/performance.py,sha256=Gdo_XLFecUZPzi2eBSlWutfD2R_N8HDDYWG
85
85
  sycli/cdp/capabilities/screenshot.py,sha256=OzQiiTVFAbPeQniWKIaeQFNA2xJ8ngcQ9R91DXoNaKw,1797
86
86
  sycli/commands/__init__.py,sha256=EbizXI__GBFr4gkqusUtMfGZ6slUN9fsnrDbFXMB-iQ,31
87
87
  sycli/commands/acp_cmd.py,sha256=QYdp9oQAF1w3X0Finbwz9SInwn2P3I2wIhafgyJeZ_M,3387
88
+ sycli/commands/acp_serve_cmd.py,sha256=Nk61uSZ-4CZNTzUDBfobbX_fG7O10xhw5RzV9ZdvtOM,3897
88
89
  sycli/commands/cdp_cmd.py,sha256=gKzTe4NggKRl-58belKutyQ8R5-7GKkQCGbhsFEjEjA,9061
89
90
  sycli/commands/chat_cmd.py,sha256=9qvCWEpglbE4WXkGLf7VWUiyV1G8OvIUkhccOddFBwY,9095
90
91
  sycli/commands/create_cmd.py,sha256=i4HyOXbxHNvV7jI7MOvZFibZpDea8aJbamrX8UOXNKM,3820
@@ -144,6 +145,7 @@ sycommon/agent/summarization_utils.py,sha256=-jQJNKZrb0np_L66qiaXWdXJC98Y4CUn9q8
144
145
  sycommon/agent/acp/__init__.py,sha256=_5QYNAgO_6b0xQXzK8ICRegODEPDQ_AhHC6XCderljg,1908
145
146
  sycommon/agent/acp/client.py,sha256=XEOoUsvVI67k0Lw0ZF6T-0Qut-vh5myVfCYQd8RJBwg,27787
146
147
  sycommon/agent/acp/fetch.py,sha256=dae2zVLgIQoj821dVg89mr5zPJ5OoaLVchcSuojWJ0Y,6986
148
+ sycommon/agent/acp/server_adapter.py,sha256=PdMfvg3aV23pAqsqAG9KSbRE-PVTdhqp3GZNaHd7EDk,4063
147
149
  sycommon/agent/acp/ssh_init.py,sha256=7OOxo0ew2J65qVkzNxTocgHlQ4RSqELujSoN_yfx-Hg,12319
148
150
  sycommon/agent/acp/tool.py,sha256=lS5MUjsPbPLzofE0L__nfog2cJojaITiosWl4ucNXOQ,11245
149
151
  sycommon/agent/mcp/__init__.py,sha256=CJZU6h6-Z6e7BEeWMaII8MQY21SlyihaT5gt0UR8GNc,666
@@ -157,7 +159,7 @@ sycommon/agent/sandbox/__init__.py,sha256=N6Mcg6Lyvk9dzZYD7Vh2yahStg3hYgtgCBb3ja
157
159
  sycommon/agent/sandbox/consistent_hash.py,sha256=ou6cS0f6Z79VGFE5Bk9PaiW2YsAKDVnG1P9pk9UmE4c,7452
158
160
  sycommon/agent/sandbox/file_ops.py,sha256=XpjxOqZvUYnGHq4ZqVJTZgTinZbzG5revp7Yqlh8u4k,43890
159
161
  sycommon/agent/sandbox/http_sandbox_backend.py,sha256=xuRejln7HFCW6Aj1Wm_k7mcPndOASynJz7OTMlMWh6w,92514
160
- sycommon/agent/sandbox/minio_sync.py,sha256=Q4SVX-ZRoF9KxGNSc5Zd9_Nt6G01fdtaj3ED0Ed1LeY,46562
162
+ sycommon/agent/sandbox/minio_sync.py,sha256=JSjqOVzDDRpZRM4GfrwwxKgk0Kiuv95toFXXy6Nun-A,46756
161
163
  sycommon/agent/sandbox/sandbox_pool.py,sha256=cvFD9VuFpYsHO-yOfuSvvJXQ3QDayFuXiXrJiuaKwpY,9400
162
164
  sycommon/agent/sandbox/sandbox_recovery.py,sha256=Sig1Db9_dZIufbkHgWEYPnBGhK8e7UZx8-EscXYsX7g,7559
163
165
  sycommon/agent/sandbox/session.py,sha256=14WP9GI-GOLoEdAmbkFHwyGdUQWcO7epOBq3GrB5rHw,2447
@@ -329,8 +331,8 @@ sycommon/tools/timing.py,sha256=IVJVqQdCFcm2timqSvKu9Ht372i8pF3K7b2JbtkcBWg,2137
329
331
  sycommon/tools/user_id.py,sha256=CfQ9bVRbtCYRHkizo-efx42DE600vNGAblXZJkJT7Nk,4867
330
332
  sycommon/xxljob/__init__.py,sha256=1VrCsCpzEcU9JLEjpyrbzfL0g0Wu8pIFgkJZJMQjmuw,89
331
333
  sycommon/xxljob/xxljob_service.py,sha256=cWLa-mrm7rJHigHrpj-xrSudDwBCtEfssv2pEntBxqA,7865
332
- sycommon_python_lib-0.2.8a7.dist-info/METADATA,sha256=tmtxkx8ciK_VB_JBkzyrOgn6wtqwfqjRqVCt2Vf5kxQ,8151
333
- sycommon_python_lib-0.2.8a7.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
334
- sycommon_python_lib-0.2.8a7.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
335
- sycommon_python_lib-0.2.8a7.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
336
- sycommon_python_lib-0.2.8a7.dist-info/RECORD,,
334
+ sycommon_python_lib-0.2.8a8.dist-info/METADATA,sha256=aCqQD-fPA4igNNYxHL4mB4HyVzaYnHAYlGBjJmZgTsU,8188
335
+ sycommon_python_lib-0.2.8a8.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
336
+ sycommon_python_lib-0.2.8a8.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
337
+ sycommon_python_lib-0.2.8a8.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
338
+ sycommon_python_lib-0.2.8a8.dist-info/RECORD,,