<!-- 来源: https://hostanagent.com/docs/integration/python/ | 协议: 1.0 | 更新: 2026-09-30 -->

# Python SDK

`hostanagent-client==0.2.5` 是产品服务端的异步 SDK，Python 3.10+，使用 httpx。先在 [API Keys](/docs/console/api-keys/) 页面创建目标 Agent 的受限 Key；模型供应商凭证由平台持有。

```bash
python -m pip install hostanagent-client==0.2.5
```

下面的函数由产品已验证的请求处理器调用。`trusted_product_user_id` 必须来自产品登录态；示例请求可能产生模型费用，只有账户有余额且 Agent 已发布时才调用。

```python
import os
from hostanagent import AgentClient, HostingError, idempotency_key

async def chat(trusted_product_user_id: str, session_id: str):
    async with AgentClient(
        "https://api.hostanagent.com/v1",
        os.environ["HAA_APPLICATION_KEY"],
        subject=trusted_product_user_id,
    ) as client:
        key = idempotency_key()
        # 产品须保存原请求正文、参数和 key；未知结果时原样核对或重试。
        try:
            accepted = await client.run(
                session_id,
                os.environ["HAA_AGENT_VERSION"],
                "整理我的任务",
                idempotency_key=key,
            )
        except HostingError as error:
            if error.code == "INSUFFICIENT_BALANCE":
                # 异步事件流只能直接结束；产品可以在外层把此错误映射为充值提示。
                return
            raise
        async for event in client.events(accepted["run_id"]):
            yield event
```

要先做独立服务端冒烟检查，可把下面内容保存为 `smoke.py`，在测试服务端设置 `HAA_APPLICATION_KEY`、`HAA_AGENT_VERSION` 和由该产品确认的 `HAA_TEST_SUBJECT`，然后运行 `python smoke.py`。这段不接收浏览器自报 Subject；它会创建一个新 Session，并在余额充足时发起**真实、可能计费**的模型 Run。

```python
import asyncio
import os
from hostanagent import AgentClient, HostingError, idempotency_key

async def main():
    async with AgentClient(
        "https://api.hostanagent.com/v1",
        os.environ["HAA_APPLICATION_KEY"],
        subject=os.environ["HAA_TEST_SUBJECT"],
    ) as client:
        session = await client.create_session()
        print("session_id", session["id"])
        try:
            run = await client.run(
                session["id"], os.environ["HAA_AGENT_VERSION"], "你好",
                idempotency_key=idempotency_key(),
            )
            print("run_id", run["run_id"])
            async for event in client.events(run["run_id"]):
                print(event["sequence"], event["type"])
        except HostingError as error:
            print(error.status_code, error.code, error.request_id)

asyncio.run(main())
```

预期：无余额时输出 `402 INSUFFICIENT_BALANCE` 且不请求模型；余额足够时先输出 Session/Run ID，再收到有序事件。网络或进程在 POST 响应前中断时，该演示脚本**不会**自动安全恢复：正式产品须事先持久化请求参数和幂等键，并用原键核对，不能简单重跑脚本生成新键。

先通过 `await client.bootstrap()` 读取运行发现，或 `await client.create_session()` 创建 managed + durable 会话，保存其 ID 后调用上面的函数。SDK 还提供模型目录、运行元数据、会话/消息、Run 快照、取消、追加输入、审批、claim/receipt 和事件订阅。Agent 的 `history_mode` / `runtime_mode` 枚举不意味着未开放模式可用；服务器只接受当前支持的组合。

网络断开时 `events()` 停止观察，不取消 Run。先读取 `snapshot(run_id)`，再从 `resume_cursor` 订阅后续事件；POST 响应未知时保存并重用原幂等键和完整参数，不换键新建付费 Run。`HostingError` 含状态码、稳定 code 和 request ID。[运行 API](/docs/reference/runtime/)、[恢复指南](/docs/integration/recovery/)。

如需收紧本轮输入窗口，可给 `run` 传 `limits={"max_context_tokens": 128000}`，且不能超过 Agent 发布配置。0.2.5 会按传入字典发送，无需为本次服务升级更换 SDK；但须从自己的模板中删除 `max_context_chars`、`max_result_bytes`、`max_result_tokens`。工具结果预算 `max_result_context_bytes` 配置在工具集，默认 16 KiB、最高 32 KiB，不是 `run` 参数。[配置与迁移](/docs/reference/configuration/)及[版本边界](/docs/releases/compatibility/)。
