# aicd

命令行 AI Agent：聊天驱动文件、进程、HTTP、任务与子 Agent。Windows 优先，预留 Linux。

本工具借助大模型，在对话中完成**由代码生成文档**与**由文档生成代码**的闭环，并对项目中的文档与源码做**深入分析与理解**，便于梳理设计、落地实现与持续维护。

## 文档库与版本迭代（约定）

Agent 在 **AI 输出根**（默认 `<workspace>/aicd/`）下使用 **`output/library/<doc_slug>/`** 存放可复用素材（`apis/`、`diagrams/`（含 **`.mmd`、`.drawio`、`.vsdx`** 等）、`outlines/`、`markdown/` 等），并建议维护 **`INDEX.md`**（含 **`latest:`** 指向当前正文、**`## Revisions`** 变更记录）。**首次成稿后**你仍可继续提修改需求；模型应在**已读 `latest` 或最高 `_vNNN` 文件**的基础上**另存为新版本**（如 `_v004`），**不覆盖**旧版，除非明确要求替换。对外交付可复制到 **`output/deliverables/<topic_slug>/`**。细则见源码中 `DOC_AUTHORING_ITERATION_DIRECTIVES` 与 `.cursor/skills/aicd-ai-output/SKILL.md`。

## 环境

```powershell
cd <本仓库根目录>
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e .
# 可选：Agent 访问 PostgreSQL / MySQL（db_inspect / db_query）
pip install -e ".[db]"
# 可选：只读聊天历史 HTTP API（aicd serve）
pip install -e ".[api]"
# 可选：PDF 整页 OCR（doc_extract use_ocr）
pip install -e ".[ocr]"
# 可选：Microsoft Visio .vsdx 流程图（visio_flowchart_write / visio_vsdx_summarize）
pip install -e ".[visio]"
# 可选：浏览器自动化
playwright install chromium
```

## 配置（config.yaml）

- **`llm`**：`apiKey` / `baseUrl` / `modelId`；可选 **`visionModel`**（多模态专用，缺省沿用主模型）；**`timeoutSec`**；**`maxRetries`**（单次请求失败后额外重试次数，0–20，默认 3）；**`retryBaseDelaySec`**（退避基数秒，默认 1.0）；采样字段 `temperature`、`topP` 等。
- **`agent`**：**`maxToolRounds`** / **`subAgentMaxToolRounds`** 各 **1–500**（超出会截断）；**`contextBudgetTokens`**、**`chatHistoryMaxMessages`**（启动时从 SQLite 恢复尾部消息再按 token 预算裁剪）。
- **`paths`**：`full_disk`、`allowed_roots` 等（见代码内默认值）。

环境变量 **`AICD_HOME`**：应用数据目录。未设置且未使用 `--home` 时，使用 **`%USERPROFILE%\.aicd`**（Windows）。其下 **`logs/`** 每次 `aicd tui` 会新建时间戳日志；LLM 重试会写入会话日志。

缺依赖时 Agent 会说明缺少的组件与推荐安装命令；若你在对话中明确说 **「帮我安装」** 等，模型可按 **`runtime_env.yaml`** 中的 **`python.executable`** 执行 **`python -m pip install …`**（与当前 Aicd 同一解释器），并调用 **`runtime_env_refresh`** 刷新环境快照。

**环境自检（模型侧）**：工具 **`agent_environment_digest`** 返回紧凑 JSON（常用 CLI、可选 Python 模块、LLM 协议/模型名、是否已配置 API Key——**不含密钥**、主/子 Agent 工具轮次上限等）；可选 **`include_capabilities_text`** 附带 `env_capabilities_summary.txt` 节选。安装新软件或 pip 依赖后可用 **`refresh_first`: true** 或先 **`runtime_env_refresh`**。系统提示中的 **Agent introspection** 约定：开工前或遇 **`ok: false`** 时核对环境，指令模糊或多方案时与用户对齐后再执行。

## 命令行

| 命令 | 说明 |
|------|------|
| `aicd init [--home DIR]` | 初始化 HOME、`config.yaml`、SQLite |
| `aicd tui [--home DIR] [--work DIR]` | TUI；**`--work`** 启动后立刻将 AI 工作区设为该目录（等同 `/work`） |
| `aicd serve [--home DIR] [--host] [--port] [--api-key]` | 只读聊天 API（需 **`pip install -e ".[api]"`**）；鉴权见下文 |
| `aicd version` | 打印版本 |

TUI 斜杠：**`/work`**、**`/doc`**、**`/agent`**、**`/llm`**（含 `maxRetries`、`retryBaseDelaySec`）、**`/task`**、**`/exit`**。

