先从官方协议确认“它是什么”
官方公开名称是 request_user_input;App Server 对应
tool/requestUserInput。它能展示 1–3 个结构化问题,但官方仍将
这条接口标为 experimental。
阶段性验证报告 · CURRENT STATE
Codex 在 Default Mode 中确实可以显示原生三选一界面;但当前实现依赖隐藏开关, 且启用后必须新建任务才能生效。技术路径跑通了,顺滑的一次会话体验还没有跑通。
每一步只回答三件事:观察到了什么、证据在哪里、它改变了什么判断。 不先讲完过程再补证据,也不把一个平台的成功外推到另一个平台。
官方公开名称是 request_user_input;App Server 对应
tool/requestUserInput。它能展示 1–3 个结构化问题,但官方仍将
这条接口标为 experimental。
我们先做最小验证,只问一个问题、给三个润色方向。目标不是完成产品,而是确认 “模型调用工具 → 客户端显示选择器 → 用户提交答案”这条链路真实存在。
公开源码包含 default_mode_request_user_input,但当前处于
under development,默认关闭。Skill 可以要求模型调用工具,却不能凭空把一个
当前任务没有注册的工具“变出来”。
我们实现了一个最小 MCP form elicitation。在 Ubuntu Codex CLI 的 Default Mode 中,它能稳定显示三选一表单并回传选择,证明外部协议路线本身可行。
同一思路进入 Windows 后,MCP 服务可以被注册,调用过程也能被观察到; 但 Windows Codex App 没有把它渲染为可用选择界面。CLI 的成功不能直接外推为 App 成功。
安装 Skill 时可以顺带打开隐藏开关;新建任务后,原生选择器能正常出现。 但开关不会把工具热注入当前任务,因此“安装并立即使用”仍需跨任务。到这里, 技术可行性与产品体验的边界已经清楚。
Skill 负责“怎么问”;安装脚本负责“把能力装进去”;开关脚本负责“让新任务获得工具”。 三者缺一不可,但也正因为工具表不会在当前任务重建,体验被切成了两段。
页面只展示会改变业务判断的核心片段:Skill 如何要求原生三选一、安装器如何校验并复制、 开关脚本如何备份和写入配置,以及为什么脚本成功后仍然要新建任务。
distribution/
├── install.ps1
└── native-picker-bootstrap-poc.zip
└── native-picker-bootstrap-poc/
├── SKILL.md
├── agents/
│ └── openai.yaml
└── scripts/
└── enable-native-picker.ps1
Skill 不自己画三选一,也不退化成文本列表。它只定义问题与选项;如果当前任务没有工具, 就明确返回不可用。
Call `request_user_input` once:
- Header: `润色方向`
- Question: `请选择这次短文润色的方向。`
- Options:
1. `自然流畅 (Recommended)`
2. `生动有画面`
3. `正式简洁`
If `request_user_input` is unavailable,
report `PICKER_NOT_INSTALLED` exactly.
安装器先核对 Skill 包的 SHA-256,避免把未知内容直接装进用户目录;校验通过后才复制并运行开关脚本。
$actualSha256 = (Get-FileHash $archivePath -Algorithm SHA256).
Hash.ToLowerInvariant()
if ($actualSha256 -ne $expectedSha256) {
throw "Package checksum mismatch"
}
Copy-Item -LiteralPath $sourceSkill `
-Destination $installedSkill -Recurse
$enableScript = Join-Path $installedSkill `
"scripts\enable-native-picker.ps1"
$featureResult = & powershell.exe -NoProfile `
-ExecutionPolicy Bypass -File $enableScript |
ConvertFrom-Json
脚本只修改 [features] 下的目标键:存在就替换,不存在就补入;写入前保留备份,写入后再读回验证。
$feature = "default_mode_request_user_input"
$configPath = Join-Path $env:USERPROFILE `
".codex\config.toml"
if (-not (Test-Path -LiteralPath $backupPath)) {
[IO.File]::WriteAllBytes(
$backupPath,
[IO.File]::ReadAllBytes($configPath)
)
}
$newBody =
"default_mode_request_user_input = true" +
$newline + $body
[IO.File]::WriteAllText(
$configPath, $text, $utf8NoBom
)
if (-not $afterEnabled) {
throw "Failed to enable $feature"
}
这里最容易混淆的不是“开关有没有写进配置”,而是“当前任务启动时是否已经拿到工具”。 我们实测的边界是:配置可改,当前任务的能力集合不会随之重建。
配置写入成功;但这个任务启动时没有原生 Picker 工具,无法在同一任务内立即调用。
新任务按最新配置构建工具表,Skill 才能调用原生 Picker 并继续短文润色。
普通用户想做的是“安装后马上使用”。如果必须先完成安装,再主动新建任务并重新输入业务需求, 用户会感知到系统边界,Skill 也失去了“一句话开始工作”的价值。因此当前不建议强行面向普通用户发布。
官方协议已经存在,原生界面也已实测出现;当前缺口集中在 Default Mode 的成熟度与会话内刷新机制。 这比“从零不存在”更接近官方后续可以自然补齐的状态。
保存 Skill、脚本与实测证据,避免继续为临时限制叠加复杂安装逻辑。
重点关注 Feature maturity、客户端工具注册和 App Server 相关更新。
后续无需重复证明基础协议;只需验证新版本是否跨过当前会话边界。
这不是功能做不到,而是当前实现成本与用户体验不匹配。