Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5023cff
feat(agent): ✨ 研究强度、线索跟踪与深度效率旋钮
rainwalkerhu Sep 22, 2026
dce6d3e
feat(search): ✨ 搜索置信度策略与检索协议对齐
rainwalkerhu Sep 22, 2026
b8a58a5
feat(llm): ✨ 请求超时快速失败与降级重试
rainwalkerhu Sep 22, 2026
50166d7
feat(report): ✨ 结构门与人类可读呈现层
rainwalkerhu Sep 22, 2026
afff461
feat(api-server): ✨ 贯通研究强度参数与生效配置快照
rainwalkerhu Sep 22, 2026
3833ee4
feat(gradio-demo): ✨ 单列布局、设置弹窗与进度渲染重构
rainwalkerhu Sep 22, 2026
58637b6
fix(gradio-demo): 🐛 停止真正中断与本地生效配置补全
rainwalkerhu Sep 22, 2026
73b3268
fix(gradio-demo): 🐛 参考来源可点击与设置弹窗/导出交互修正
rainwalkerhu Sep 22, 2026
3e4722c
docs: 📝 补充研究质量文档与变更日志
rainwalkerhu Sep 22, 2026
b3d38f5
chore: 🔧 本地 GLM 配置与实机验收脚本
rainwalkerhu Sep 22, 2026
09bb7eb
fix(report): 总结失败交付降级报告并隐藏占位结论
rainwalkerhu Sep 22, 2026
d690f23
refactor(brand): 项目更名为谛听 / Diting
rainwalkerhu Sep 22, 2026
5f623fb
feat(gradio-demo): 深空主题、玻璃搜索行与进度文案统一
rainwalkerhu Sep 22, 2026
1a5b2a9
docs(changelog): 记录降级报告、品牌更名与深空 UI
rainwalkerhu Sep 22, 2026
ded80ee
fix(gradio-demo): 收敛星空漂浮与闪烁强度
rainwalkerhu Sep 22, 2026
52e15b2
refactor(gradio-demo): extract static assets and UI modules for hot r…
rainwalkerhu Sep 23, 2026
2b1c852
fix: address PR review on compose, scrape budget, early-stop, confidence
rainwalkerhu Sep 23, 2026
3ed79ea
merge: resolve upstream docs i18n conflicts with Diting branding
rainwalkerhu Sep 23, 2026
7c0bfcc
docs: point Chinese doc index at skills/diting
rainwalkerhu Sep 23, 2026
396de8b
chore: expand UI i18n and sync post-review polish
rainwalkerhu Sep 23, 2026
e858546
fix(gradio-demo): stop the dead stop-then-start cycle
rainwalkerhu Sep 24, 2026
dcacc9b
fix(miroflow-agent): gate early-stop on evidence agreement, not domai…
rainwalkerhu Sep 24, 2026
de3d1ee
docs: refresh research-depth roadmap and add jev-search benchmarking …
rainwalkerhu Sep 24, 2026
0334af2
fix(miroflow-agent): fail closed on stale evidence-agreement verdicts
rainwalkerhu Sep 24, 2026
8aa2b9c
docs: backfill review corrections into roadmap and jev-search drafts
rainwalkerhu Sep 24, 2026
fb797ab
fix(miroflow-agent): count scrape evidence only on success with body
rainwalkerhu Sep 28, 2026
fada786
chore: ignore local .workbuddy-ai/ workspace files
rainwalkerhu Sep 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.compose.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ===============================
# OpenClaw-MiroSearch Compose 环境变量示例
# 谛听 Compose 环境变量示例
# 使用方法:
# cp .env.compose.example .env.compose
# docker compose --env-file .env.compose up -d --build
Expand Down Expand Up @@ -60,6 +60,8 @@ DEFAULT_VERIFICATION_MIN_SEARCH_ROUNDS=3
# 页面刷新 / 断电后重连 SSE 续看进度。
# 需配套 api/worker/valkey 服务(compose 已默认包含)。
BACKEND_MODE=api
# 生产/Compose 关闭静态热读,允许短缓存(本地开发默认不设或设 1)
DITING_STATIC_HOT=0
# host-network 模式下使用本机 API 端口;端口映射模式可写 http://api:8090
API_BASE_URL=http://127.0.0.1:8090
# API 模式的 Bearer Token 在上方“API 鉴权”段统一配置
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ data/
.idea/
.windsurf/
.claude/
.workbuddy-ai/
CLAUDE.md