## Agent 能力与工具（摘要）

- **工作区**：主会话须用工具 **`ai_workspace_set`** 切换项目目录（**`run_command cd` 无效**）；TUI 用 **`/work`**。
- **环境与自省**：**`agent_environment_digest`**（可选 **`refresh_first`**）、**`runtime_env_refresh`**；完整探测见 **`$AICD_HOME/data/runtime_env.yaml`** 与 **`env_capabilities_summary.txt`**。详见 **`src/aicd/agent/prompts.py`** 中 **`AGENT_INTROSPECTION_DIRECTIVES`**。
- **多模态**：**`vision_analyze_image`** — 将本地图片送视觉模型解析图表/图中文字；默认 **`save_report`** 把结果写入 **AI tmp**（`ai_output_dir/tmp`），便于后续 **`fs_read_file`**。发送前会对大图做长边与体积压缩（默认长边 ≤1920、编码目标 ≤1MiB 等，见 `llm.image_file_to_data_url`）。
- **文档**：**`doc_extract`**（PDF/DOCX/PPTX 等）；**`document_outline`** — 对 `.md`/`.html`/`.txt` 提取标题树、**行号**与 **UTF-8 字节偏移**，默认写入 **`tmp/outlines/<stem>.json`**，便于大文档分块阅读。
- **超大上下文策略**：系统提示中的 **LARGE_CONTEXT** 约定：先检索/目录再 **`fs_read_file` offset/limit**、在 **`ai_tmp`** 写清单与 **`session_focus.md`**（稳定事实 vs 工作假设）、大输出落盘、必要时 **`task_ai`** / **`chat_save_summary`** / **`chat_history_*`**。
- **聊天持久化**：消息与摘要存 SQLite；**`aicd serve`** 提供只读 HTTP 拉取（与 TUI 共用同一库）。
- **主 / 子任务闭环**：复杂工作优先 **`task_ai`**。主会话可在旧子任务仍 **`running`** 时继续发话；若新意图属于同一子任务，主 AI 应 **`task_message_send`**（**`kind`**: **`directive`**，**`body`**: `{"text":"..."}`，主会话可省略 **`from_task_id`**，库内记为 **`main-<session_id>`**）。子 Agent 在每段 LLM 工具循环结束后**自动拉取收件箱**；有未读则合并为新的 **user** 轮次并继续，**无新消息则任务结束**。累计 LLM 轮次有上限（约 `max(subAgentMaxToolRounds*6, 300)`），防无限循环。相关工具：**`task_list`** / **`task_result`**（**timeline**）、**`task_thread_stats`**。
- **`script_run` 脚本备份**：每次运行会在 **`AICD_HOME/tmp/scripts/`** 写入规范化临时文件，执行结束后**复制**到 **`<workspace>/aicd/bak/`**（同名），便于审查与复用；工具返回 **`script_bak_path`**。建议传 **`related_doc`**（如当前文档/交付物简称）以便文件名对齐上下文。详见 `prompts.py` 与 **`.cursor/skills/aicd-ai-output/SKILL.md`**。
- **图表 HTML → 栅格 → Word/PPT**：**`viz_export_html` / `viz_data_chart`** 的 **`.html` + `res/`须保留**；嵌入 **`docx_compose` / `pptx_compose`** 前用 **`viz_html_to_png`** 生成 **`.png`**，勿把 `.html` 当图片路径。
- **Visio 流程图（`.vsdx`）**：需 **`pip install -e ".[visio]"`** 或 **`pip install "vsdx>=0.6.1"`**（PyPI 包名是 **`vsdx`**，**不是** `python-visio`——后者在 PyPI 上不可用，会导致 *No matching distribution*）。Agent 应使用内置工具 **`visio_flowchart_write`** / **`visio_vsdx_summarize`**，**不要**用 **`script_run`** 手写 `.vsdx` 的 ZIP/XML 目录树（易出现 `visio/_rels` 等路径错误）。用户**明确要求 Visio / `.vsdx`** 时，须生成并**长期保留**源文件（建议 **`output/library/<doc_slug>/diagrams/`** 或 **`output/deliverables/`**）。来自**图片**的流程图可先 **`vision_analyze_image`** 抽取 **`nodes`/`edges`**，再 **`visio_flowchart_write`**。详见 **`src/aicd/agent/prompts.py`** 的 **`VISIO_DIRECTIVES`**。
- **PDF 生成**：**`markdown_to_pdf`** — 默认 **`engine=pymupdf`**（Markdown→HTML→**PyMuPDF Story**，支持表格/代码块/插图，**`archive_path`** 解析相对图片）；可选 **`engine=pandoc`**（需本机 **pandoc**，适合 LaTeX/复杂模板）。**`pdf_compose`** — **ReportLab** 块式排版（**`pip install aicd[pdf]`**）：标题/段落/图片/表格/分页，**`cjk_font_path`** 传入 TTF 以正确排中文。**Word 章节转 PDF**：**`docx_compose`** → **`docx_export_pdf`**（LibreOffice 或 Word+docx2pdf）。
- **样式与 Office**：**`style_reference_scan`**；**`docx_compose`**（可选 **`style_profile_path`**）；**`xlsx_write_workbook`**；**`pptx_inspect_template`** + **`pptx_compose`**。示例配置：**`examples/style_ref/docx_style.example.yaml`**。

