Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
82c75b2
feat: 新增可替换引擎的通用 Agent 无界面首个切片
Nex-Z Oct 10, 2026
e50b1b2
fix: 阻止浏览器重定向越界并验证 Windows headless 能力
Nex-Z Oct 10, 2026
e0de7d2
fix: 限制浏览器 fixture 范围并绑定任务会话
Nex-Z Oct 10, 2026
f5c882e
feat: 复用工作区校验并整合 Windows 可信适配与验收指标
Nex-Z Oct 10, 2026
7380f31
docs: 区分正常验收与安全拒绝样本
Nex-Z Oct 10, 2026
f38021d
fix: coordinate nested workspaces and handle immediate cancellation
Nex-Z Oct 10, 2026
8b13077
feat: connect opt-in fixture runtime to Electron chat sessions
Nex-Z Oct 10, 2026
f19ca51
feat: 接入受限 Pi 会话与内存凭据配置
Nex-Z Oct 10, 2026
8064910
feat: 接通受限 Windows GUI 与 Pi 工具并记录前台验收阻塞
Nex-Z Oct 11, 2026
76df1bb
fix: 手动验收入口打印确切目标窗口
Nex-Z Oct 11, 2026
f19ef5d
fix: 保留 GUI 初始化失败原因和自有窗口身份
Nex-Z Oct 11, 2026
fecf6ea
docs: 区分测试授权与 Windows 前台技术限制
Nex-Z Oct 11, 2026
d547249
feat: 区分对话测试授权并记录单次前台激活失败
Nex-Z Oct 11, 2026
f1df0ce
fix: 独立核对前台身份并归档 Windows 只读诊断
Nex-Z Oct 11, 2026
c43ffc9
fix(gui): report release promptly and preserve manual OS evidence
Nex-Z Oct 11, 2026
c28e43b
docs(gui): preserve evidence bytes across platform checkouts
Nex-Z Oct 11, 2026
25c49db
fix(gui): require observed text receipts before continuing input
Nex-Z Oct 11, 2026
90b4d92
feat(agent): separate semantic text filling from native key diagnostics
Nex-Z Oct 11, 2026
b1f8f80
feat(agent): add bound Windows UIA sidecar and guarded text tools
Nex-Z Oct 11, 2026
0e20577
feat(desktop): wire opt-in UIA sessions with shared lease and package…
Nex-Z Oct 11, 2026
5f54f31
fix(test): require owned-window start before UIA acceptance
Nex-Z Oct 11, 2026
52afe46
test(uia): use owned foreground sentinel for background acceptance
Nex-Z Oct 11, 2026
fecb3c2
fix(uia): preserve interrupted acceptance evidence and audit worker p…
Nex-Z Oct 11, 2026
e407daf
test(uia): verify authorized foreground Unicode write and archive evi…
Nex-Z Oct 11, 2026
cd502ee
fix(uia): invalidate replaced grants and expose safe actionable failures
Nex-Z Oct 11, 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
6 changes: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

docs/v2/evidence/windows-uia-owned-2026-10-11/report.json -text

docs/v2/evidence/windows-uia-background-2026-10-11/report.json -text

docs/v2/evidence/windows-uia-foreground-2026-10-11/report.json -text
70 changes: 70 additions & 0 deletions .github/workflows/agent-core.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Agent Core v2
on:
pull_request:
paths: ['native/windows-uia/**', 'packages/agent-core/**', 'electron/**', 'src/**', 'scripts/verify-v2-*.cjs', 'scripts/build-windows-uia.cjs', 'scripts/uia-start-gate.cjs', 'electron-builder.yml', 'package.json', 'pnpm-lock.yaml', 'pnpm-workspace.yaml', '.github/workflows/agent-core.yml']
workflow_dispatch:
permissions:
contents: read
jobs:
headless-linux:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: 10.7.0
- uses: actions/setup-node@v6
with:
node-version: '22.19.0'
cache: pnpm
- run: pnpm install --frozen-lockfile --ignore-scripts
- run: pnpm --filter @open-eagle/agent-core exec playwright install --with-deps chromium
- run: pnpm v2:typecheck
- run: pnpm exec tsc --noEmit
- run: pnpm exec tsc -p tsconfig.electron.json
- run: node scripts/ensure-cjs-package.cjs
- run: node --test scripts/verify-v2-gui-policy.cjs scripts/verify-v2-uia-host.cjs scripts/verify-v2-uia-start.cjs
- run: node scripts/verify-v2-uia.cjs --plan
# OS GUI smoke requires an interactive owned window; not run on hosted CI.
- run: pnpm v2:test

