Skip to content

Commit 2a2817e

Browse files
feat(opencli):align-workflows-and-native-agents
1 parent 23997ee commit 2a2817e

303 files changed

Lines changed: 36483 additions & 1235 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.docker.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ TASK_EXECUTOR=local
2626
COLLECTION_MODE=local
2727
DEBUG=false
2828

29+
# Optional built-in web search. This base URL must be reachable from the API
30+
# container, and the SearXNG service must enable the JSON search format.
31+
SEARXNG_URL=
32+
# Enable only for an operator-owned search service on the private network.
33+
# User-supplied page URLs remain subject to public-address validation.
34+
SEARXNG_ALLOW_PRIVATE=false
35+
2936
# Optional: Feishu bot webhook for Gaojixing verification recovery alerts.
3037
GAOJIXING_FEISHU_WEBHOOK_URL=
3138
# Optional External Analysis Runtime. The default Compose stack does not start

.env.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ AGENT_CODEX_ALLOWED_ROOTS=
3434
# 仅在同一部署还通过额外域名访问 /mcp 时补充,逗号分隔。
3535
OPENCLI_MCP_ALLOWED_HOSTS=
3636
OPENCLI_MCP_ALLOWED_ORIGINS=
37+
# REST address reached by the MCP adapter. Inside the API container use
38+
# http://127.0.0.1:8000; native development defaults to port 8031.
39+
OPENCLI_ADMIN_API_URL=http://localhost:8031
40+
# stdio only: caller identity bearer, separate from fleet API_AUTH_TOKEN.
41+
# HTTP MCP forwards the authenticated caller's Authorization header instead.
42+
OPENCLI_MCP_CALLER_TOKEN=
43+
# Optional SearXNG base URL with JSON output enabled. Without it, research
44+
# supports explicitly supplied public URLs and reports search as unavailable.
45+
SEARXNG_URL=
46+
# Enable only for an operator-owned search service on localhost/private LAN.
47+
# Public page retrieval keeps the default private-address prohibition.
48+
SEARXNG_ALLOW_PRIVATE=false
3749

3850
# 组织身份验证(标准 OpenID Connect;提供方可为 Gitea、Keycloak、Authentik、
3951
# Azure AD 或任何兼容 OIDC 的企业身份源)。

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ coverage.xml
4444
node_modules/
4545
frontend/node_modules/
4646
frontend/.next/
47+
frontend/.next-*/
4748
frontend/dist/
4849
frontend/tsconfig.tsbuildinfo
4950
frontend/.mcp.json

Dockerfile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ ENV PYTHONPATH=/app \
6666
ARG IMAGE_TAG=latest
6767
ENV IMAGE_TAG=${IMAGE_TAG}
6868

