CMDC Agent Kernel Python SDK — connect to cmdc_gateway via HTTP + SSE + WebSocket
Project description
cmdc-python
CMDC Agent Kernel Python SDK — 通过 HTTP + SSE + WebSocket 连接 cmdc_gateway,在 Python 中使用 CMDC Agent 能力。
安装
pip install cmdc
或从源码安装(开发模式):
cd python
pip install -e ".[dev]"
依赖要求:
- Python 3.10+
httpx >= 0.27httpx-sse >= 0.4websockets >= 12.0
快速开始(5 分钟)
1. 启动 cmdc_gateway
cd cmdc_gateway
CMDC_API_KEYS=sk-abc123 mix run --no-halt
2. 最简对话
from cmdc import CMDC
client = CMDC(base_url="http://localhost:4000", api_key="sk-abc123")
with client.session(model="deepseek:deepseek-chat") as session:
for event in session.prompt("帮我写一个快速排序算法"):
if event.type == "message_delta":
print(event.delta, end="", flush=True)
print() # 换行
3. 流式输出(完整示例)
from cmdc import CMDC
with CMDC(base_url="http://localhost:4000", api_key="sk-abc123") as client:
with client.session(
model="deepseek:deepseek-chat",
system_prompt="你是一个专业的 Python 编程助手",
tools=["CMDC.Tool.Shell", "CMDC.Tool.ReadFile"],
max_turns=20,
) as session:
full_reply = ""
for event in session.prompt("分析当前目录的 Python 文件"):
match event.type:
case "message_delta":
print(event.delta, end="", flush=True)
full_reply += event.delta or ""
case "tool_execution_start":
print(f"\n[工具] {event.data['toolName']} 开始执行...")
case "tool_execution_end":
status = event.data.get("status", "?")
print(f"[工具] 执行完成 ({status})")
case "agent_end":
tokens = event.token_usage
if tokens:
print(f"\n[完成] 共消耗 {tokens.total_tokens} tokens")
API 参考
CMDC 主客户端
client = CMDC(
base_url="http://localhost:4000", # Gateway 地址
api_key="sk-abc123", # API Key
timeout=30.0, # 请求超时(秒)
connect_timeout=10.0, # 连接超时(秒)
)
方法
| 方法 | 说明 |
|---|---|
create_session(model, **kwargs) |
创建 Session,返回 Session 实例 |
session(model, **kwargs) |
Context Manager,自动 stop |
create_session_async(model, **kwargs) |
异步版 create_session |
asession(model, **kwargs) |
异步 Context Manager |
health() |
检查 Gateway 健康状态 |
close() / aclose() |
关闭 HTTP 连接池 |
SessionOptions 字段
from cmdc import SessionOptions
opts = SessionOptions(
model="deepseek:deepseek-chat", # 必填
session_id="my-session-001", # 自定义 ID(可选)
system_prompt="你是助手", # 系统提示词
working_dir="/home/user/project", # 工具工作目录
tools=["CMDC.Tool.Shell"], # 启用的工具模块
plugins=["CMDC.Plugin.Builtin.SecurityGuard"], # 插件
blueprint="CMDC.Blueprint.Base", # 蓝图模块
max_turns=50, # 最大轮次
max_tokens=4096, # 最大输出 token
skills_dirs=["/home/user/skills"], # Skill 目录
provider_opts={"temperature": 0.7},# Provider 额外参数
)
session = client.create_session(options=opts)
Session 操作
发送消息
# 方式一:迭代事件流
for event in session.prompt("你好"):
if event.type == "message_delta":
print(event.delta, end="")
# 方式二:阻塞等待完整回复
reply = session.prompt_sync("简单回答:1+1=?")
print(reply) # "2"
# 方式三:仅投递,不监听
response = session.send_prompt("开始执行任务")
print(response.request_id) # 16 位 hex
控制操作
session.approve("apr_x7y8z9") # 审批通过
session.reject("apr_x7y8z9") # 审批拒绝
session.respond("ask_001", "快速排序") # 回答 Agent 提问
session.stop() # 停止 Agent
查询
info = session.get_info() # SessionInfo
stats = session.get_stats() # Stats(含 token 用量)
messages = session.get_messages() # List[Message]
事件类型(15 种)
| 类型 | 说明 | 常用字段 |
|---|---|---|
agent_start |
Agent 开始处理 | — |
agent_end |
处理完成 | event.last_message, event.token_usage |
agent_abort |
Agent 被中止 | event.data["reason"] |
prompt_received |
确认收到 prompt | event.data["text"] |
message_start |
LLM 开始生成 | — |
message_delta |
流式文本片段 | event.delta |
thinking_start |
思考链开始 | — |
thinking_delta |
思考文本片段 | event.data["delta"] |
tool_calls |
本轮工具数量 | event.data["count"] |
tool_execution_start |
工具开始执行 | event.data["toolName"], event.data["args"] |
tool_execution_end |
工具执行完成 | event.data["status"], event.data["result"] |
approval_required |
需要人工审批 | event.approval_id, event.data["toolName"] |
approval_resolved |
审批已决定 | event.data["status"] |
ask_user |
Agent 向用户提问 | event.ask_ref, event.question |
error |
运行时错误 | event.data["reason"] |
HITL 审批(HumanApproval)
from cmdc import CMDC, AutoApprove, AutoReject, PromptApproval
# 自动批准所有工具
for event in session.prompt("执行清理任务", approval_policy="auto_approve"):
...
# 终端手动审批
for event in session.prompt("执行清理任务", approval_policy="prompt"):
...
# 自定义逻辑:只允许非 Shell 工具
policy = lambda e: e.data.get("toolName") != "Shell"
for event in session.prompt("执行任务", approval_policy=policy):
...
本地工具注册
from cmdc import LocalTool
def search_db(args: dict) -> str:
query = args.get("query", "")
# 本地数据库查询逻辑
return f"查询结果: {query}"
tool = LocalTool(
name="search_database",
description="在本地数据库中搜索信息",
parameters={
"type": "object",
"properties": {
"query": {"type": "string", "description": "搜索关键词"}
},
"required": ["query"],
},
callback=search_db,
timeout=10.0,
)
# 向 Gateway 注册(需要本地 HTTP 服务监听 callback_url)
session.register_tool(tool, callback_url="http://my-service:8080/tools/search_database")
WebSocket 双向连接
# 同步版本
with session.connect_ws() as ws:
ws.send_prompt("执行危险操作")
for event in ws.iter_events():
if event.type == "approval_required":
print(f"需要审批: {event.data['toolName']}")
ws.approve(event.approval_id)
elif event.type == "message_delta":
print(event.delta, end="")
elif event.type == "agent_end":
break
# 异步版本
async with session.connect_ws() as ws:
await ws.send_prompt("执行危险操作")
async for event in ws.iter_events():
if event.type == "approval_required":
await ws.approve(event.approval_id)
elif event.type == "agent_end":
break
异步 API
import asyncio
from cmdc import CMDC
async def main():
async with CMDC(base_url="http://localhost:4000", api_key="sk-abc123") as client:
async with client.asession(model="deepseek:deepseek-chat") as session:
gen = await session.aprompt("你好")
async for event in gen:
if event.type == "message_delta":
print(event.delta, end="", flush=True)
asyncio.run(main())
错误处理
from cmdc import (
CMDCError,
AuthError,
SessionNotFoundError,
RateLimitError,
SessionCreateError,
)
try:
session = client.create_session(model="unknown:model")
except AuthError:
print("API Key 无效")
except SessionCreateError as e:
print(f"创建失败: {e.message}")
except RateLimitError as e:
print(f"超出限流,{e.retry_after}s 后重试")
except CMDCError as e:
print(f"其他错误 [{e.status_code}]: {e.message}")
运行测试
cd python
pip install -e ".[dev]"
pytest tests/ -v
环境变量
| 变量 | 说明 |
|---|---|
CMDC_BASE_URL |
Gateway 地址,默认 http://localhost:4000 |
CMDC_API_KEY |
API Key |
快速配置:
import os
from cmdc import CMDC
client = CMDC(
base_url=os.environ.get("CMDC_BASE_URL", "http://localhost:4000"),
api_key=os.environ["CMDC_API_KEY"],
)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
cmdc_sdk-0.1.0.tar.gz
(25.3 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
cmdc_sdk-0.1.0-py3-none-any.whl
(21.1 kB
view details)
File details
Details for the file cmdc_sdk-0.1.0.tar.gz.
File metadata
- Download URL: cmdc_sdk-0.1.0.tar.gz
- Upload date:
- Size: 25.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db34bd5449e830de6028f0498d9a29d3d8918753fa9d8ea211e9f69e85c5d996
|
|
| MD5 |
0f84b8369cd681d1e161a02b2e2e259d
|
|
| BLAKE2b-256 |
6180be35256cafcebcf7d45287b1297b177ce671725d0709be31c6ee379c0a1c
|
File details
Details for the file cmdc_sdk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cmdc_sdk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a26e1f7b547df9d61250c4c5263740905191302489ce60d56ce9ded38d214ae
|
|
| MD5 |
e856ebc161e76891754a580d7c46d21d
|
|
| BLAKE2b-256 |
a10badde904082fadca3b5a188ebbfdf0f662140f16144adee740387e2e823cd
|