.DS_Store
Expand Down
113 changes: 110 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# OpenClaw-MiroSearch
# Diting (谛听)

<p align="center">
<img src="assets/diting_logo.png" alt="Diting Logo" width="320" />
</p>

[English](README.md) | [中文](README_zh.md)

OpenClaw-MiroSearch is an agentic research service built on MiroThinker. It combines multi-provider web search, full-page extraction, multi-step reasoning, source verification, asynchronous execution, and structured Markdown reports.
Diting (谛听) is an open-source agentic research service built on MiroThinker. It combines multi-provider web search, full-page extraction, multi-step reasoning, source verification, asynchronous execution, and structured Markdown reports.

Current stable release: **v0.2.11**. See the [Changelog](docs/CHANGELOG.md) for released changes and the [Roadmap](docs/ROADMAP.md) for planned work.

Expand Down Expand Up @@ -104,12 +108,115 @@ These are client recommendations, not immutable server defaults. Omitted optiona
- [Changelog](docs/CHANGELOG.md)
- [Security](docs/SECURITY.md)
- [Contributing](docs/CONTRIBUTING.md)
- [OpenClaw skill](skills/openclaw-mirosearch/SKILL.md)
- [Diting skill](skills/diting/SKILL.md)

## Development

Python 3.12+ is required for the primary applications and library.

```bash
# Install app dependencies
cd apps/gradio-demo && uv sync
cd ../miroflow-agent && uv sync
cd ../../libs/miroflow-tools && uv sync
```

If you need legacy compatibility or want to reuse the Demo UI directly, Gradio API remains available:

```bash
BASE_URL="http://127.0.0.1:8080"
curl -sS "$BASE_URL/gradio_api/info"
```

## For OpenClaw / AI Agents

Project positioning:

- Provides web research capability callable by upper-layer agents
- Supports four-dimensional control: mode, routing, search depth, and output detail
- Uses SSE terminal events so agents can determine task completion

Recommended agent calling loop:

1. Call `GET /health` for health check
1. Submit `POST /v1/research`
1. Poll `GET /v1/research/{task_id}` or subscribe to `GET /v1/research/{task_id}/stream`
1. When `status=completed` or `cached`, consume only the final Markdown

Skill guidance:

- Simple search, single-fact lookup, and cost-first usage: use the repository-distributed `searxng` skill
- Repository: `skills/searxng/`
- Packaged file: `skills/searxng.zip`
- Deep research or high-quality retrieval: use the `diting` skill
- Skill docs: [`skills/diting/SKILL.md`](skills/diting/SKILL.md)
- Usage docs: [`skills/diting/references/usage.md`](skills/diting/references/usage.md)

Skill acquisition and installation:

- Recommended dual-skill bundle: `skills/openclaw-search-skills-bundle.zip`
- Simple search skill: `skills/searxng/`
- Repository: `skills/diting/`
- Packaged file: `skills/diting.zip`
- Installation guide: [`skills/diting/references/skill-install.md`](skills/diting/references/skill-install.md)
- API docs: [`skills/diting/references/api.md`](skills/diting/references/api.md)
- AI Agent integration: [`docs/API_SPEC.md`](docs/API_SPEC.md)

## Recommended Configuration Baseline

- **Default production**: `mode=balanced` + `search_profile=parallel-trusted`
- **High-risk fact-checking**: `mode=verified` + `search_profile=parallel-trusted`
- **Quota-priority**: `mode=quota` + `search_profile=searxng-only`
- **Verification depth**: `search_result_num=30` + `verification_min_search_rounds=4`