69+
EXPOSE 8000
70+
71+
ENTRYPOINT ["/entrypoint.sh"]
72+
CMD ["uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "8000", "--access-log", "--log-level", "info"]
73+
6974
# Acceptance-only image: production runtime plus the independently pinned III
7075
# engine and deterministic source-only CLI fixture. It is never the default
7176
# Compose image.
@@ -95,7 +100,5 @@ ENV III_CLI_PATH=/opt/iii/iii \
95100
OPENCLI_BIN=/opt/non-bypass/opencli-proof
96101
USER appuser
97102

98-
EXPOSE 8000
99-
100-
ENTRYPOINT ["/entrypoint.sh"]
101-
CMD ["uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "8000", "--access-log", "--log-level", "info"]
103+
# Keep the default Docker output free of acceptance fixtures and harnesses.
104+
FROM runtime AS production

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![License](https://img.shields.io/github/license/2233admin/opencli-Razormind)](LICENSE)
66
[![Docker](https://img.shields.io/badge/docker-amd64%20%7C%20arm64-2496ED?logo=docker&logoColor=white)](https://github.com/2233admin/opencli-Razormind/pkgs/container/opencli-admin-api)
77

8-
opencli-Razormind 是一个开源、自托管的研究与情报管线。它把浏览器 / OpenCLI / RSS / API 数据采集、可视化工作流、AI 处理、证据关系和结果交付,统一到一个可运行、可审计的系统中
8+
opencli-Razormind 是一个开源、自托管的研究与情报平台。平台 Agent 负责获取、整理和分析信息,保留来源与运行记录;Codex、Claude Code 等下游 Agent 通过 API / MCP 查询项目内的成果
99

1010
![License](https://img.shields.io/badge/license-Apache--2.0-blue)
1111
![Stars](https://img.shields.io/github/stars/2233admin/opencli-Razormind)
@@ -16,6 +16,22 @@ opencli-Razormind 是一个开源、自托管的研究与情报管线。它把
1616
- **适合谁**:做研究或情报收集,想把采集、工作流、AI 处理、证据和交付串起来的。
1717
- **不适合谁**:只需要一个单点爬虫脚本、不想运维一套系统的。
1818

19+
当前源码的操作路径、Agent 接入方式和已知缺口见[使用说明(核对稿)](docs/usage/product-manual.md)[产品契约核对记录](docs/usage/product-contract-findings.md)。两份文档区分现场观察、测试结果、实现依据和设计目标,不代表完整持续采集链路已经验收。
20+
21+
## 从一个场景开始
22+
23+
当前开发分支的 `/launch` 入口聚焦以下三个场景;这些新增能力不属于下面的旧版 `v0.4.1` 镜像。完整工作流编辑、浏览器账号和既有项目仍可从原入口使用。
24+
25+
| 场景 | 输入 | 预期成果 |
26+
| --- | --- | --- |
27+
| 公开资料研究 | 一个问题,可选公开网页 URL | 带来源引用的研究结论、采集时间与未解决问题 |
28+
| 竞品网页变化跟踪 | 一组固定的公开网页 URL | 与各网页上次成功采集结果的差异;首次运行建立基线 |
29+
| 项目知识查询 | 项目和检索词 | 已授权项目内的匹配记录与来源,供人和下游 Agent 使用 |
30+
31+
先在平台配置可用模型,再选择工作区和项目运行研究。仅输入问题的网页研究还需要配置启用 JSON 输出的 SearXNG 服务(`SEARXNG_URL`);提供公开 URL 时可以直接采集。界面的就绪状态会显示缺失配置,运行结果中的缺口需与结论一起阅读。变化跟踪当前由用户发起每次运行,定时工作流属于原有高级入口。
32+
33+
配置步骤见[内置研究与变化跟踪](docs/usage/research.md),下游接入见[Codex / Claude Code 的 API 与 MCP 配置](docs/usage/downstream-agents.md)。当前真实运行的证据与尚未验证的范围见[首发验收记录](docs/testing/launch-live-acceptance-2026-09-14.md)
34+
1935
## 为什么做这个
2036

2137
做研究或情报收集的时候,工具链总是碎的:浏览器登录态在本地、爬虫脚本在服务器、数据在 Excel、分析在另一个工具、交付靠手动复制粘贴。这个系统想把整条链路串起来——从登录采集到工作流编排,到 AI 处理,到证据关系,到定时交付,都在一个界面里完成。
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
---
2+
title: 'Codex / OMP 原生 TUI 会话'
3+
type: 'feature'
4+
created: '2026-09-17'
5+
status: 'done'
6+
baseline_commit: '23997ee8215357af3f3b755fa4bd6404fe97c365'
7+
review_loop_iteration: 0
8+
context:
9+
- 'frontend/components/experience/alice-chat/README.md'
10+
- 'agent/native-chat/README.md'
11+
---
12+
13+
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
14+
15+
## Intent
16+
17+
**Problem:** `/launch` 目前只把 Codex / OMP CLI 当作 GUI 对话的推理后端;模式菜单仍禁用 TUI,用户无法获得 Alice 已有的原生终端交互、持续会话和重连体验。
18+
19+
**Approach:** 在右侧聊天区接入真实 PTY 终端。前端复用 Alice 的 xterm 交互;控制面通过已认证 WebSocket 与 Fleet 出站连接复用现有 WSL 隔离节点,节点持有 PTY、回放缓冲和进程清理证据。首版支持已经授权的 Codex 与 OMP,不改变左侧导航或 GUI 对话路径。
20+
21+
## Boundaries & Constraints
22+
23+
**Always:** 工作区身份、平台管理员与执行权限必须在创建、附着、输入、接管、停止时逐次校验;只允许匹配当前原生绑定的保留节点。PTY 在既有 bubblewrap 边界内运行,仅挂载对应运行时凭据与只读空工作目录,不获得控制面环境、主机仓库或另一运行时凭据。刷新/短暂断线重附着同一 PTY并回放权威终端快照;单会话仅一个写入控制者。停止必须等待进程组清理确认,Ctrl+C 只作为终端输入。
24+
25+
**Ask First:** 开放任意项目目录写入、CLI 原生工具/插件/MCP、普通成员或其他工作区共享本机账号、接入 Codex/OMP 之外运行时。
26+
27+
**Never:** 伪造终端输出;在控制面直接启动 CLI;用 Docker 或 PowerShell 作为 TUI 前提;复制 Alice 的 localhost 免认证;把浏览器断开当作进程停止;绕过既有提案、权限或保留节点门禁;改写左侧导航。
28+
29+
## I/O & Edge-Case Matrix
30+
31+
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
32+
|----------|--------------|---------------------------|----------------|
33+
| 首次启动 | 有效工作区、Codex/OMP 在线绑定、选择 TUI | 创建持久技术会话,终端显示真实 CLI,键盘输入与 ANSI 输出双向流动 | 启动失败不生成可附着会话,显示可重试原因 |
34+
| 刷新重连 | PTY仍存活,浏览器重载或网络短断 | 重新附着同一会话,先回放快照,再解锁输入 | 有界退避;未知/已结束会话明确关闭,不自动新建 |
35+
| 多窗口 | 第二控制者附着同一会话 | 只读拒绝并显示接管操作;显式接管后旧连接被踢出 | 不自动抢占,不缓存断线期间输入 |
36+
| Resize / 中文输入 | 容器尺寸变化、IME或Kitty键盘模式 | PTY尺寸同步,组合输入与特殊键不丢失 | cols/rows限制在1–1000,畸形控制帧关闭连接 |
37+
| 停止与退出 | 点击停止、CLI自然退出、API重启 | 停止等待清理证明;自然退出显示退出码;API恢复后可查询同一节点状态 | 未确认清理保持锁定,不显示假成功 |
38+
| 越权 | 错误工作区、非管理员、绑定变更或通用调度调用 | 拒绝创建、附着、输入和派发 | 返回通用错误,不泄露节点、路径、命令或凭据 |
39+
40+
</frozen-after-approval>
41+
42+
## Code Map
43+
44+
- `frontend/components/experience/alice-chat/chat-surface.tsx:113` -- 当前 GUI/TUI 模式菜单;TUI被硬禁用。
45+
- `frontend/components/shell/global-agent-dock.tsx:741` -- `/launch` 右侧会话编排、运行时选择与停止入口;在此切换 GUI/终端内容。
46+
- `frontend/lib/api/agent-conversations.ts:151` -- 执行配置与会话 API 类型;增加终端会话/状态客户端。
47+
- `frontend/components/experience/alice-chat/terminal/` -- 新终端叶组件;从 Alice `Terminal.tsx`、协议、输入/IME、renderer 与 appearance 依赖闭包移植,保留 AGPL 来源说明。
48+
- `backend/schemas/agent_conversation.py:21` -- 当前执行模式仅 `gui`;增加受约束的 `terminal`
49+
- `backend/api/v1/agent_conversations.py:179` -- 既有会话取消入口;同一认证域新增终端创建、状态、停止和 WebSocket。
50+
- `backend/services/agent_native_chat.py` -- 复用精确工作区/运行时/节点绑定与权限校验,不另建宽松授权路径。
51+
- `backend/ws_agent_manager.py:335` -- Fleet 唯一派发门;增加保留节点终端帧多路复用、附着、输入、resize、状态和清理确认。
52+
- `backend/agent_server.py:480` -- 节点任务生命周期与终态证明;新增节点侧 PTY 管理、单写入、回放缓冲和重附着。
53+
- `agent/native-chat/runner.py` -- 复用 bubblewrap 隔离清单,增加交互 TUI 入口但不扩大挂载或环境。
54+
- `D:/Temp/openalice-comparison-20260915/ui/src/components/workspace/Terminal.tsx:294` -- 只读参考:冷附着回放、二进制输入、resize、重连、IME/Kitty与单控制者体验。
55+
- `D:/Temp/openalice-comparison-20260915/src/webui/workspaces-ws.ts:43` -- 只读参考:PTY WS 协议与状态码;其 localhost 信任规则不得照搬。
56+
57+
## Tasks & Acceptance
58+
59+
**Execution:**
60+
- [x] `backend/models/`, `backend/schemas/agent_conversation.py`, `backend/api/v1/agent_conversations.py` -- 持久化终端会话映射与授权 API/WS,保持其为会话实现而非新业务对象。
61+
- [x] `backend/services/agent_native_chat.py`, `backend/ws_agent_manager.py` -- 将终端协议接入精确原生绑定和 Fleet 出站通道,拒绝通用派发绕过。
62+
- [x] `backend/agent_server.py`, `agent/native-chat/` -- 在隔离节点实现 PTY、快照/环形回放、单写入、resize、重附着与清理证明;Codex/OMP 使用各自真实 TUI。
63+
- [x] `frontend/components/experience/alice-chat/terminal/`, `frontend/components/experience/alice-chat/chat-surface.tsx`, `frontend/components/shell/global-agent-dock.tsx` -- 移植 Alice 终端交互并启用真实 TUI 模式,GUI行为保持不变。
64+
- [x] `tests/`, `frontend/e2e/`, `docs/verification/` -- 覆盖矩阵中的协议、权限、竞态和实际浏览器流程,记录未验证边界。
65+
66+
**Acceptance Criteria:**
67+
- Given 已授权工作区且 Codex/OMP 绑定在线,when 选择 TUI并提交首条指令,then 右侧显示真实 CLI TUI并可连续交互,不创建 GUI 消息流的替代输出。
68+
- Given TUI运行中,when 刷新页面或短暂断网后恢复,then 同一 PTY恢复终端快照和后续输出,不重复启动 CLI。
69+
- Given 未授权身份、错误工作区或通用任务路径,when 尝试创建或附着终端,then 服务端拒绝且无节点/路径/凭据泄露。
70+
- Given 用户点击停止,when 节点尚未确认进程组退出,then 页面保持“正在停止/未确认”;确认后才解锁并显示终态。
71+
- Given GUI模式的现有会话,when 本功能上线,then 既有创建、恢复、受控工具提案和取消测试继续通过。
72+
73+
## Spec Change Log
74+
75+
## Design Notes
76+
77+
浏览器只连接控制面同源 WebSocket;控制面不持有本机账号,也不运行 PTY。终端二进制帧通过 Fleet 连接按 `terminal_session_id` 多路复用,控制消息使用有界 JSON;节点维护权威回放与控制权。API重启后由持久映射向同一节点查询/重附着,节点丢失时保持不可恢复状态,不用超时伪造清理。
78+
79+
## Verification
80+
81+
**Commands:**
82+
- `.venv\Scripts\python.exe -m pytest tests/unit/test_agent_server.py tests/unit/api/test_agent_terminal.py tests/unit/test_ws_agent_manager.py tests/unit/security/test_fleet_auth.py --no-cov -q` -- expected: PTY协议、权限、重连、鉴权例外和清理竞态通过。
83+
- `npm --prefix frontend run typecheck` -- expected: xterm与终端 API 类型通过。
84+
- `set PLAYWRIGHT_SMOKE_PORT=3010&& set PLAYWRIGHT_REUSE_EXISTING_SERVER=1&& npm exec -- playwright test e2e/agent-terminal.spec.mjs --workers=1`(工作目录 `frontend`)-- expected: GUI/TUI切换、回放、接管和停止通过。
85+
86+
**Manual checks (if no CLI):**
87+
- 使用 Codex 内置浏览器分别操作 Alice 与 OpenCLI:Codex、OMP真实TUI输入/输出、刷新重附着、双标签接管、停止后进程归零;不宣称未实测的窄屏或其他运行时。
88+
89+
## Suggested Review Order
90+
91+
**右侧聊天入口**
92+
93+
- 从会话编排入口理解 GUI/TUI 切换与终端生命周期。
94+
[`global-agent-dock.tsx:829`](../../frontend/components/shell/global-agent-dock.tsx#L829)
95+
96+
- Alice 风格终端负责重连、回放、控制权与输入分片。
97+
[`native-terminal.tsx:67`](../../frontend/components/experience/alice-chat/terminal/native-terminal.tsx#L67)
98+
99+
**认证与控制面**
100+
101+
- 单次票据 WebSocket 在每个输入动作前重新授权。
102+
[`agent_conversations.py:113`](../../backend/api/v1/agent_conversations.py#L113)
103+
104+
- 会话服务绑定工作区、运行时、节点和单调状态。
105+
[`agent_native_chat.py:214`](../../backend/services/agent_native_chat.py#L214)
106+
107+
- 数据库原子消费终端票据,阻止有效期内重放。
108+
[`agent_native_chat.py:421`](../../backend/services/agent_native_chat.py#L421)
109+
110+
- Fleet 管理器复用唯一出站连接并限制附件数量。
111+
[`ws_agent_manager.py:397`](../../backend/ws_agent_manager.py#L397)
112+
113+
**隔离 PTY 生命周期**
114+
115+
- 节点原子启动 PTY,避免并发和取消泄漏。
116+
[`agent_server.py:1029`](../../backend/agent_server.py#L1029)
117+
118+
- 停止后轮询进程组消失,未确认时失败关闭。
119+
[`agent_server.py:956`](../../backend/agent_server.py#L956)
120+
121+
- 隔离运行器选择真实 Codex/OMP TUI 命令。
122+
[`runner.py:12`](../../agent/native-chat/runner.py#L12)
123+
124+
**持久化契约**
125+
126+
- 技术会话状态独立持久化,不新增用户业务对象。
127+
[`agent_conversation.py:101`](../../backend/models/agent_conversation.py#L101)
128+
129+
- 迁移约束运行时、状态、版本及会话唯一性。
130+
[`nat20260917a_add_agent_terminal_sessions.py:19`](../../backend/migrations/versions/nat20260917a_add_agent_terminal_sessions.py#L19)
131+
132+
- 前端客户端统一创建、查询、停止与票据请求。
133+
[`agent-conversations.ts:229`](../../frontend/lib/api/agent-conversations.ts#L229)
134+
135+
**验证证据**
136+
137+
- 浏览器回归覆盖切换、回放、重连、接管与停止。
138+
[`agent-terminal.spec.mjs:25`](../../frontend/e2e/agent-terminal.spec.mjs#L25)
139+
140+
- 节点测试证明进程组清理只在确认消失后成功。
141+
[`test_agent_server.py:1213`](../../tests/unit/test_agent_server.py#L1213)
142+
143+
- 真实 Codex/OMP、API 重启续接和边界集中记录。
144+
[`native-agent-tui-2026-09-17.md:24`](../../docs/verification/native-agent-tui-2026-09-17.md#L24)
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
topic: OpenCLI Agent-First Operations System
3-
updated: 2026-08-24T12:44
3+
updated: 2026-09-12T11:51
44
---
55

66
- (event) 当前 Agent Home 被判定为错误方向:三栏空壳、虚假的 Requirements/Plan/Evidence、全 mock 验收以及登录状态 401;决定重新定义整套 Agent 系统,再进入 UX 和 Designer Pipeline。
@@ -10,4 +10,8 @@ updated: 2026-08-24T12:44
1010
- (decision) Product Brief 必须采用存量能力收束而非重造:将 OpenCLI 定义为分层的本地 Deep Research 数据上游——Acquisition Plane 负责实时多源采集,Evidence Plane 负责原始内容、逐源结果、lineage、版本与运行证据,Research Plane 负责问题拆解、检索编排、冲突/缺口识别与带引用综合,Consumption Plane 通过 MCP/SDK/API 向下游 Agent/系统交付。
1111
- (event) 发现两项方向冲突需在 Brief 中显式裁决:Issue #15 将产品扩展为数据采集、处理与外部交付平台,且要求全局 Agent Dock;当前用户将边界收窄为本地爬虫/数据上游并正在质疑独立 Agent Home。Issue #15 应作为历史产品证据,而非无条件继承的最新权威。
1212
- (assumption) 当前最大缺口不是来源数量或节点数量,而是尚未形成一条面向 Deep Research 的统一、可查询、可引用、可复现、可更新的 Source→Snapshot/Record→Transform→Claim/Citation→Research Output 源数据链;这一判断需要结合现有数据模型和用户确认继续验证。
13-
13+
- (decision) 沿用已有简报:用户确认平台内置 Agent 获取清洗分析数据,经 API/MCP 向下游 Agent 提供成果和工具;本轮补全首发场景与模板设计,不宣称运行实现。
14+
- (assumption) 首发受众暂按使用编程 Agent 的独立开发者与小团队;三个场景拟定为研究简报、竞品变化跟踪、项目知识供给,待试用验证;历史技术状态不作为当前验收证据。
15+
- (decision) 模板必须包含输入、依赖检查、执行定义、标记演示的材料、结果与下游消费示例、真实验收;首发先主推研究,后续模板逐个验收,不以卡片数量或演示代替运行证据。
16+
- (event) 历史 memlog 中的上游定位和可信源链已进入 brief,契约与验收进入 addendum;历史页面争议及旧 Issue 状态留作过程背景。Firecrawl/OpenBB 官方资料仅作任务式入口与 MCP 复用参考,未用于声称采用率。
17+
- (event) 简报与附录均已完成独立 structure/prose 审阅并采纳清晰度修正;三份 JSON 输入例和各模板七节结构检查通过。仅产品设计文档变更,模板运行时、页面、真实网络和下游联调尚未实现或验收。

0 commit comments

Comments
 (0)