headless-windows:
runs-on: windows-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: 10.7.0
- uses: actions/setup-node@v6
with:
node-version: '24.8.0'
cache: pnpm
- run: pnpm install --frozen-lockfile --ignore-scripts
- run: pnpm --filter @open-eagle/agent-core exec playwright install chromium
- run: pnpm v2:typecheck
- run: pnpm exec tsc --noEmit
- run: pnpm exec tsc -p tsconfig.electron.json
- run: node scripts/ensure-cjs-package.cjs
- run: node --test scripts/verify-v2-gui-policy.cjs scripts/verify-v2-uia-host.cjs scripts/verify-v2-uia-start.cjs
- run: node scripts/verify-v2-uia.cjs --plan
# OS GUI smoke requires an interactive owned window; not run on hosted CI.
# Windows 显式可信工作区测试;旧 Linux-only 测试跳过不等于通过。
- run: pnpm --filter @open-eagle/agent-core test:unit
- run: pnpm --filter @open-eagle/agent-core test:browser
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
- name: Build and self-test UIA sidecar (no OS interaction)
shell: pwsh
env:
DOTNET_CLI_TELEMETRY_OPTOUT: '1'
DOTNET_GENERATE_ASPNET_CERTIFICATE: 'false'
run: |
dotnet restore native/windows-uia/OpenEagle.Uia.csproj --locked-mode --configfile native/windows-uia/NuGet.Config
if ($LASTEXITCODE) { exit $LASTEXITCODE }
dotnet build native/windows-uia/OpenEagle.Uia.csproj -c Release --no-restore
if ($LASTEXITCODE) { exit $LASTEXITCODE }
& native/windows-uia/bin/Release/net10.0-windows/OpenEagle.Uia.exe --self-test
exit $LASTEXITCODE
6 changes: 6 additions & 0 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ jobs:
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- name: Set up .NET for Windows UIA
if: matrix.platform == 'windows'
uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'

- name: Set up Python
uses: actions/setup-python@v6
with:
Expand Down
51 changes: 51 additions & 0 deletions docs/v2/GUI_TEXT_INPUT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# 文本填写与按键操作:实现、证据及后续边界

用户已明确:不要长期围绕逐字fixture打补丁;文本填写应优先整段语义写入,按键是最后手段。本轮没有新建UIA/native栈,没有读取或覆盖真实剪贴板,没有自动切输入法,也没有继续前台试验。

## 本轮已落地

新增独立text_fill能力,参数target={kind:browser-element,ref}和text;语义是替换整个字段值,允许Unicode、换行、首尾及连续空格和空字符串。它注册在既有createBrowserCapabilities返回的同一工具集,复用browser_fill的prepare、目标指纹、资源锁、write/external-submit权限、handle.fill及独立字段值验证;记录text-method/browser-semantic-fill证据,不记录文本到新增机制证据中。旧browser_fill保留。跨工具demo已改为text_fill→表单提交→files→CLI。

当前只支持宿主批准的隔离literal-loopback浏览器fixture,不连接日常profile或任意站点;不支持desktop-control目标,不在失败后自动改成鼠键。文本工具可由同一AgentRuntime/Pi注册表使用,但普通Pi产品会话仍只有原来明确注册的临时sample工具,不宣称本轮新增任意网页/桌面路由。真实无头Chrome回归以中文、emoji、重音、连续/首尾空格及换行整段填写,检查字段值和独立HTTP提交值。这个证据是浏览器语义操作,不是OS输入。

原desktop_type仅保留显式前台ASCII扫描码诊断,schema和prepare都提前拒绝多字节及控制字符;其逐字receipt不是产品默认填写方案。自有窗口观测到composition-active时明确GUI_IME_COMPOSITION_ACTIVE停止,而非真值误判成功或等待笼统超时。不发Enter/Esc/Shift提交/取消候选,不改变用户输入法。鼠标精确坐标保护不变。

## 原始现场证据

[第三轮](evidence/windows-gui-manual-2026-10-11-round3/oracle.json):仅发送O,出现compositionstart/insertCompositionText,无compositionend;最终composing=true,500ms后停止,未发第二字符。87次指针差值0。证明本轮存在未提交的IME组合输入,不证明前两轮全部错字原因。

[第四轮](evidence/windows-gui-manual-2026-10-11-round4/oracle.json):用户同意手动英文对照,但实际事件仍为上述组合流程,不能仅凭点击认定英文直输。首45次指针读数均(1811,1113),约358.70ms后读到(1810,1113),前后采样间隔约14.85ms,立即停止,未保存。

坐标链:控件相对DIP加内容区原点→Math.round得到全局DIP(1207,742)→Electron dipToScreenPoint得到(1811,1113)→nut-js/provider→native绝对坐标SendInput;读回经native GetCursorPos直接传给JS,中间没有第二轮DIP换算。打字期间没有再次setPosition,也没有read→set循环。第一次转换会有整数舍入,但它不能单独解释连续45次一致后才出现的差异;OS坐标上下文、采样或其他移动来源未确定,不指认用户动鼠标,不全局加1或扩大容差。离线回放全部46个样本仍在最后单像素差异停止。

## 已有依赖审计与最小架构