> For the full list of routing environment variables, see [`apps/miroflow-agent/README.md`](apps/miroflow-agent/README.md#4-检索路由配置) and [`docs/API_SPEC.md`](docs/API_SPEC.md)

## Changelog

- Release `0.2.4` highlights:
- `scrape_url` now supports PDF extraction with a 20MB streamed body limit
- JSON / RSS / Atom / XML payloads can pass through with structured fields (`json_keys`, `feed_title`, `entries`, `xml_root`)
- Redirect handling now uses streamed responses and closes intermediate 30x hops eagerly
- Local Docker end-to-end verification passed on the `app + api + worker + searxng + valkey` stack
- See [`docs/SCRAPING_ITERATION_PLAN.md`](docs/SCRAPING_ITERATION_PLAN.md) for the full T1–T9 scraping roadmap
- Release `0.2.2` highlights:
- API-mode regression fix: `mode` / `search_profile` / `search_result_num` / `verification_min_search_rounds` / `output_detail_level` are now respected end-to-end via `services/profile_resolver.py`
- Demo crash-recovery: `BACKEND_MODE=api` plus `?task_id=xxx` URL bridge — refresh / disconnect resumes the same task via SSE replay
- MCP tool `scrape_url`: lightweight `httpx + BeautifulSoup` scraper with SSRF guard so the LLM can "open the page" when `google_search` snippets are insufficient
- Worker cancel watcher hardened against Redis hiccups; unresponsive pipelines are abandoned after a 10s timeout
- Dockerfile uses a domestic apt mirror by default; compose builds run with `network: host`; `scripts/deploy/build_images.sh` bypasses BuildKit's `network.host` entitlement prompt
- Release `0.2.1` highlights:
- Clickable `[N]` references in research summaries pointing to the report's References / 参考文献 section
- `api-worker` startup command pinned to `.venv/bin/python` for reliable arq worker boot
- Release `0.2.0` highlights:
- Async task queue (arq + Valkey), persistent SSE event streams, cache and metadata persistence
- `SearchProvider` Protocol + `ProviderRegistry` (Serper / SerpAPI / SearXNG)
- Full history: [`docs/CHANGELOG.md`](docs/CHANGELOG.md)

## Documentation Index

- Overview: [`docs/README.md`](docs/README.md)
- Architecture: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
- Deployment: [`docs/DEPLOY.md`](docs/DEPLOY.md)
- API spec & Agent integration: [`docs/API_SPEC.md`](docs/API_SPEC.md)
- Roadmap: [`docs/ROADMAP.md`](docs/ROADMAP.md)
- Changelog: [`docs/CHANGELOG.md`](docs/CHANGELOG.md)
- Demo docs: [`apps/gradio-demo/README.md`](apps/gradio-demo/README.md)
- API server docs: [`apps/api-server/README.md`](apps/api-server/README.md)
- Agent docs: [`apps/miroflow-agent/README.md`](apps/miroflow-agent/README.md)
- Tools docs: [`libs/miroflow-tools/README.md`](libs/miroflow-tools/README.md)
- Diting skill package: [`skills/diting/SKILL.md`](skills/diting/SKILL.md)

## Open Source Collaboration

- Contributing, governance, support & release: [`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md)
- Security policy: [`docs/SECURITY.md`](docs/SECURITY.md)
- Code of conduct: [`docs/CODE_OF_CONDUCT.md`](docs/CODE_OF_CONDUCT.md)
- Changelog: [`docs/CHANGELOG.md`](docs/CHANGELOG.md)


## Development Validation

```bash
# Repository-wide checks
just lint
Expand Down
110 changes: 106 additions & 4 deletions README_zh.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# OpenClaw-MiroSearch
# 谛听(Diting)

<p align="center">
<img src="assets/diting_logo.png" alt="Diting Logo" width="320" />
</p>

[English](README.md) | [中文](README_zh.md)

OpenClaw-MiroSearch 是基于 MiroThinker 构建的智能体研究服务,集成多源网页检索、正文抓取、多步推理、来源校验、异步执行和结构化 Markdown 报告。
谛听(Diting)是基于 MiroThinker 构建的开源智能体研究服务,集成多源网页检索、正文抓取、多步推理、来源校验、异步执行和结构化 Markdown 报告。

当前稳定版本:**v0.2.11**。已发布变更见 [变更记录](docs/CHANGELOG_zh.md),未来计划见 [路线图](docs/ROADMAP_zh.md)。

Expand Down Expand Up @@ -37,6 +41,8 @@ OpenClaw-MiroSearch 是基于 MiroThinker 构建的智能体研究服务,集

需要 Docker Compose v2、一个 OpenAI 兼容或 Anthropic LLM 端点,以及至少一个可用搜索来源。

<p align="center"><img src="assets/demo-screenshot.png" alt="Demo Screenshot" width="900" /></p>

```bash
cp .env.compose.example .env.compose
# 编辑 .env.compose,替换 LLM 和搜索服务的占位凭据。
Expand Down Expand Up @@ -104,20 +110,116 @@ curl -sS -N http://127.0.0.1:8090/v1/research/<task_id>/stream
- [变更记录](docs/CHANGELOG_zh.md)
- [安全策略](docs/SECURITY_zh.md)
- [贡献指南](docs/CONTRIBUTING_zh.md)
- [OpenClaw Skill](skills/openclaw-mirosearch/SKILL.md)
- [Diting Skill](skills/diting/SKILL.md)

## 开发

主要应用和工具库要求 Python 3.12+。

```bash
# 安装依赖
cd apps/gradio-demo && uv sync
cd ../miroflow-agent && uv sync
cd ../../libs/miroflow-tools && uv sync
```

如需兼容旧链路或直接复用 Demo UI,仍可使用 Gradio API:

```bash
BASE_URL="http://127.0.0.1:8080"
curl -sS "$BASE_URL/gradio_api/info"
```

## 面向 OpenClaw / AI Agent

这个项目的定位:

- 提供可被上层智能体调用的联网研究能力
- 支持模式、路由、检索深度与输出篇幅四维可控
- 通过 SSE 终态事件,保证智能体编排时可判断任务完成

推荐给 AI Agent 的调用闭环:

1. 先调 `GET /health` 探活
1. 发起 `POST /v1/research`
1. 轮询 `GET /v1/research/{task_id}` 或订阅 `GET /v1/research/{task_id}/stream`
1. `status=completed` 或 `cached` 时,只消费最终 Markdown

Skill 使用建议(先分流):

- 简单搜索(快速网页检索、单事实查询):优先使用仓库内分发的 `searxng` skill
- 仓库目录:`skills/searxng/`
- 打包文件:`skills/searxng.zip`
- 深度检索或高质量检索(多来源交叉、核查、研究报告):使用 `diting` skill

Skill 安装:

- 推荐双 skill 打包:`skills/openclaw-search-skills-bundle.zip`
- 简单搜索 skill:`skills/searxng/`
- 仓库目录:`skills/diting/`
- 打包文件:`skills/diting.zip`
- 安装说明:[`skills/diting/references/skill-install.md`](skills/diting/references/skill-install.md)

Skill 使用:

- 使用说明:[`skills/diting/references/usage.md`](skills/diting/references/usage.md)
- API 说明:[`skills/diting/references/api.md`](skills/diting/references/api.md)
- AI Agent 接入详解:[`docs/API_SPEC.md`](docs/API_SPEC.md)

## 建议配置基线

- **默认生产**:`mode=balanced` + `search_profile=parallel-trusted`
- **高风险事实核查**:`mode=verified` + `search_profile=parallel-trusted`
- **额度优先**:`mode=quota` + `search_profile=searxng-only`
- **核查深度**:`search_result_num=30` + `verification_min_search_rounds=4`

> 完整路由环境变量说明请参见 [`apps/miroflow-agent/README.md`](apps/miroflow-agent/README.md) 和 [`docs/API_SPEC.md`](docs/API_SPEC.md)

## 版本亮点

- `0.2.4` 版本亮点:
- `scrape_url` 已支持 PDF 抽取,并带 20MB 流式响应体上限
- 已支持 JSON / RSS / Atom / XML 结构化直通,返回 `json_keys`、`feed_title`、`entries`、`xml_root` 等字段
- 重定向链路改为流式响应,并在中间 30x hop 及时关闭连接
- 本地 Docker `app + api + worker + searxng + valkey` 真实端到端验证已通过
- `0.2.2` 版本亮点:
- API 模式严重回归修复:`mode` / `search_profile` / `search_result_num` / `verification_min_search_rounds` / `output_detail_level` 已可端到端透传
- Demo 断线重连:`BACKEND_MODE=api` 配合 `?task_id=xxx` 可通过 SSE 回放恢复任务
- MCP `scrape_url` 初版上线:基于 `httpx + BeautifulSoup`,在 `google_search` 摘要不足时让 LLM 主动打开正文
- 详细抓取路线图见 [`docs/SCRAPING_ITERATION_PLAN.md`](docs/SCRAPING_ITERATION_PLAN.md)

## 文档索引

- 文档总览:[`docs/README.md`](docs/README.md)
- 架构概览:[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
- 部署指南:[`docs/DEPLOY.md`](docs/DEPLOY.md)
- API 规格 & Agent 接入:[`docs/API_SPEC.md`](docs/API_SPEC.md)
- 路线图:[`docs/ROADMAP.md`](docs/ROADMAP.md)
- 抓取能力迭代计划:[`docs/SCRAPING_ITERATION_PLAN.md`](docs/SCRAPING_ITERATION_PLAN.md)(T1-T9,对应 v0.2.4 → v0.3.0)
- 变更记录:[`docs/CHANGELOG.md`](docs/CHANGELOG.md)
- Demo 说明:[`apps/gradio-demo/README.md`](apps/gradio-demo/README.md)
- API Server 说明:[`apps/api-server/README.md`](apps/api-server/README.md)
- Agent 说明:[`apps/miroflow-agent/README.md`](apps/miroflow-agent/README.md)
- 工具层说明:[`libs/miroflow-tools/README.md`](libs/miroflow-tools/README.md)
- Diting 技能包:[`skills/diting/SKILL.md`](skills/diting/SKILL.md)

## 开源协作文档

- 贡献、治理、支持与发布:[`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md)
- 安全策略:[`docs/SECURITY.md`](docs/SECURITY.md)
- 行为准则:[`docs/CODE_OF_CONDUCT.md`](docs/CODE_OF_CONDUCT.md)
- 变更记录:[`docs/CHANGELOG.md`](docs/CHANGELOG.md)

## 开发验证

```bash
# 仓库级检查
just lint
just sort-imports
just format
just format-md

# 各模块测试
# 分模块测试
cd apps/miroflow-agent && uv sync && uv run pytest
cd apps/api-server && uv sync && AUTH_DISABLED=1 uv run pytest
cd apps/gradio-demo && uv sync && uv run pytest
Expand Down
2 changes: 1 addition & 1 deletion apps/api-server/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# MiroSearch API Server
# Diting API Server

[English](README.md) | [中文](README_zh.md)

Expand Down
4 changes: 2 additions & 2 deletions apps/api-server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ async def _cleanup_loop():


app = FastAPI(
title="MiroSearch API",
description="OpenClaw-MiroSearch 标准 HTTP API,独立于 Gradio Demo",
title="Diting API",
description="谛听标准 HTTP API,独立于 Gradio Demo",
version=settings.api_version,
docs_url="/docs",
redoc_url="/redoc",
Expand Down
32 changes: 32 additions & 0 deletions apps/api-server/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
MAX_VERIFICATION_SEARCH_ROUNDS = 8


VALID_RESEARCH_INTENSITIES = ("light", "standard", "deep")


class ResearchRequest(BaseModel):
"""POST /v1/research 请求体。

Expand All @@ -55,6 +58,10 @@ class ResearchRequest(BaseModel):
default=None,
description="输出篇幅档位",
)
research_intensity: Optional[str] = Field(
default=None,
description="研究强度:light / standard / deep(可选,默认 standard)",
)
caller_id: Optional[str] = Field(
default=None, description="调用方 ID,用于定向取消"
)
Expand Down Expand Up @@ -114,6 +121,18 @@ def validate_output_detail_level(cls, v: Optional[str]) -> Optional[str]:
)
return normalized

@field_validator("research_intensity")
@classmethod
def validate_research_intensity(cls, v: Optional[str]) -> Optional[str]:
if v is None:
return None
normalized = v.strip().lower()
if normalized not in VALID_RESEARCH_INTENSITIES:
raise ValueError(
f"research_intensity must be one of {VALID_RESEARCH_INTENSITIES}, got '{v}'"
)
return normalized

@field_validator("caller_id")
@classmethod
def validate_caller_id(cls, v: Optional[str]) -> Optional[str]:
Expand Down Expand Up @@ -163,6 +182,17 @@ class ErrorResponse(BaseModel):
# ---- 新增任务状态模型 ----


class EffectiveConfig(BaseModel):
"""实际生效的配置(记录任务真正使用的参数)。"""

mode: str
search_profile: str
search_result_num: int
verification_min_search_rounds: int
output_detail_level: str
research_intensity: Optional[str] = None


class ResearchTaskMeta(BaseModel):
"""任务元数据。"""

Expand All @@ -175,6 +205,8 @@ class ResearchTaskMeta(BaseModel):
search_result_num: int = 20
verification_min_search_rounds: int = 3
output_detail_level: str = "detailed"
research_intensity: Optional[str] = None
effective_config: Optional[EffectiveConfig] = None
created_at: float = 0.0
started_at: Optional[float] = None
finished_at: Optional[float] = None
Expand Down
2 changes: 1 addition & 1 deletion apps/api-server/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[project]
name = "api-server"
version = "0.2.0"
description = "FastAPI API server for MiroSearch, independent from Gradio demo"
description = "FastAPI API server for Diting, independent from Gradio demo"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
Expand Down
Loading