feat(v1.8.0): 稳定性修复 + AI Agent 体验增强
稳定性修复: - 修复 cache.py SQLite 连接泄漏(contextlib.closing 包装) - 修复 fetch.py requests stream=True 连接泄漏(try/finally resp.close()) - RETRYABLE_STATUS 新增 403,激活 UA fallback 切换逻辑 - --cache-stats 移至实例解析前,无需实例即可查询 - classify_error 从错误消息提取 HTTP 状态码,正确分类 E_AUTH/E_RATE_LIMIT - --stream 与 --queries-file 互斥检查,违规报 E_INPUT - batch 退出码语义统一(0=有结果 / 1=全部错误 / 2=全部空结果) AI Agent 体验增强: - 错误码体系完善:E_CONFIG/E_AUTH/E_NETWORK/E_RATE_LIMIT/E_PARSE/E_EMPTY/E_INPUT/E_INTERNAL - recovery_hint 恢复提示字段,AI Agent 可程序化决策恢复策略 - stream 模式新增 error 事件类型(含 error_code + recovery_hint) - 进度事件扩展:instance_try/instance_ok/instance_fail - batch 模式统一 schema(status 字段区分 success/failed) - JSON 输出含 schema_version 字段确保版本兼容 测试与文档: - 测试覆盖:330 -> 352 - SKILL.md / README.md 同步更新
This commit is contained in:
@@ -55,36 +55,47 @@ AI 调用后,stdout 输出网页正文(text/html/markdown 三种格式),
|
||||
| exit 1 | 失败 | 致命错误(所有实例不可用、参数错误等) |
|
||||
| exit 2 | 空结果 | 搜索成功但无结果 |
|
||||
|
||||
**错误处理**:`--format json` 模式下,错误以 JSON 输出到 stdout(非 stderr),格式为 `{"error": "...", "error_code": "E_NETWORK", "exit_code": 1, "query": "..."}`,AI 可程序化捕获。
|
||||
**错误处理**:`--format json` 模式下,错误以 JSON 输出到 stdout(非 stderr),格式为 `{"error": "...", "error_code": "E_NETWORK", "recovery_hint": "...", "exit_code": 1, "query": "..."}`,AI 可程序化捕获并按 `recovery_hint` 采取恢复行动。
|
||||
|
||||
**错误码体系**(`error_code` 字段):
|
||||
**错误码体系**(`error_code` + `recovery_hint` 字段):
|
||||
|
||||
| 错误码 | 含义 | AI 恢复策略 |
|
||||
|--------|------|-------------|
|
||||
| `E_CONFIG` | 配置错误(无实例) | 提示用户设置 `-i` / `SEARXNG_INSTANCE` |
|
||||
| `E_AUTH` | 认证失败(401/403) | 检查 token/凭证 |
|
||||
| `E_NETWORK` | 网络错误(连接失败、5xx) | 重试或切换实例/代理 |
|
||||
| `E_RATE_LIMIT` | 限流(429) | 等待后重试 |
|
||||
| `E_PARSE` | 解析错误 | 检查实例 JSON 支持 |
|
||||
| `E_INPUT` | 输入错误(参数/文件) | 修正参数 |
|
||||
| `E_INTERNAL` | 内部错误 | 报告 bug |
|
||||
| 错误码 | 含义 | recovery_hint(节选) |
|
||||
|--------|------|----------------------|
|
||||
| `E_CONFIG` | 配置错误(无实例) | 设置 `-i`/`SEARXNG_INSTANCE`/配置文件 |
|
||||
| `E_AUTH` | 认证失败(401/403) | 检查凭证、token 过期与权限 |
|
||||
| `E_NETWORK` | 网络错误(连接失败、5xx) | 重试退避、切换实例、检查代理 |
|
||||
| `E_RATE_LIMIT` | 限流(429) | 等待重试、降低频率、分散负载 |
|
||||
| `E_PARSE` | 解析错误 | 切换实例、切换 `--method` |
|
||||
| `E_EMPTY` | 空结果(exit 2) | 调整查询词、扩大 `--time-range`/`--categories` |
|
||||
| `E_INPUT` | 输入错误(参数/文件) | 检查语法、标志组合、文件路径 |
|
||||
| `E_INTERNAL` | 内部错误 | 用 `--verbose` 重跑并报告 |
|
||||
|
||||
### 流式输出与进度事件(AI 高级用法)
|
||||
|
||||
**`--stream`**:JSON Lines 流式输出,每条结果一行 JSON,AI 可增量处理:
|
||||
```
|
||||
{"type": "result", "result": {"title": "...", "url": "..."}}
|
||||
{"type": "done", "count": 10, "query": "..."}
|
||||
{"type": "done", "schema_version": "1.0", "count": 10, "query": "..."}
|
||||
```
|
||||
搜索失败时输出 error 事件(含 `recovery_hint`):
|
||||
```
|
||||
{"type": "error", "error": "...", "error_code": "E_AUTH", "recovery_hint": "Verify credentials...", "query": "..."}
|
||||
```
|
||||
注意:`--stream` 仅在单查询 + `--format json` 下有效;与 `--queries-file` 或非 json 格式同用会立即报 `E_INPUT`。
|
||||
|
||||
**`--progress`**:进度事件流(JSON Lines 到 stderr),AI 可实时跟踪执行:
|
||||
```
|
||||
{"event": "start", "query": "...", "instances": 2}
|
||||
{"event": "instance_try", "url": "https://inst1.example.com", "attempt": 1}
|
||||
{"event": "instance_ok", "url": "https://inst1.example.com", "latency": 0.342, "results": 10}
|
||||
{"event": "instance_fail", "url": "https://inst2.example.com", "error": "HTTP 503", "error_code": "E_NETWORK"}
|
||||
{"event": "cache_hit", "query": "...", "ttl": 30}
|
||||
{"event": "fetch_ok", "url": "...", "chars": 12345}
|
||||
{"event": "done", "results": 10, "query": "..."}
|
||||
```
|
||||
|
||||
**`--dump-schema`**:输出当前版本的 JSON Schema 到 stdout 并退出,AI 可程序化发现字段名与类型,无需解析文档。
|
||||
|
||||
```bash
|
||||
# AI 推荐用法:流式输出 + 进度事件
|
||||
python scripts/search.py -q "research" -i https://your-instance --stream --progress
|
||||
@@ -94,7 +105,7 @@ python scripts/search.py -q "research" -i https://your-instance --stream --progr
|
||||
|
||||
### 前置条件
|
||||
|
||||
- Python 3.8+
|
||||
- Python 3.8+(3.11+ 开箱即用;3.8-3.10 使用 `searxng.toml` 配置需 `pip install tomli`)
|
||||
- 一个 SearXNG 实例 URL(自建或受信任的实例)
|
||||
|
||||
### 安装
|
||||
@@ -105,9 +116,13 @@ git clone https://git.metona.cn/MetonaTeam/searxng-use-cli.git
|
||||
|
||||
无需安装依赖。`search.py` 仅使用 Python 标准库,开箱即用。
|
||||
|
||||
可选安装(提升 `fetch.py` 抓取质量):
|
||||
可选安装:
|
||||
```bash
|
||||
# 提升 fetch.py 抓取质量(HTTP 连接池 + HTML 解析)
|
||||
pip install requests beautifulsoup4
|
||||
|
||||
# Python 3.8-3.10 使用 searxng.toml 配置文件时需要(3.11+ 内置 tomllib)
|
||||
pip install tomli
|
||||
```
|
||||
|
||||
### 配置实例
|
||||
@@ -248,10 +263,12 @@ python scripts/fetch.py -u https://example.com \
|
||||
**工程**
|
||||
- 共享 `common.py`(统一重试/字符集/认证/日志)
|
||||
- 结构化日志(`--verbose` / `--quiet`)
|
||||
- 结构化错误码(`E_NETWORK` / `E_AUTH` / `E_RATE_LIMIT` 等)
|
||||
- JSON Lines 流式输出(`--stream`)
|
||||
- 进度事件(`--progress`,JSON Lines 到 stderr)
|
||||
- 330 个单元+集成测试
|
||||
- 结构化错误码 + `recovery_hint` 恢复建议(`E_NETWORK` / `E_AUTH` / `E_RATE_LIMIT` 等)
|
||||
- JSON 输出含 `schema_version` 字段,`--dump-schema` 输出 JSON Schema 文档
|
||||
- JSON Lines 流式输出(`--stream`,含 `error` 事件类型)
|
||||
- 进度事件(`--progress`,含 `instance_try`/`instance_ok`/`instance_fail`,JSON Lines 到 stderr)
|
||||
- batch 模式统一 schema(`status` 字段区分成功/失败)
|
||||
- 352 个单元+集成测试
|
||||
|
||||
## 跨 Agent 兼容性
|
||||
|
||||
@@ -279,7 +296,7 @@ pip install pytest
|
||||
pytest -q
|
||||
```
|
||||
|
||||
330 个测试覆盖:缓存操作、认证解析、域名过滤、Markdown 转换、搜索逻辑、集成流程、日志配置、HTML 回退、自动抓取、健康检查、输出格式化、实例解析、并行搜索、CLI 端到端、错误码分类、流式输出、进度事件、配置文件认证。
|
||||
352 个测试覆盖:缓存操作、认证解析、域名过滤、Markdown 转换、搜索逻辑、集成流程、日志配置、HTML 回退、自动抓取、健康检查、输出格式化、实例解析、并行搜索、CLI 端到端、错误码分类、流式输出、进度事件、配置文件认证、schema_version、recovery_hint、batch 统一 schema、--dump-schema。
|
||||
|
||||
## 项目结构
|
||||
|
||||
|
||||
Reference in New Issue
Block a user