Metadata-Version: 2.4
Name: tokincloud
Version: 0.2.0
Summary: Tokin 拓令云 Python SDK —— OpenAI 兼容调用 + 一键登录(OAuth PKCE) + 多 agent panel + 短期凭证透明续期 + 余额/用量回显。零运行时依赖。
Project-URL: Homepage, https://tokincloud.com
Author: Tokin 拓令云
License: MIT
License-File: LICENSE
Keywords: gateway,llm,multi-agent,openai-compatible,panel,sdk,tokin,tokincloud
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# tokin (Python SDK)

Tokin 数据面 SDK 的 Python 实现，与 TS 版 `@tokin/sdk` 等价。**零运行时依赖**（仅标准库），可直接运行。

> **最省事：连我们的包都不用装。** Tokin 完全 OpenAI 兼容，直接用官方 `openai` 库改个 `base_url` 即可：
> ```python
> from openai import OpenAI
> client = OpenAI(base_url="https://api.tokincloud.com/v1", api_key="sk-tokin-xxxx")
> r = client.chat.completions.create(model="deepseek-v4-flash",
>                                    messages=[{"role": "user", "content": "你好"}])
> ```
> 本包的价值在其上多做的一层：**短期凭证自动续期 + app_id 归属 + 余额/用量回显 + 多 agent `panel`**。

## 三种登录入口（按场景挑一种）

```python
from tokincloud import TokinClient

BASE = "https://api.tokincloud.com"

# ① 服务器 / CI（无浏览器）—— 最省事，直接用主 Key
client = TokinClient.with_api_key(BASE, "sk-tokin-xxxx")

# ② 受信第一方工具 —— 手机号+密码登录，密码用完即弃，换短期凭证（可吊销、自动续期）
client = TokinClient.login(BASE, phone="13800000000", password="•••", app_id="app_demo")

# ③ 桌面 / 本地 —— OAuth PKCE 一键连接：拉起浏览器授权，密码只留在 tokincloud.com
client = TokinClient.connect(BASE, app_id="app_demo")  # 自动开浏览器 + 本地 loopback 收码
```

> 安全：`login` 的密码只用于换取凭证、绝不落存储；`connect` 走标准 PKCE，本机只经手一次性 code。
> 没有浏览器的服务器/CI 场景请用 `with_api_key`（或 `login`），不要用 `connect`。

## 对话（含图片）与多 agent

```python
r = client.chat(model="deepseek-v4-flash", messages=[{"role": "user", "content": "你好"}])
print(r["choices"][0]["message"]["content"])

# 流式
for delta in client.chat_stream(model="glm-5.2", messages=[{"role": "user", "content": "数到三"}]):
    print(delta, end="", flush=True)

# 图片（本地路径或 URL 均可）
from tokincloud import user_image
r = client.chat(model="qwen3-vl-plus", messages=[user_image("这张图是什么？", "cat.png")])

# 多 agent 抗辩：一次调 N 个「不同厂商」模型（红蓝抗辩 / 多模型辩论）
res = client.panel(messages=[{"role": "user", "content": "该不该上这个方案？"}], n=3, tier="quality")
for a in res["agents"]:
    print(a["agent"], a["model"], "→", a["content"][:40])   # 透明返回真实模型名
# 也可手动指定模型（命名需与 /v1/models 精确匹配）：
client.panel(messages=[...], models=["deepseek-v4-flash", "glm-5.2", "kimi-k2.6"])

client.get_balance()   # {"balance": ...}
client.get_usage()     # {"count", "totalSpent", "records"}  仅自身花费
client.list_models()   # [...]
```

自动续期透明：每次调用前 `ensure_fresh`，401 再 `force_refresh` 重试一次，并发单飞（`threading.Lock` + access 变更检测），刷新轮换 refresh_token。续期失败抛 `TokinAuthError`。

## 运行示例

```bash
# 先启动网关：cd ../gateway && npm run dev
python examples/quickstart.py
```

> 本包与 TS 版共用同一份契约 `../openapi/tokin-gateway.yaml`。方法名遵循 Python 习惯（snake_case）。