## 只读聊天 HTTP API（`aicd serve`）

需安装 **`aicd[api]`**。默认监听 **`127.0.0.1:8765`**（可用 `--host` / `--port` 修改）。

- **`GET /health`** → `{"ok": true}`
- **`GET /v1/sessions/{session_id}/messages?limit=&offset=`** — 分页消息（`limit` 1–2000）
- **`GET /v1/sessions/{session_id}/summaries?limit=`** — 会话摘要列表

若启动时传入 **`--api-key`** 或环境变量 **`AICD_API_KEY`**，则请求须带 **`X-API-Key`** 或 **`Authorization: Bearer <token>`**。

## 离线可视化（导出 HTML）

包内自带 `src/aicd/res/`：**Chart.js**、**Mermaid**、**vis-network**（含 CSS）。升级或重装依赖可执行：

```powershell
python scripts/download_viz_res.py
```

Agent 工具：`viz_export_html`、`viz_data_chart`、`viz_copy_resources`、`viz_list_bundled_assets`；导出前可用 **`viz_spec_validate`**。

## 分析函数库（kit）

`src/aicd/kit/` 提供 JSON 友好的纯函数，并由聚合工具暴露：`data_stats`、`data_text`、`data_time`、`script_template`（骨架 + `script_run`）。实现与路由见 `src/aicd/agent/handlers/`。

## Cursor 技能（`.cursor/skills/`）

仓库内包含若干 **SKILL.md**（工作区、输出目录、聊天历史、大仓库索引 **aicd-code-index**、Draw.io、Visio `.vsdx`（见 **`aicd-ai-output`** 与 **`prompts.py`**）、可视化校验、Analytics、DB 等），便于在 Cursor 中改代码时对齐行为。

## 版本号

- 当前版本见 `src/aicd/version.py` 中的 **`VERSION`**（`pyproject.toml` 动态读取）。**变更摘要**：根目录 **`CHANGELOG.md`**。
- **每次合入/发布前**在仓库根目录执行：`python scripts/bump_version.py`。
- **上传 PyPI 前**先构建再自检：`python scripts/package.py --clean`，然后 `python scripts/release_precheck.py`（可加 `--strict` 做更严的 apiKey 字面量检查）；通过后再上传（需配置 PyPI **API token** 或 `~/.pypirc`，勿将 token 写入仓库）。**Windows** 若 `twine upload` 因控制台编码报错，可：`$env:PYTHONUTF8=1; python -m twine upload dist\aicd-* --non-interactive --disable-progress-bar`。安装校验工具：`pip install twine`。

## 代码结构（速查）

| 路径 | 作用 |
|------|------|
| `src/aicd/app.py` | Typer 入口：`tui` / `init` / `serve` / `version` |
| `src/aicd/runtime.py` | `build_runtime`、工作区/输出目录、`set_vision_llm` / `attach_session_log` |
| `src/aicd/agent/loop.py` | 主对话与子 Agent 工具循环 |
| `src/aicd/agent/llm.py` | OpenAI 兼容客户端、**重试**、**vision 图片编码** |
| `src/aicd/agent/prompts.py` | 系统提示（含 **LARGE_CONTEXT**） |
| `src/aicd/api_serve.py` | FastAPI 只读聊天 API |
| `src/aicd/tools/document_outline.py` | 文档标题索引 |
| `src/aicd/tools/visio_flowchart.py` | Visio **`.vsdx`** 写入与摘要（可选依赖 **`vsdx`**） |
| `src/aicd/tools/markdown_to_pdf.py` | Markdown → PDF（PyMuPDF Story / 可选 pandoc） |
| `src/aicd/tools/pdf_compose_rl.py` | 块式 PDF（**ReportLab**，**`aicd[pdf]`**） |
| `src/aicd/config.py` | **`MAX_AGENT_TOOL_ROUNDS`**、**`LLMConfig`** |