将效果区分为text_set(替换整值,当前text_fill)、text_insert(插入当前选区,尚未通用暴露)、key_action(按键/快捷键,独立前台授权)。宿主只注册实际可用且目标已授权的backend;记录requestedEffect、actualMechanism、目标身份、交互模式和独立结果验证。选择发生在prepare之前,执行失败/unknown后不盲目换通道重试。

|优先级/通道|可复用能力与当前状态|权限及验证边界|
|---|---|---|
|1 API/files/browser语义|browser整段填写本轮已接text_fill;现有API/files按各自语义使用|当前browser仅literal-loopback;保留write/external-submit批准和最终值验证,不伪称OS输入|
|2 桌面辅助功能控件写入|UIA ValuePattern.SetValue是候选;仓库和当前Node依赖没有UIA桥,未实现|只适用支持该pattern的可写控件;不能把TextPattern当通用写接口。目标绑定、enabled/read-only、副作用和后台性逐provider验证;需要新桥/依赖时先报告,不立即安装|
|已有Electron语义(特定宿主)|webContents.insertText是现有依赖接口,尚未接本轮通用工具|只适用持有授权webContents的应用内目标,插入focused element,不适用于任意第三方窗口;需要选区/最终值验证,不能算OS输入,也不能代替通用桌面支持|
|3 原生Unicode文本|现有libnut-win32没有导出此模式;候选是在同一native模块增加独立入口|仍前台系统输入;UTF-16/代理对、UIPI、修饰键、部分送入和取消均需验证。需修改/构建现有native模块,工具链和权限需求先报告;不新造第二套驱动|
|4 显式受控粘贴|Electron clipboard与旧quick-assistant快照代码存在,但不能原样当可靠通道|会接触全局用户数据与剪贴板历史;读取快照需最小化、不得日志持久化。其他应用/用户可并发改变,比较后恢复也非原子。必须明确授权和占用/变化策略,不能覆盖后来内容;本轮不读取、不写入、不测试真实剪贴板|
|5 按键后备|nut-js现有扫描码路径;逐字receipt仅诊断|文本受布局/IME影响,明确foreground/usesSystemInput,独立验证;失败停止,不自动切输入法或再次抢焦点|

旧quick-assistant只快照text/html/rtf/image,随后clear、copy、sleep再恢复:未覆盖所有自定义格式,也没有所有权/并发版本保护。因此没有把这段代码直接复用为text_fill fallback。剪贴板方案不是无风险的便捷替代,不声称一定能完整恢复原状。

## 原生实现和社区经验

已核对本机版本标签及同版[libnut v2.7.5 keypress](https://github.com/ZachJW34/libnut-core/blob/v2.7.5/src/win32/keypress.c):typeString最终走扫描码,解码后还有char转换,不是Unicode注入。[keycode](https://github.com/ZachJW34/libnut-core/blob/v2.7.5/src/win32/keycode.c)通过VkKeyScan决定键码及修饰键,大写O的Shift序列与本轮事件一致;不能据此证明Shift导致切换输入法。JS逐字符await保持调用顺序,不能证明应用提交文本。

Windows的[KEYBDINPUT](https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput)明确区分UNICODE/VK_PACKET与SCANCODE。[SendInput](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput)插入计数不是控件回执,受UIPI与既有键状态约束;不能提权绕过或释放用户按下的键。Unicode入口也不能保证消除已经存在的composition。

[UIA SetValue](https://learn.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationvaluepattern-setvalue)与[Electron insertText](https://www.electronjs.org/docs/latest/api/web-contents#contentsinserttexttext)为后续目标适配候选,不等于当前已支持。

已只读查阅[nut.js #569](https://github.com/nut-tree/nut.js/issues/569)的Windows中文输出问题,以及[libnut-core #126](https://github.com/nut-tree/libnut-core/issues/126)的历史鼠标归一化问题。这些是版本/触发条件不同的社区线索,不证明本机首O组合或迟发1像素差异的具体根因;本轮读取路径与同版[mouse.c](https://github.com/ZachJW34/libnut-core/blob/v2.7.5/src/win32/mouse.c)核对,不套用旧issue的补偿办法。没有对外发帖、上传日志或声称获得维护者确认。

下一步优先扩展经过授权、可独立验证的语义目标,而不是继续让用户重复逐字fixture。任意桌面UIA/Unicode/受控粘贴仍是明确缺口,需具体选型后实施;本轮不自动新增依赖、权限或前台测试。


## 2026-10-11 UIA sidecar 增量

新增受宿主绑定的 FlaUI.UIA3 sidecar 与通用 runtime 工具;仅离线验证,真实 UIA、生产 UI/Pi 注册及 Electron 打包尚未验收/接入。默认 unknown,不能宣称后台或 native 键盘问题已解决。依赖、构建、测试与边界见 [UIA_SIDECAR.md](UIA_SIDECAR.md)。
Loading
Loading