Metadata-Version: 2.4
Name: scholai-cli
Version: 0.1.20
Summary: scholai course atoms: CLI + runtime for article courseware generation pipeline (MVP)
Author: haoyiqiang
License: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: typer>=0.12
Requires-Dist: pydantic>=2.7
Requires-Dist: openai>=1.0
Requires-Dist: requests[socks]>=2.31
Requires-Dist: curl_cffi<1.0,>=0.7
Requires-Dist: beautifulsoup4>=4.12
Requires-Dist: markdown>=3.5
Requires-Dist: Pillow>=10.0
Requires-Dist: numpy>=1.24
Requires-Dist: edge-tts>=6.1
Requires-Dist: moviepy>=2.0
Requires-Dist: mutagen>=1.47
Requires-Dist: pdfplumber>=0.10
Requires-Dist: python-docx>=1.0
Requires-Dist: striprtf>=0.0.26
Requires-Dist: html2text>=2024.0
Requires-Dist: lxml>=5.0
Requires-Dist: cos-python-sdk-v5>=1.9
Requires-Dist: oss2>=2.18
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-mock>=3.12; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"

# scholai-cli

scholai 课件生成管线的 Python CLI。

由 `@scholai/openclaw-scholai` plugin 的 skill 通过 `metadata.openclaw.install: [kind: uv]` 自动安装;也可独立使用:

```bash
uv tool install scholai-cli
scholai course vfd-url --run-id 260422-abc12345-article-01
```

## 管线 atom 列表

### 通用（kind-agnostic）

- `scholai course vfd-url` — URL → `intermediate/VFD.json`
- `scholai course iod` — VFD → `intermediate/IOD.json`
- `scholai course publish --kind <article|mindmap>` — POST 对应 kind 的 publish-facing 产物到 scholai 平台

### article kind

- `scholai course pd` — IOD + VFD → `intermediate/PD.md`
- `scholai course txd-gen` — 含图占位符的 `intermediate/TXD.md`
- `scholai course txd-imagegen` — 生成占位图 + `intermediate/TXD_final.md`
- `scholai course txd-render-html` — TXD_final → `output/article.html`

publish payload: `output/article.html`。

### mindmap kind

- `scholai course mmd-gen` — IOD → `output/mindmap.md`（Markmap 风格 Markdown，**严格按 IOD keywords 平铺，不扩展**）
- `scholai course mmd-render-html` — mindmap.md → `output/mindmap.html`（markmap-autoloader 本地预览，含「保存为 PNG」按钮，零 LLM 调用）

publish payload: `output/mindmap.md`（**Markdown，不是 HTML** —— scholai 后端的 `MARKDOWN_KINDS` 白名单包含 mindmap，传 HTML 会被 400 拒绝；最终页面由后端用 markmap 渲染）。

### video kind

| atom | 类型 | 输入 | 输出 |
|------|------|------|------|
| `vfd-url` | 复用 | input/source.json (type=url) | intermediate/VFD.json |
| `ssd-gen` | LLM 文本 | VFD.json | intermediate/SSD.json |
| `ssd-imagegen` | LLM 图像 | SSD.json | intermediate/images/SEG-NN.jpg + manifest.json |
| `tts-gen` | edge-tts CLI | SSD.json | intermediate/audio/SEG-NN.mp3 + durations.json |
| `video-compose` | moviepy + ffmpeg | SSD + images + audio | output/video.mp4 + output/cover.jpg + intermediate/SSD.srt |
| `lark-send` | lark-cli | output/video.mp4 + cover.jpg + chat_type/chat_native_id | output/lark_send.json（消息 ID） |

**publish payload**: 无（本期 MVP 跳过 publish 与 OSS；视频通过 lark-send 直接推回原 IM 会话）。

## Token 用量查询

运行 `scholai usage <subcommand>` 查询 LLM 调用用量。

### 命令

```bash
scholai usage today                          # 今天的用量
scholai usage yesterday                      # 昨天的用量
scholai usage range --from 2026-05-01 --to 2026-05-06   # 日期区间
scholai usage run <run_id>                   # 单次 run 的用量

# 可选：按 skill 过滤（today / yesterday / range）
scholai usage today --skill article
```

### 配置价格（可选）

创建 `~/.openclaw/scholai-usage/pricing.toml`（dev 模式为 `~/.openclaw-dev/scholai-usage/pricing.toml`）：

```toml
[chat."deepseek-chat"]
prompt = 2.0          # 元/百万 token，cache miss
prompt_cached = 0.5   # 元/百万 token，cache hit（可省略，省略回落到 prompt 价）
completion = 8.0

[chat."glm-4-plus"]
prompt = 5.0
completion = 5.0

[image."cogview-3"]
per_call = 0.06       # 元/张
```

没有此文件时，命令仍可用，只显示 token 数量，不计算金额。

### 数据文件位置

| 文件 | 路径 |
|---|---|
| per-run 用量 | `<openclaw_home>/agents/<bot_id>/workspace/runs/<run_id>/logs/usage.jsonl` |
| 按天汇总 | `<openclaw_home>/scholai-usage/<YYYY-MM-DD>.jsonl` |
| 价格配置 | `<openclaw_home>/scholai-usage/pricing.toml` |

`<openclaw_home>` 由 openclaw 注入的 `OPENCLAW_STATE_DIR` 确定（dev 模式为 `~/.openclaw-dev`）。

## 开发

```bash
cd packages/scholai-cli
uv sync --all-extras
uv run pytest
```
