Metadata-Version: 2.5
Name: managed-agent-sdk
Version: 0.0.1
Summary: Managed Agent SDK (Python) — 控制面走腾讯云 API，数据面走 ACP
Project-URL: Homepage, https://cnb.cool/codebuddy/managed-agent-sdk
Project-URL: Repository, https://cnb.cool/codebuddy/managed-agent-sdk
Project-URL: Issues, https://cnb.cool/codebuddy/managed-agent-sdk/-/issues
Project-URL: Changelog, https://cnb.cool/codebuddy/managed-agent-sdk/-/blob/main/packages/python/CHANGELOG.md
Author-email: Tencent CodeBuddy <codebuddy@tencent.com>
License: MIT
License-File: LICENSE
Keywords: acp,agent,llm,managed-agent,sandbox
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: <3.15,>=3.10
Requires-Dist: agent-client-protocol<0.13,>=0.12
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.6
Requires-Dist: tencentcloud-sdk-python-common>=3.0.1000
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Requires-Dist: uvicorn>=0.30; extra == 'dev'
Description-Content-Type: text/markdown

# managed-agent-sdk（Python）

腾讯云 **WorkBuddy 企业版 Managed Agent** 的 Python SDK。

控制面走腾讯云 API（TC3 签名），数据面走 ACP 协议，两段凭证由 SDK 内部缝合。

```bash
pip install managed-agent-sdk
```

要求 Python 3.10 ~ 3.14。Node 版见 [`@tencent-ai/managed-agent-sdk`](https://www.npmjs.com/package/@tencent-ai/managed-agent-sdk)，两侧 API 语义一致。

## 凭证

从环境变量读取，或在构造时显式传入：

```bash
export TENCENTCLOUD_SECRET_ID=你的SecretId
export TENCENTCLOUD_SECRET_KEY=你的SecretKey
```

只支持长期密钥，不支持 STS 临时密钥。数据面（ACP）的凭证由 SDK 用这套密钥自动换取并缓存，无需单独配置。

## 快速开始

```python
import asyncio

from managed_agent_sdk import (
    CreateAgentOpts,
    CreateSessionOpts,
    CreateVersionOpts,
    ManagedAgentClient,
    ManifestBuilder,
)


async def main() -> None:
    async with ManagedAgentClient() as client:
        # 创建 Agent
        agent = await client.agents.create(
            CreateAgentOpts(
                agent_name="日志分析助手",
                model="deepseek-v3",
                manifest=ManifestBuilder().system_prompt("你是日志分析专家").build(),
            )
        )

        # 创建版本（manifest 服务端必填）
        version = await agent.versions.create(
            CreateVersionOpts(
                manifest=ManifestBuilder().system_prompt("你是日志分析专家").build(),
            )
        )

        # 创建会话（拉起真实沙箱，不会自动回收 —— 尽量复用）
        session = await agent.sessions.create(
            CreateSessionOpts(version_id=version.version_id)
        )

        # 对话
        res = await session.prompt("分析这份日志")
        print(res.stop_reason)

        await session.disconnect()


asyncio.run(main())
```

`prompt()` 的返回值只携带 `stop_reason`，回复文本从 `on_chunk` 取 —— 流式内容与终局结果分两条通道，这是 ACP 的协议设计。

## 配置连接器 / 技能 / 专家

三类资源的**配置入口不统一**，这是最容易配错的地方：

| 资源 | 查询 | 配置入口 | 最终落点 |
| --- | --- | --- | --- |
| 连接器（MCP） | `client.connectors.list()` | `connector_ids`（Action 入参） | 服务端物化成 manifest 的 `mcp_servers` |
| 技能 | `client.skills.list()` | `ManifestBuilder.skills()` | manifest 的 `skills` |
| 专家 | `client.experts.list()` | `ManifestBuilder.experts()` | manifest 的 `experts` |

技能与专家进 manifest，连接器**不进** —— 只把 ID 交给服务端，由它查网关地址后物化。
自己往 manifest 里写 `mcp_servers` 会与之重复。

```python
skills = await client.skills.list("BUILTIN", ListSkillsOpts(limit=50))
connectors = await client.connectors.list_active()

agent = await client.agents.create(
    CreateAgentOpts(
        agent_name="运维助手",
        manifest=(
            ManifestBuilder()
            .system_prompt("你是运维专家")
            .skills([{"type": "builtin", "id": s["SkillId"]} for s in skills.items])
            .build()
        ),
        connector_ids=[c["ConnectorId"] for c in connectors.items],  # 独立入参
    )
)
```

`connector_ids` 是该版本最终要绑的完整集合，服务端按它做全量覆盖 ——
改绑定直接传新集合，解绑从列表里去掉即可，传 `[]` 解绑全部。

## 两条约定

**入参 snake_case，出参 PascalCase。** 出参原样透传云 API 字段名，便于对照官方文档排查。

**不做控制面自动重试。** `Create*` 类接口非幂等且服务端不提供 `ClientToken`，重试 `sessions.create()` 会重复拉起沙箱并产生真实费用。唯一例外是 ACP 断线重连（`Last-Event-ID` 断点续传，不重放 prompt）。

**会话即沙箱，且不会自动回收。** `sessions.create()` 每次调用都拉起一个真实沙箱。注意 `disconnect()` **只断 ACP 连接，不释放沙箱** —— 服务端既没有销毁会话的接口，也没有空闲超时回收（`IDLE` 只是「上一轮对话结束」的轮次状态，沙箱照常运行）。要复用会话，别在循环里反复新建。

## 文档

完整 API 参考、错误码表、已知问题见
[Managed Agent SDK 文档](https://cnb.cool/codebuddy/managed-agent-doc/-/blob/main/python/README.md)。
